Replace the syncqt.pl script with syncqt tool
syncqt.pl adds an extra dependency on perl when building Qt. Modern C++ provides the convenient cross-platform way to access a filesystem and to use regular expressions, so we may replace the perl script with C++ application. The syncqt executable is built at configure time and installed as QtCore tool. It's running at configure time to deliver the required header files for IDE to build a consistent code model and at the build time to keep tracking changes in header files and generate the missing aliases without reconfiguring. 'syncqt' only parses header files from a CMake build tree, so the resulting Qt installation only contains interfacing headers that belong to the platform that Qt is built for. 'sync.profile' files are not used as the 'source of truth' for sync qt procedure anymore, all the necessary information is taken from either CMake files at configure time or from the module header files while parsing them. syncqt.pl is still in place since it's required as fallback solution for a smooth transition to the new syncqt implementation for all qt repositories. This patchset only enables the C++ based syncqt for 'qtbase' repository. From the performance perspective C++ version works faster then perl script, also the configure time is reduced significally on subsequent reconfigurations - up x2 times faster when re-configuring repository, but it also takes time to compile the tool itself the first time. Numbers for qtbase: syncqt.pl syncqt.cpp initial: 0m16,035s 0m20,413s reconfig: 0m6,819s 0m3,725s The syncing procedure can be run separately for each module using <ModuleName>_sync_headers targets. The 'sync_headers' target can be used to sync all the modules at once. Task-number: QTBUG-87480 Task-number: QTBUG-103196 Change-Id: I8c938bcaf88a8713b39bbfd66d9e7ef12b2c3523 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
parent
458ec4cb54
commit
b89d63515b
@ -31,3 +31,6 @@ set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_STATIC "3.21")
|
||||
# in sync.
|
||||
set(QT_MIN_NEW_POLICY_CMAKE_VERSION "3.16")
|
||||
set(QT_MAX_NEW_POLICY_CMAKE_VERSION "3.21")
|
||||
|
||||
# Use cpp-based syncqt
|
||||
set(QT_USE_SYNCQT_CPP TRUE)
|
||||
|
@ -247,6 +247,7 @@ qt_copy_or_install(FILES
|
||||
cmake/QtLalrHelpers.cmake
|
||||
cmake/QtModuleConfig.cmake.in
|
||||
cmake/QtModuleDependencies.cmake.in
|
||||
cmake/QtModuleHeadersCheck.cmake
|
||||
cmake/QtModuleHelpers.cmake
|
||||
cmake/QtModuleToolsConfig.cmake.in
|
||||
cmake/QtModuleToolsDependencies.cmake.in
|
||||
|
@ -228,6 +228,15 @@ if(NOT QT_MKSPECS_DIR)
|
||||
set(QT_MKSPECS_DIR "${QT_MKSPECS_DIR}" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
# macOS versions 10.14 and less don't have the implementation of std::filesystem API.
|
||||
if(CMAKE_HOST_APPLE AND CMAKE_HOST_SYSTEM_VERSION VERSION_LESS "19.0.0")
|
||||
message(FATAL_ERROR "macOS versions less than 10.15 are not supported for building Qt.")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED QT_USE_SYNCQT_CPP)
|
||||
set(QT_USE_SYNCQT_CPP FALSE)
|
||||
endif()
|
||||
|
||||
# the default RPATH to be used when installing, but only if it's not a system directory
|
||||
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}" isSystemDir)
|
||||
if("${isSystemDir}" STREQUAL "-1")
|
||||
|
@ -419,6 +419,10 @@ macro(qt_build_repo_begin)
|
||||
add_dependencies(install_docs install_html_docs install_qch_docs)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET sync_headers)
|
||||
add_custom_target(sync_headers)
|
||||
endif()
|
||||
|
||||
# Add global qt_plugins, qpa_plugins and qpa_default_plugins convenience custom targets.
|
||||
# Internal executables will add a dependency on the qpa_default_plugins target,
|
||||
# so that building and running a test ensures it won't fail at runtime due to a missing qpa
|
||||
@ -474,6 +478,10 @@ macro(qt_build_repo_begin)
|
||||
if(NOT TARGET benchmark)
|
||||
add_custom_target(benchmark)
|
||||
endif()
|
||||
|
||||
if(QT_INTERNAL_SYNCED_MODULES)
|
||||
set_property(GLOBAL PROPERTY _qt_synced_modules ${QT_INTERNAL_SYNCED_MODULES})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(qt_build_repo_end)
|
||||
@ -510,6 +518,12 @@ macro(qt_build_repo_end)
|
||||
if(NOT QT_SUPERBUILD)
|
||||
qt_print_build_instructions()
|
||||
endif()
|
||||
|
||||
get_property(synced_modules GLOBAL PROPERTY _qt_synced_modules)
|
||||
if(synced_modules)
|
||||
set(QT_INTERNAL_SYNCED_MODULES ${synced_modules} CACHE INTERNAL
|
||||
"List of the synced modules. Prevents running syncqt.cpp after the first configuring.")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(qt_build_repo)
|
||||
|
@ -140,6 +140,12 @@ function(qt_internal_add_docs)
|
||||
)
|
||||
|
||||
add_dependencies(prepare_docs_${target} qattributionsscanner_${target})
|
||||
if(QT_USE_SYNCQT_CPP)
|
||||
if(NOT TARGET sync_all_public_headers)
|
||||
add_custom_target(sync_all_public_headers)
|
||||
endif()
|
||||
add_dependencies(prepare_docs_${target} sync_all_public_headers)
|
||||
endif()
|
||||
|
||||
# generate docs target
|
||||
set(generate_qdoc_args
|
||||
|
@ -429,7 +429,7 @@ function(qt_internal_add_configure_time_executable target)
|
||||
|
||||
set(cmake_flags_arg)
|
||||
if(arg_CMAKE_FLAGS)
|
||||
set(cmake_flags_arg CMAKE_FLAGS ${arg_CMAKE_FLAGS})
|
||||
set(cmake_flags_arg CMAKE_FLAGS "${arg_CMAKE_FLAGS}")
|
||||
endif()
|
||||
configure_file("${template}" "${target_binary_dir}/CMakeLists.txt" @ONLY)
|
||||
try_compile(result
|
||||
|
@ -97,6 +97,19 @@ function(qt_copy_framework_headers target)
|
||||
QT_COPIED_FRAMEWORK_HEADERS "${out_files}")
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_generate_fake_framework_header target)
|
||||
# Hack to create the "Headers" symlink in the framework:
|
||||
# Create a fake header file and copy it into the framework by marking it as PUBLIC_HEADER.
|
||||
# CMake now takes care of creating the symlink.
|
||||
set(fake_header "${CMAKE_CURRENT_BINARY_DIR}/${target}_fake_header.h")
|
||||
qt_internal_get_main_cmake_configuration(main_config)
|
||||
file(GENERATE OUTPUT "${fake_header}" CONTENT "// ignore this file\n"
|
||||
CONDITION "$<CONFIG:${main_config}>")
|
||||
target_sources(${target} PRIVATE "${fake_header}")
|
||||
set_source_files_properties("${fake_header}" PROPERTIES GENERATED ON)
|
||||
set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER "${fake_header}")
|
||||
endfunction()
|
||||
|
||||
function(qt_finalize_framework_headers_copy target)
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
if(${target_type} STREQUAL "INTERFACE_LIBRARY")
|
||||
@ -108,17 +121,7 @@ function(qt_finalize_framework_headers_copy target)
|
||||
endif()
|
||||
get_target_property(headers ${target} QT_COPIED_FRAMEWORK_HEADERS)
|
||||
if(headers)
|
||||
# Hack to create the "Headers" symlink in the framework:
|
||||
# Create a fake header file and copy it into the framework by marking it as PUBLIC_HEADER.
|
||||
# CMake now takes care of creating the symlink.
|
||||
set(fake_header ${target}_fake_header.h)
|
||||
qt_internal_get_main_cmake_configuration(main_config)
|
||||
file(GENERATE OUTPUT ${fake_header} CONTENT "// ignore this file\n"
|
||||
CONDITION "$<CONFIG:${main_config}>")
|
||||
string(PREPEND fake_header "${CMAKE_CURRENT_BINARY_DIR}/")
|
||||
target_sources(${target} PRIVATE ${fake_header})
|
||||
set_source_files_properties(${fake_header} PROPERTIES GENERATED ON)
|
||||
set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER ${fake_header})
|
||||
qt_internal_generate_fake_framework_header(${target})
|
||||
|
||||
# Add a target, e.g. Core_framework_headers, that triggers the header copy.
|
||||
add_custom_target(${target}_framework_headers DEPENDS ${headers})
|
||||
|
@ -4,26 +4,18 @@
|
||||
# Add a custom ${module_target}_headersclean_check target that builds each header in
|
||||
# ${module_headers} with a custom set of defines. This makes sure our public headers
|
||||
# are self-contained, and also compile with more strict compiler options.
|
||||
function(qt_internal_add_headersclean_target
|
||||
module_target
|
||||
module_include_name
|
||||
module_headers)
|
||||
# module_headers is a list of strings of the form
|
||||
# <headerfile>[:feature]
|
||||
set(hclean_headers "")
|
||||
foreach(entry ${module_headers})
|
||||
string(REPLACE ":" ";" entry_list ${entry})
|
||||
list(LENGTH entry_list entry_list_length)
|
||||
list(GET entry_list 0 entry_path)
|
||||
function(qt_internal_add_headersclean_target module_target module_headers)
|
||||
get_target_property(has_headers ${module_target} _qt_module_has_headers)
|
||||
if(NOT has_headers)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (${entry_list_length} EQUAL 2)
|
||||
list(GET entry_list 1 entry_feature)
|
||||
if (NOT QT_FEATURE_${entry_feature})
|
||||
message(STATUS "headersclean: Ignoring header ${entry_path} because of missing feature ${entry_feature}")
|
||||
continue()
|
||||
endif()
|
||||
set(hclean_headers "")
|
||||
foreach(header IN LISTS module_headers)
|
||||
get_filename_component(header_name "${header}" NAME)
|
||||
if(header_name MATCHES "^q[^_]+\\.h$" AND NOT header_name MATCHES ".*(global|exports)\\.h")
|
||||
list(APPEND hclean_headers "${header}")
|
||||
endif()
|
||||
list(APPEND hclean_headers ${entry_path})
|
||||
endforeach()
|
||||
|
||||
# Make sure that the header compiles with our strict options
|
||||
@ -53,6 +45,12 @@ function(qt_internal_add_headersclean_target
|
||||
set(target_includes_joined_genex
|
||||
"$<${includes_exist_genex}:-I$<JOIN:${target_includes_genex},;-I>>")
|
||||
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(is_multi_config)
|
||||
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
|
||||
set(config_suffix "$<$<NOT:$<CONFIG:${first_config_type}>>:-$<CONFIG>>")
|
||||
endif()
|
||||
|
||||
# qmake doesn't seem to add the defines that are set by the header_only_module when checking the
|
||||
# the cleanliness of the module's header files.
|
||||
# This allows us to bypass an error with CMake 3.18 and lower when trying to evaluate
|
||||
@ -165,35 +163,23 @@ function(qt_internal_add_headersclean_target
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
foreach(header ${hclean_headers})
|
||||
get_filename_component(input_path "${header}" ABSOLUTE)
|
||||
set(artifact_path "header_check/${header}.o")
|
||||
get_filename_component(artifact_directory "${artifact_path}" DIRECTORY)
|
||||
set(comment_header_path "${CMAKE_CURRENT_SOURCE_DIR}/${header}")
|
||||
file(RELATIVE_PATH comment_header_path "${PROJECT_SOURCE_DIR}" "${comment_header_path}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${artifact_path}"
|
||||
COMMENT "headersclean: Checking header ${comment_header_path}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${artifact_directory}"
|
||||
COMMAND
|
||||
${compiler_to_run} -c ${cxx_flags}
|
||||
"${target_compile_flags_joined_genex}"
|
||||
"${target_defines_joined_genex}"
|
||||
${hcleanFLAGS}
|
||||
"${target_includes_joined_genex}"
|
||||
${framework_includes}
|
||||
${hcleanDEFS}
|
||||
-xc++ "${input_path}"
|
||||
-o${artifact_path}
|
||||
IMPLICIT_DEPENDS CXX
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS "${input_path}"
|
||||
)
|
||||
list(APPEND hclean_artifacts "${artifact_path}")
|
||||
endforeach()
|
||||
set(compiler_command_line
|
||||
"${compiler_to_run}" "-c" "${cxx_flags}"
|
||||
"${target_compile_flags_joined_genex}"
|
||||
"${target_defines_joined_genex}"
|
||||
"${hcleanFLAGS}"
|
||||
"${target_includes_joined_genex}"
|
||||
"${framework_includes}"
|
||||
"${hcleanDEFS}"
|
||||
|
||||
)
|
||||
string(JOIN " " compiler_command_line_variables
|
||||
"-xc++"
|
||||
"\${INPUT_HEADER_FILE}"
|
||||
"-o"
|
||||
"\${OUTPUT_ARTIFACT}"
|
||||
)
|
||||
set(input_header_path_type ABSOLUTE)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
# -Za would enable strict standards behavior, but we can't add it because
|
||||
# <windows.h> and <GL.h> violate the standards.
|
||||
@ -202,37 +188,87 @@ function(qt_internal_add_headersclean_target
|
||||
# cl.exe needs a source path
|
||||
get_filename_component(source_path "${QT_MKSPECS_DIR}/features/data/dummy.cpp" REALPATH)
|
||||
|
||||
foreach(header ${hclean_headers})
|
||||
# We need realpath here to make sure path starts with drive letter
|
||||
get_filename_component(input_path "${header}" REALPATH)
|
||||
set(artifact_path "header_${header}.o")
|
||||
set(comment_header_path "${CMAKE_CURRENT_SOURCE_DIR}/${header}")
|
||||
file(RELATIVE_PATH comment_header_path "${PROJECT_SOURCE_DIR}" "${comment_header_path}")
|
||||
set(compiler_command_line
|
||||
"${compiler_to_run}" "-nologo" "-c" "${CMAKE_CXX_FLAGS}"
|
||||
"${target_compile_flags_joined_genex}"
|
||||
"${target_defines_joined_genex}"
|
||||
"${hcleanFLAGS}"
|
||||
"${target_includes_joined_genex}"
|
||||
"${hcleanDEFS}"
|
||||
)
|
||||
string(JOIN " " compiler_command_line_variables
|
||||
"-FI"
|
||||
"\${INPUT_HEADER_FILE}"
|
||||
"-Fo\${OUTPUT_ARTIFACT}"
|
||||
"${source_path}"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${artifact_path}"
|
||||
COMMENT "headersclean: Checking header ${comment_header_path}"
|
||||
COMMAND
|
||||
${compiler_to_run} -nologo -c ${CMAKE_CXX_FLAGS}
|
||||
"${target_compile_flags_joined_genex}"
|
||||
"${target_defines_joined_genex}"
|
||||
${hcleanFLAGS}
|
||||
"${target_includes_joined_genex}"
|
||||
${hcleanDEFS}
|
||||
-FI "${input_path}"
|
||||
-Fo${artifact_path} "${source_path}"
|
||||
IMPLICIT_DEPENDS CXX
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS "${input_path}"
|
||||
)
|
||||
list(APPEND hclean_artifacts "${artifact_path}")
|
||||
endforeach()
|
||||
set(input_header_path_type REALPATH)
|
||||
else()
|
||||
message(FATAL_ERROR "CMAKE_CXX_COMPILER_ID \"${CMAKE_CXX_COMPILER_ID}\" is not supported"
|
||||
" for the headersclean check.")
|
||||
endif()
|
||||
|
||||
get_target_property(module_include_name ${target} _qt_module_include_name)
|
||||
|
||||
unset(header_check_exceptions)
|
||||
if(QT_USE_SYNCQT_CPP)
|
||||
set(header_check_exceptions
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${module_include_name}_header_check_exceptions")
|
||||
endif()
|
||||
set(headers_check_parameters
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${module_target}HeadersCheckParameters${config_suffix}.cmake")
|
||||
string(JOIN "\n" headers_check_parameters_content
|
||||
"set(HEADER_CHECK_EXCEPTIONS"
|
||||
" \"${header_check_exceptions}\")"
|
||||
"set(HEADER_CHECK_COMPILER_COMMAND_LINE"
|
||||
" \[\[$<JOIN:${compiler_command_line},\]\]\n \[\[>\]\]\n"
|
||||
" ${compiler_command_line_variables}"
|
||||
")"
|
||||
)
|
||||
file(GENERATE OUTPUT "${headers_check_parameters}"
|
||||
CONTENT "${headers_check_parameters_content}")
|
||||
|
||||
set(sync_headers_dep "")
|
||||
if(QT_USE_SYNCQT_CPP)
|
||||
set(sync_headers_dep "sync_headers")
|
||||
endif()
|
||||
|
||||
foreach(header ${hclean_headers})
|
||||
# We need realpath here to make sure path starts with drive letter
|
||||
get_filename_component(input_path "${header}" ${input_header_path_type})
|
||||
|
||||
get_filename_component(input_file_name ${input_path} NAME)
|
||||
set(artifact_path "${CMAKE_CURRENT_BINARY_DIR}/header_check/${input_file_name}.o")
|
||||
|
||||
if(input_path MATCHES "${CMAKE_BINARY_DIR}")
|
||||
set(input_base_dir "${CMAKE_BINARY_DIR}")
|
||||
elseif(input_path MATCHES "${CMAKE_SOURCE_DIR}")
|
||||
set(input_base_dir "${CMAKE_SOURCE_DIR}")
|
||||
endif()
|
||||
file(RELATIVE_PATH comment_header_path "${input_base_dir}" "${input_path}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${artifact_path}"
|
||||
COMMENT "headersclean: Checking header ${comment_header_path}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/header_check"
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DINPUT_HEADER_FILE=${input_path}
|
||||
-DOUTPUT_ARTIFACT=${artifact_path}
|
||||
-DPARAMETERS=${headers_check_parameters}
|
||||
-P "${QT_CMAKE_DIR}/QtModuleHeadersCheck.cmake"
|
||||
IMPLICIT_DEPENDS CXX
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS
|
||||
${headers_check_parameters}
|
||||
${sync_headers_dep}
|
||||
${input_path}
|
||||
${header_check_exceptions}
|
||||
)
|
||||
list(APPEND hclean_artifacts "${artifact_path}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(${module_target}_headersclean_check
|
||||
COMMENT "headersclean: Checking headers in ${module_include_name}"
|
||||
DEPENDS ${hclean_artifacts}
|
||||
|
33
cmake/QtModuleHeadersCheck.cmake
Normal file
33
cmake/QtModuleHeadersCheck.cmake
Normal file
@ -0,0 +1,33 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
# The PARAMETERS file should specify the following variables for the correct work of
|
||||
# this script:
|
||||
# HEADER_CHECK_EXCEPTIONS - path to file that contains exceptions.
|
||||
# The file is created by syncqt.
|
||||
#
|
||||
# HEADER_CHECK_COMPILER_COMMAND_LINE - compiler command line
|
||||
include("${PARAMETERS}")
|
||||
|
||||
if(EXISTS ${HEADER_CHECK_EXCEPTIONS})
|
||||
file(READ ${HEADER_CHECK_EXCEPTIONS} header_check_exception_list)
|
||||
endif()
|
||||
|
||||
file(TO_CMAKE_PATH "${INPUT_HEADER_FILE}" header)
|
||||
foreach(exception IN LISTS header_check_exception_list)
|
||||
file(TO_CMAKE_PATH "${exception}" exception)
|
||||
if(exception STREQUAL header)
|
||||
file(WRITE "${OUTPUT_ARTIFACT}" "skipped")
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
execute_process(COMMAND ${HEADER_CHECK_COMPILER_COMMAND_LINE}
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE output
|
||||
)
|
||||
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "${INPUT_HEADER_FILE} header check"
|
||||
" failed: ${HEADER_CHECK_COMPILER_COMMAND_LINE}\n"
|
||||
" ${output}")
|
||||
endif()
|
@ -29,6 +29,7 @@ macro(qt_internal_get_internal_add_module_keywords option_args single_args multi
|
||||
EXTERNAL_HEADERS_DIR
|
||||
PRIVATE_HEADER_FILTERS
|
||||
QPA_HEADER_FILTERS
|
||||
HEADER_SYNC_SOURCE_DIRECTORY
|
||||
${__default_target_info_args}
|
||||
)
|
||||
set(${multi_args}
|
||||
@ -111,6 +112,12 @@ endfunction()
|
||||
# QPA_HEADER_FILTERS
|
||||
# The regular expressions that filter QPA header files out of target sources.
|
||||
# The value must use the following format 'regex1|regex2|regex3'.
|
||||
#
|
||||
# HEADER_SYNC_SOURCE_DIRECTORY
|
||||
# The source directory for header sync procedure. Header files outside this directory will be
|
||||
# ignored by syncqt. The specifying this directory allows to skip the parsing of the whole
|
||||
# CMAKE_CURRENT_SOURCE_DIR for the header files that needs to be synced and only parse the
|
||||
# single subdirectory, that meanwhile can be outside the CMAKE_CURRENT_SOURCE_DIR tree.
|
||||
function(qt_internal_add_module target)
|
||||
qt_internal_get_internal_add_module_keywords(
|
||||
module_option_args
|
||||
@ -382,13 +389,18 @@ function(qt_internal_add_module target)
|
||||
else()
|
||||
set_property(TARGET ${target} APPEND PROPERTY EXPORT_PROPERTIES _qt_module_include_name)
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
_qt_module_include_name "${module_include_name}")
|
||||
_qt_module_include_name "${module_include_name}"
|
||||
_qt_module_has_headers ON
|
||||
)
|
||||
|
||||
# Use QT_BUILD_DIR for the syncqt call.
|
||||
# So we either write the generated files into the qtbase non-prefix build root, or the
|
||||
# module specific build root.
|
||||
# Need to call qt_ensure_sync_qt to install syncqt.pl script.
|
||||
qt_ensure_sync_qt()
|
||||
set(syncqt_full_command "${HOST_PERL}" -w "${QT_SYNCQT}"
|
||||
# Repo uses old perl script to sync files.
|
||||
if(NOT QT_USE_SYNCQT_CPP)
|
||||
# Use QT_BUILD_DIR for the syncqt call.
|
||||
# So we either write the generated files into the qtbase non-prefix build root, or the
|
||||
# module specific build root.
|
||||
set(syncqt_full_command "${HOST_PERL}" -w "${QT_SYNCQT}"
|
||||
-quiet
|
||||
-check-includes
|
||||
-module "${module_include_name}"
|
||||
@ -396,18 +408,24 @@ function(qt_internal_add_module target)
|
||||
-outdir "${QT_BUILD_DIR}"
|
||||
-builddir "${PROJECT_BINARY_DIR}"
|
||||
"${PROJECT_SOURCE_DIR}")
|
||||
message(STATUS "Running syncqt for module: '${module_include_name}' ")
|
||||
execute_process(COMMAND ${syncqt_full_command} RESULT_VARIABLE syncqt_ret)
|
||||
if(NOT syncqt_ret EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to run syncqt, return code: ${syncqt_ret}")
|
||||
message(STATUS "Running syncqt for module: '${module_include_name}' ")
|
||||
execute_process(COMMAND ${syncqt_full_command} RESULT_VARIABLE syncqt_ret)
|
||||
if(NOT syncqt_ret EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to run syncqt, return code: ${syncqt_ret}")
|
||||
endif()
|
||||
|
||||
### FIXME: Can we replace headers.pri?
|
||||
qt_read_headers_pri("${module_build_interface_include_dir}" "module_headers")
|
||||
set_property(TARGET ${target} APPEND PROPERTY
|
||||
_qt_module_timestamp_dependencies "${module_headers_generated}")
|
||||
else()
|
||||
set(sync_source_directory "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
if(arg_HEADER_SYNC_SOURCE_DIRECTORY)
|
||||
set(sync_source_directory "${arg_HEADER_SYNC_SOURCE_DIRECTORY}")
|
||||
endif()
|
||||
set_target_properties(${target} PROPERTIES
|
||||
_qt_sync_source_directory "${sync_source_directory}")
|
||||
endif()
|
||||
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
_qt_module_has_headers ON)
|
||||
|
||||
### FIXME: Can we replace headers.pri?
|
||||
qt_read_headers_pri("${module_build_interface_include_dir}" "module_headers")
|
||||
|
||||
# We should not generate export headers if module is defined as pure STATIC.
|
||||
# Static libraries don't need to export their symbols, and corner cases when sources are
|
||||
# also used in shared libraries, should be handled manually.
|
||||
@ -428,6 +446,9 @@ function(qt_internal_add_module target)
|
||||
|
||||
set(module_depends_header
|
||||
"${module_build_interface_include_dir}/${module_include_name}Depends")
|
||||
set_source_files_properties("${module_depends_header}" PROPERTIES GENERATED TRUE)
|
||||
set_target_properties(${target} PROPERTIES _qt_module_depends_header
|
||||
"${module_depends_header}")
|
||||
if(NOT ${arg_HEADER_MODULE})
|
||||
set(module_header "${module_build_interface_include_dir}/${module_include_name}")
|
||||
set_property(TARGET "${target}" PROPERTY MODULE_HEADER
|
||||
@ -455,15 +476,17 @@ function(qt_internal_add_module target)
|
||||
DESTINATION "${module_install_interface_include_dir}"
|
||||
)
|
||||
else()
|
||||
if(arg_EXTERNAL_HEADERS)
|
||||
set(module_headers_public "${arg_EXTERNAL_HEADERS}")
|
||||
if(NOT QT_USE_SYNCQT_CPP)
|
||||
if(arg_EXTERNAL_HEADERS)
|
||||
set(module_headers_public "${arg_EXTERNAL_HEADERS}")
|
||||
endif()
|
||||
qt_internal_install_module_headers(${target}
|
||||
PUBLIC
|
||||
${module_headers_public}
|
||||
"${module_depends_header}"
|
||||
"${module_header}"
|
||||
)
|
||||
endif()
|
||||
qt_internal_install_module_headers(${target}
|
||||
PUBLIC
|
||||
${module_headers_public}
|
||||
"${module_depends_header}"
|
||||
"${module_header}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -650,7 +673,7 @@ function(qt_internal_add_module target)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
if(NOT arg_HEADER_MODULE AND NOT QT_USE_SYNCQT_CPP)
|
||||
if(DEFINED module_headers_private)
|
||||
qt_internal_add_linker_version_script("${target}" PRIVATE_HEADERS ${module_headers_private} ${module_headers_qpa})
|
||||
else()
|
||||
@ -671,7 +694,7 @@ function(qt_internal_add_module target)
|
||||
string(APPEND final_injections "${extra_library_injections} ")
|
||||
endif()
|
||||
|
||||
if(final_injections)
|
||||
if(final_injections AND NOT QT_USE_SYNCQT_CPP)
|
||||
qt_install_injections(${target} "${QT_BUILD_DIR}" "${QT_INSTALL_DIR}" ${final_injections})
|
||||
endif()
|
||||
|
||||
@ -853,10 +876,9 @@ set(QT_LIBINFIX \"${QT_LIBINFIX}\")")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(QT_FEATURE_headersclean AND NOT arg_NO_MODULE_HEADERS)
|
||||
if(QT_FEATURE_headersclean AND NOT arg_NO_MODULE_HEADERS AND NOT QT_USE_SYNCQT_CPP)
|
||||
qt_internal_add_headersclean_target(
|
||||
${target}
|
||||
"${module_include_name}"
|
||||
"${module_headers_clean}")
|
||||
endif()
|
||||
|
||||
@ -890,16 +912,29 @@ endfunction()
|
||||
|
||||
function(qt_finalize_module target)
|
||||
qt_internal_collect_module_headers(module_headers ${target})
|
||||
set_property(TARGET ${target} APPEND PROPERTY
|
||||
_qt_module_timestamp_dependencies "${module_headers_public}")
|
||||
|
||||
# qt_internal_install_module_headers needs to be called before
|
||||
# qt_finalize_framework_headers_copy, because the last uses the QT_COPIED_FRAMEWORK_HEADERS
|
||||
# property which supposed to be updated inside every qt_internal_install_module_headers call.
|
||||
qt_internal_install_module_headers(${target}
|
||||
PRIVATE ${module_headers_private}
|
||||
QPA ${module_headers_qpa}
|
||||
)
|
||||
# property which supposed to be updated inside every qt_internal_install_module_headers
|
||||
# call.
|
||||
if(QT_USE_SYNCQT_CPP)
|
||||
if(QT_FEATURE_headersclean)
|
||||
qt_internal_add_headersclean_target(${target} "${module_headers_public}")
|
||||
endif()
|
||||
qt_internal_target_sync_headers(${target} "${module_headers_all}"
|
||||
"${module_headers_generated}")
|
||||
get_target_property(module_depends_header ${target} _qt_module_depends_header)
|
||||
qt_internal_install_module_headers(${target}
|
||||
PUBLIC ${module_headers_public} "${module_depends_header}"
|
||||
PRIVATE ${module_headers_private}
|
||||
QPA ${module_headers_qpa}
|
||||
)
|
||||
else()
|
||||
qt_internal_install_module_headers(${target}
|
||||
PRIVATE ${module_headers_private}
|
||||
QPA ${module_headers_qpa}
|
||||
)
|
||||
endif()
|
||||
|
||||
qt_finalize_framework_headers_copy(${target})
|
||||
qt_generate_prl_file(${target} "${INSTALL_LIBDIR}")
|
||||
@ -1098,6 +1133,13 @@ function(qt_internal_generate_cpp_global_exports target module_define_infix)
|
||||
|
||||
set(${out_public_header} "${generated_header_path}" PARENT_SCOPE)
|
||||
target_sources(${target} PRIVATE "${generated_header_path}")
|
||||
set_source_files_properties("${generated_header_path}" PROPERTIES GENERATED TRUE)
|
||||
if(NOT QT_USE_SYNCQT_CPP)
|
||||
qt_internal_install_module_headers(${target}
|
||||
PUBLIC
|
||||
"${generated_header_path}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(arg_GENERATE_PRIVATE_CPP_EXPORTS)
|
||||
set(generated_private_header_path
|
||||
@ -1110,35 +1152,7 @@ function(qt_internal_generate_cpp_global_exports target module_define_infix)
|
||||
|
||||
set(${out_private_header} "${generated_private_header_path}" PARENT_SCOPE)
|
||||
target_sources(${target} PRIVATE "${generated_private_header_path}")
|
||||
endif()
|
||||
|
||||
get_target_property(is_framework ${target} FRAMEWORK)
|
||||
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
set(is_interface_lib 0)
|
||||
if(target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
set(is_interface_lib 1)
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${target} APPEND PROPERTY
|
||||
_qt_module_timestamp_dependencies "${generated_header_path}")
|
||||
|
||||
if(is_framework)
|
||||
if(NOT is_interface_lib)
|
||||
qt_copy_framework_headers(${target} PUBLIC "${generated_header_path}")
|
||||
|
||||
if(arg_GENERATE_PRIVATE_CPP_EXPORTS)
|
||||
qt_copy_framework_headers(${target} PRIVATE "${generated_private_header_path}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
qt_install(FILES "${generated_header_path}"
|
||||
DESTINATION "${module_install_interface_include_dir}")
|
||||
|
||||
if(arg_GENERATE_PRIVATE_CPP_EXPORTS)
|
||||
qt_install(FILES "${generated_private_header_path}"
|
||||
DESTINATION "${module_install_interface_private_include_dir}")
|
||||
endif()
|
||||
set_source_files_properties("${generated_private_header_path}" PROPERTIES GENERATED TRUE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@ -1180,10 +1194,9 @@ function(qt_internal_install_module_headers target)
|
||||
qt_install(FILES ${arg_PRIVATE}
|
||||
DESTINATION "${module_install_interface_private_include_dir}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(arg_QPA)
|
||||
qt_install(FILES ${arg_QPA} DESTINATION "${module_install_interface_qpa_include_dir}")
|
||||
if(arg_QPA)
|
||||
qt_install(FILES ${arg_QPA} DESTINATION "${module_install_interface_qpa_include_dir}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@ -1191,6 +1204,7 @@ function(qt_internal_collect_module_headers out_var target)
|
||||
set(${out_var}_public "")
|
||||
set(${out_var}_private "")
|
||||
set(${out_var}_qpa "")
|
||||
set(${out_var}_all "")
|
||||
|
||||
qt_internal_get_target_sources(sources ${target})
|
||||
|
||||
@ -1203,6 +1217,7 @@ function(qt_internal_collect_module_headers out_var target)
|
||||
if(NOT file_name MATCHES ".+\\.h$")
|
||||
continue()
|
||||
endif()
|
||||
get_source_file_property(is_generated "${file_path}" GENERATED)
|
||||
get_filename_component(file_path "${file_path}" ABSOLUTE)
|
||||
get_filename_component(file_path "${file_path}" REALPATH)
|
||||
list(APPEND ${out_var}_all "${file_path}")
|
||||
@ -1213,6 +1228,9 @@ function(qt_internal_collect_module_headers out_var target)
|
||||
elseif(NOT public_filter OR file_name MATCHES "${public_filter}")
|
||||
list(APPEND ${out_var}_public "${file_path}")
|
||||
endif()
|
||||
if(is_generated)
|
||||
list(APPEND ${out_var}_generated "${file_path}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(header_types public private qpa)
|
||||
@ -1226,6 +1244,8 @@ function(qt_internal_collect_module_headers out_var target)
|
||||
|
||||
set(${out_var}_${header_type} "${${out_var}_${header_type}}" PARENT_SCOPE)
|
||||
endforeach()
|
||||
set(${out_var}_all "${${out_var}_all}" PARENT_SCOPE)
|
||||
set(${out_var}_generated "${${out_var}_generated}" PARENT_SCOPE)
|
||||
|
||||
if(has_header_types_properties)
|
||||
set_target_properties(${target} PROPERTIES ${has_header_types_properties})
|
||||
|
@ -276,6 +276,8 @@ function(qt_internal_add_plugin target)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_internal_add_autogen_sync_header_dependencies(${target} ${qt_module_target})
|
||||
endif()
|
||||
|
||||
# Change the configuration file install location for qml plugins into the Qml package location.
|
||||
|
@ -1,8 +1,9 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
function(qt_internal_write_depends_file target module_include_name)
|
||||
set(outfile "${QT_BUILD_DIR}/include/${module_include_name}/${module_include_name}Depends")
|
||||
function(qt_internal_write_depends_file target)
|
||||
get_target_property(module_depends_header ${target} _qt_module_depends_header)
|
||||
set(outfile "${module_depends_header}")
|
||||
set(contents "/* This file was generated by cmake with the info from ${target} target. */\n")
|
||||
string(APPEND contents "#ifdef __cplusplus /* create empty PCH in C mode */\n")
|
||||
foreach (m ${ARGN})
|
||||
@ -249,8 +250,7 @@ function(qt_internal_create_module_depends_file target)
|
||||
|
||||
get_target_property(hasModuleHeaders "${target}" _qt_module_has_headers)
|
||||
if (${hasModuleHeaders})
|
||||
get_target_property(module_include_name "${target}" _qt_module_include_name)
|
||||
qt_internal_write_depends_file(${target} ${module_include_name} ${qtdeps})
|
||||
qt_internal_write_depends_file(${target} ${qtdeps})
|
||||
endif()
|
||||
|
||||
if(third_party_deps OR main_module_tool_deps OR target_deps)
|
||||
|
@ -206,3 +206,269 @@ function(qt_compute_injection_forwarding_header target)
|
||||
string(APPEND ${arg_OUT_VAR} " ${relpath}:${fwd}")
|
||||
set(${arg_OUT_VAR} ${${arg_OUT_VAR}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# The function generates the Qt module header structure in build directory and creates install
|
||||
# rules. Apart the lists of header files the function takes into account
|
||||
# QT_REPO_PUBLIC_NAMESPACE_REGEX cache variable, that can be set by repository in .cmake.conf file.
|
||||
# The variable tells the syncqt program, what namespaces are treated as public. Symbols in public
|
||||
# namespaces are considered when generating CaMeL case header files.
|
||||
function(qt_internal_target_sync_headers target module_headers module_headers_generated)
|
||||
if(NOT TARGET ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt)
|
||||
message(FATAL_ERROR "${QT_CMAKE_EXPORT_NAMESPACE}::syncqt is not a target.")
|
||||
endif()
|
||||
get_target_property(has_headers ${target} _qt_module_has_headers)
|
||||
if(NOT has_headers)
|
||||
return()
|
||||
endif()
|
||||
|
||||
qt_internal_module_info(module "${target}")
|
||||
|
||||
get_target_property(sync_source_directory ${target} _qt_sync_source_directory)
|
||||
set(syncqt_timestamp "${CMAKE_CURRENT_BINARY_DIR}/${target}_syncqt_timestamp")
|
||||
set(syncqt_outputs "${syncqt_timestamp}")
|
||||
|
||||
set(is_interface_lib FALSE)
|
||||
get_target_property(type ${target} TYPE)
|
||||
if(type STREQUAL "INTERFACE_LIBRARY")
|
||||
set(is_interface_lib TRUE)
|
||||
endif()
|
||||
|
||||
set(version_script_private_content_file "")
|
||||
if(NOT is_interface_lib)
|
||||
list(APPEND syncqt_outputs
|
||||
"${module_build_interface_include_dir}/${module}Version"
|
||||
"${module_build_interface_include_dir}/qt${module_lower}version.h")
|
||||
if(TEST_ld_version_script)
|
||||
set(version_script_private_content_file
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${target}.version.private_content")
|
||||
set(version_script_args
|
||||
"-versionScript" "${version_script_private_content_file}")
|
||||
list(APPEND syncqt_outputs "${version_script_private_content_file}")
|
||||
qt_internal_add_linker_version_script(${target}
|
||||
PRIVATE_CONTENT_FILE "${version_script_private_content_file}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Check for _qt_module_is_3rdparty_header_library flag to detect non-Qt modules and
|
||||
# indicate this to syncqt.
|
||||
get_target_property(is_3rd_party_library ${target} _qt_module_is_3rdparty_header_library)
|
||||
set(non_qt_module_argument "")
|
||||
if(is_3rd_party_library)
|
||||
set(non_qt_module_argument "-nonQt")
|
||||
else()
|
||||
list(APPEND syncqt_outputs "${module_build_interface_include_dir}/${module}")
|
||||
if(QT_FEATURE_headersclean)
|
||||
list(APPEND syncqt_outputs
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${module}_header_check_exceptions")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(is_framework FALSE)
|
||||
if(NOT is_interface_lib)
|
||||
get_target_property(is_framework ${target} FRAMEWORK)
|
||||
if(is_framework)
|
||||
qt_internal_get_framework_info(fw ${target})
|
||||
get_target_property(fw_output_base_dir ${target} LIBRARY_OUTPUT_DIRECTORY)
|
||||
set(framework_args "-framework"
|
||||
"-frameworkIncludeDir" "${fw_output_base_dir}/${fw_versioned_header_dir}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_internal_get_qt_all_known_modules(known_modules)
|
||||
|
||||
get_target_property(is_internal_module ${target} _qt_is_internal_module)
|
||||
set(internal_module_argument "")
|
||||
if(is_internal_module)
|
||||
set(internal_module_argument "-internal")
|
||||
endif()
|
||||
|
||||
get_target_property(qpa_filter_regex ${target} _qt_module_qpa_headers_filter_regex)
|
||||
get_target_property(private_filter_regex ${target} _qt_module_private_headers_filter_regex)
|
||||
|
||||
# We need to use the real paths since otherwise it may lead to the invalid work of the
|
||||
# std::filesystem API
|
||||
get_filename_component(source_dir_real "${sync_source_directory}" REALPATH)
|
||||
get_filename_component(binary_dir_real "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
|
||||
|
||||
if(QT_REPO_PUBLIC_NAMESPACE_REGEX)
|
||||
set(public_namespaces_filter -publicNamespaceFilter "${QT_REPO_PUBLIC_NAMESPACE_REGEX}")
|
||||
endif()
|
||||
|
||||
if(qpa_filter_regex)
|
||||
set(qpa_filter_argument
|
||||
-qpaHeadersFilter "${qpa_filter_regex}"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(common_syncqt_arguments
|
||||
-module "${module}"
|
||||
-sourceDir "${source_dir_real}"
|
||||
-binaryDir "${binary_dir_real}"
|
||||
-privateHeadersFilter "${private_filter_regex}"
|
||||
-includeDir "${module_build_interface_include_dir}"
|
||||
-privateIncludeDir "${module_build_interface_private_include_dir}"
|
||||
-qpaIncludeDir "${module_build_interface_qpa_include_dir}"
|
||||
${qpa_filter_argument}
|
||||
${public_namespaces_filter}
|
||||
${non_qt_module_argument}
|
||||
${internal_module_argument}
|
||||
)
|
||||
|
||||
if(QT_INTERNAL_ENABLE_SYNCQT_DEBUG_OUTPUT)
|
||||
list(APPEND common_syncqt_arguments -debug)
|
||||
endif()
|
||||
|
||||
|
||||
if(is_framework)
|
||||
list(REMOVE_ITEM module_headers "${CMAKE_CURRENT_BINARY_DIR}/${target}_fake_header.h")
|
||||
endif()
|
||||
|
||||
# Filter the generated ui_ header files and header files located in the 'doc/' subdirectory.
|
||||
list(FILTER module_headers EXCLUDE REGEX
|
||||
"(.+/(ui_)[^/]+\\.h|${CMAKE_CURRENT_SOURCE_DIR}(/.+)?/doc/+\\.h)")
|
||||
|
||||
set(module_headers_rsp "${binary_dir_real}/module_headers")
|
||||
list(JOIN module_headers "\n" module_headers_string)
|
||||
qt_configure_file_v2(OUTPUT "${module_headers_rsp}" CONTENT "${module_headers_string}")
|
||||
|
||||
set(module_headers_generated_rsp "${binary_dir_real}/module_headers_generated")
|
||||
list(JOIN module_headers_generated "\n" module_headers_generated_string)
|
||||
qt_configure_file_v2(OUTPUT "${module_headers_generated_rsp}" CONTENT
|
||||
"${module_headers_generated_string}")
|
||||
|
||||
set(syncqt_staging_dir "${module_build_interface_include_dir}/.syncqt_staging")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${syncqt_outputs}
|
||||
COMMAND
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
|
||||
${common_syncqt_arguments}
|
||||
-headers "@${module_headers_rsp}"
|
||||
-generatedHeaders "@${module_headers_generated_rsp}"
|
||||
-stagingDir "${syncqt_staging_dir}"
|
||||
-knownModules ${known_modules}
|
||||
${framework_args}
|
||||
${version_script_args}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch "${syncqt_timestamp}"
|
||||
DEPENDS
|
||||
${module_headers_rsp}
|
||||
${module_headers_generated_rsp}
|
||||
${module_headers}
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
|
||||
COMMENT
|
||||
"Running syncqt.cpp for module: ${module}"
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(${target}_sync_headers
|
||||
DEPENDS
|
||||
${syncqt_outputs}
|
||||
)
|
||||
add_dependencies(sync_headers ${target}_sync_headers)
|
||||
|
||||
# This target is required when building docs, to make all header files and their aliases
|
||||
# available for qdoc.
|
||||
# ${target}_sync_headers is added as dependency to make sure that
|
||||
# ${target}_sync_all_public_headers is running after ${target}_sync_headers, when building docs.
|
||||
add_custom_target(${target}_sync_all_public_headers
|
||||
COMMAND
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
|
||||
${common_syncqt_arguments}
|
||||
-all
|
||||
DEPENDS
|
||||
${module_headers}
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
|
||||
${target}_sync_headers
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
if(NOT TARGET sync_all_public_headers)
|
||||
add_custom_target(sync_all_public_headers)
|
||||
endif()
|
||||
add_dependencies(sync_all_public_headers ${target}_sync_all_public_headers)
|
||||
|
||||
if(NOT is_3rd_party_library AND NOT is_framework)
|
||||
# Install all the CaMeL style aliases of header files from the staging directory in one rule
|
||||
qt_install(DIRECTORY "${syncqt_staging_dir}/"
|
||||
DESTINATION "${module_install_interface_include_dir}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT is_interface_lib)
|
||||
set_property(TARGET ${target}
|
||||
APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "${target}_sync_headers")
|
||||
endif()
|
||||
add_dependencies(${target} "${target}_sync_headers")
|
||||
|
||||
|
||||
get_target_property(private_module_target ${target} _qt_private_module_target_name)
|
||||
if(private_module_target)
|
||||
add_dependencies(${private_module_target} "${target}_sync_headers")
|
||||
endif()
|
||||
|
||||
# Run sync Qt first time at configure step to make all header files available for the code model
|
||||
# of IDEs.
|
||||
get_property(synced_modules GLOBAL PROPERTY _qt_synced_modules)
|
||||
if(NOT "${module}" IN_LIST synced_modules)
|
||||
message(STATUS "Running syncqt.cpp for module: ${module}")
|
||||
get_target_property(syncqt_location ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt LOCATION)
|
||||
execute_process(
|
||||
COMMAND
|
||||
${syncqt_location}
|
||||
${common_syncqt_arguments}
|
||||
-headers "@${module_headers_rsp}"
|
||||
-generatedHeaders "@${module_headers_generated_rsp}"
|
||||
-stagingDir "${syncqt_staging_dir}"
|
||||
-knownModules ${known_modules}
|
||||
${framework_args}
|
||||
RESULT_VARIABLE syncqt_result
|
||||
OUTPUT_VARIABLE syncqt_output
|
||||
ERROR_VARIABLE syncqt_output
|
||||
)
|
||||
if(NOT syncqt_result EQUAL 0)
|
||||
message(FATAL_ERROR
|
||||
"Unable to execute syncqt.cpp for module ${target}: ${syncqt_output}")
|
||||
endif()
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_synced_modules ${module})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_collect_sync_header_dependencies out_var skip_non_existing)
|
||||
if(NOT QT_USE_SYNCQT_CPP)
|
||||
set(${out_var} "" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
list(LENGTH ARGN sync_headers_target_count)
|
||||
if(sync_headers_target_count EQUAL 0)
|
||||
message(FATAL_ERROR "Invalid use of qt_internal_collect_sync_header_dependencies,"
|
||||
" dependencies are not specified")
|
||||
endif()
|
||||
|
||||
set(${out_var} "")
|
||||
foreach(sync_headers_target IN LISTS ARGN)
|
||||
set(sync_headers_target "${sync_headers_target}_sync_headers")
|
||||
if(NOT skip_non_existing OR TARGET ${sync_headers_target})
|
||||
list(APPEND ${out_var} ${sync_headers_target})
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES ${out_var})
|
||||
|
||||
set(${out_var} "${${out_var}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_add_sync_header_dependencies target)
|
||||
qt_internal_collect_sync_header_dependencies(sync_headers_targets FALSE ${ARGN})
|
||||
if(sync_headers_targets)
|
||||
add_dependencies(${target} ${sync_headers_targets})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_add_autogen_sync_header_dependencies target)
|
||||
qt_internal_collect_sync_header_dependencies(sync_headers_targets TRUE ${ARGN})
|
||||
foreach(sync_headers_target IN LISTS sync_headers_targets)
|
||||
set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS
|
||||
"${sync_headers_target}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
@ -634,10 +634,11 @@ function(qt_internal_add_configure_time_tool target_name)
|
||||
set(extra_args "INSTALL_DIRECTORY" "${install_dir}")
|
||||
endif()
|
||||
|
||||
string(REPLACE "\\\;" "\\\\\\\;" unparsed_arguments "${arg_UNPARSED_ARGUMENTS}")
|
||||
qt_internal_add_configure_time_executable(${target_name}
|
||||
OUTPUT_NAME ${name}
|
||||
${extra_args}
|
||||
${arg_UNPARSED_ARGUMENTS}
|
||||
${unparsed_arguments}
|
||||
)
|
||||
|
||||
if(NOT arg_NO_INSTALL AND arg_TOOLS_TARGET)
|
||||
|
@ -15,6 +15,9 @@ qt_add_library(QtLibraryInfo OBJECT
|
||||
propertyprinter.cpp propertyprinter.h
|
||||
qmakelibraryinfo.cpp qmakelibraryinfo.h
|
||||
)
|
||||
|
||||
qt_internal_add_sync_header_dependencies(QtLibraryInfo Core)
|
||||
|
||||
set_target_properties(QtLibraryInfo PROPERTIES
|
||||
COMPILE_OPTIONS $<TARGET_PROPERTY:Qt::Core,INTERFACE_COMPILE_OPTIONS>
|
||||
COMPILE_DEFINITIONS $<TARGET_PROPERTY:Qt::Core,INTERFACE_COMPILE_DEFINITIONS>
|
||||
|
2
src/3rdparty/harfbuzz-ng/CMakeLists.txt
vendored
2
src/3rdparty/harfbuzz-ng/CMakeLists.txt
vendored
@ -70,6 +70,8 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/harfbuzz>
|
||||
)
|
||||
|
||||
qt_internal_add_sync_header_dependencies(BundledHarfbuzz Core)
|
||||
|
||||
# GHS compiler doesn't support the __restrict keyword
|
||||
if(INTEGRITY)
|
||||
target_compile_definitions(BundledHarfbuzz PRIVATE __restrict=)
|
||||
|
2
src/3rdparty/zlib/CMakeLists.txt
vendored
2
src/3rdparty/zlib/CMakeLists.txt
vendored
@ -34,6 +34,8 @@ qt_internal_add_3rdparty_library(BundledZLIB
|
||||
$<TARGET_PROPERTY:Core,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
qt_internal_add_sync_header_dependencies(BundledZLIB Core)
|
||||
|
||||
qt_disable_warnings(BundledZLIB)
|
||||
|
||||
qt_set_symbol_visibility_hidden(BundledZLIB)
|
||||
|
@ -15,6 +15,8 @@ if(QT_FEATURE_gui)
|
||||
qt_feature_evaluate_features("${CMAKE_CURRENT_SOURCE_DIR}/gui/configure.cmake")
|
||||
endif()
|
||||
|
||||
add_subdirectory(tools/syncqt)
|
||||
|
||||
function(find_or_build_bootstrap_names)
|
||||
if (QT_WILL_BUILD_TOOLS)
|
||||
add_subdirectory(tools/bootstrap) # bootstrap library
|
||||
|
@ -377,10 +377,15 @@ endif()
|
||||
# additional json files.
|
||||
qt6_extract_metatypes(Core ${core_metatype_args})
|
||||
|
||||
set_property(TARGET Core APPEND PROPERTY
|
||||
PUBLIC_HEADER "${CMAKE_CURRENT_BINARY_DIR}/global/qconfig.h")
|
||||
set_property(TARGET Core APPEND PROPERTY
|
||||
PRIVATE_HEADER "${CMAKE_CURRENT_BINARY_DIR}/global/qconfig_p.h")
|
||||
target_sources(Core PRIVATE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/global/qconfig.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/global/qconfig_p.h"
|
||||
)
|
||||
set_source_files_properties(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/global/qconfig.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/global/qconfig_p.h"
|
||||
PROPERTIES GENERATED TRUE
|
||||
)
|
||||
|
||||
# Find ELF interpreter and define a macro for that:
|
||||
if ((LINUX OR HURD) AND NOT CMAKE_CROSSCOMPILING AND BUILD_SHARED_LIBS)
|
||||
|
@ -5,7 +5,10 @@
|
||||
#define QTCONFIGMACROS_H
|
||||
|
||||
#ifdef QT_BOOTSTRAPPED
|
||||
#include <QtCore/qconfig-bootstrapped.h>
|
||||
// qconfig-bootstrapped.h is not supposed to be a part of the synced header files. So we find it by
|
||||
// the include path specified for Bootstrap library in the source tree instead of the build tree as
|
||||
// it's done for regular header files.
|
||||
#include "qconfig-bootstrapped.h"
|
||||
#else
|
||||
#include <QtCore/qconfig.h>
|
||||
#include <QtCore/qtcore-config.h>
|
||||
|
@ -10,7 +10,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef QT_BOOTSTRAPPED
|
||||
#include <QtCore/qconfig-bootstrapped.h>
|
||||
// qconfig-bootstrapped.h is not supposed to be a part of the synced header files. So we find it by
|
||||
// the include path specified for Bootstrap library in the source tree instead of the build tree as
|
||||
// it's done for regular header files.
|
||||
#include "qconfig-bootstrapped.h"
|
||||
#else
|
||||
#include <QtCore/qconfig.h>
|
||||
#include <QtCore/qtcore-config.h>
|
||||
|
@ -109,6 +109,8 @@ if(WIN32)
|
||||
target_compile_definitions(EntryPointPrivate INTERFACE QT_NEEDS_QMAIN)
|
||||
qt_internal_extend_target(EntryPointImplementation DEFINES QT_NEEDS_QMAIN)
|
||||
endif()
|
||||
|
||||
qt_internal_add_sync_header_dependencies(EntryPointImplementation Core)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
|
@ -887,7 +887,6 @@ qt_internal_extend_target(Gui CONDITION QT_FEATURE_filesystemmodel
|
||||
qt_internal_extend_target(Gui CONDITION QT_FEATURE_vulkan
|
||||
SOURCES
|
||||
rhi/qrhivulkan.cpp rhi/qrhivulkan_p.h
|
||||
rhi/qrhivulkan_p_p.h
|
||||
rhi/qrhivulkanext_p.h
|
||||
vulkan/qbasicvulkanplatforminstance.cpp vulkan/qbasicvulkanplatforminstance_p.h
|
||||
vulkan/qplatformvulkaninstance.cpp vulkan/qplatformvulkaninstance.h
|
||||
|
@ -46,6 +46,8 @@ qt_internal_add_module(EglFSDeviceIntegrationPrivate
|
||||
Qt::FbSupportPrivate
|
||||
Qt::GuiPrivate
|
||||
EGL::EGL # special case
|
||||
HEADER_SYNC_SOURCE_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/api"
|
||||
)
|
||||
|
||||
#### Keys ignored in scope 2:.:.:eglfsdeviceintegration.pro:<TRUE>:
|
||||
|
@ -11,6 +11,9 @@
|
||||
# The bootstrap library has a few manual tweaks compared to other
|
||||
# libraries.
|
||||
qt_add_library(Bootstrap STATIC)
|
||||
|
||||
qt_internal_add_sync_header_dependencies(Bootstrap Core)
|
||||
|
||||
# special case end
|
||||
qt_internal_extend_target(Bootstrap
|
||||
SOURCES
|
||||
@ -104,6 +107,7 @@ qt_internal_extend_target(Bootstrap
|
||||
../../3rdparty/tinycbor/src
|
||||
PUBLIC_INCLUDE_DIRECTORIES # special case
|
||||
$<TARGET_PROPERTY:Core,INCLUDE_DIRECTORIES> # special case
|
||||
../../corelib/global
|
||||
PUBLIC_LIBRARIES # special case
|
||||
Qt::Platform # special case
|
||||
)
|
||||
|
30
src/tools/syncqt/CMakeLists.txt
Normal file
30
src/tools/syncqt/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
# The tool should be optimized for maximum performance when working.
|
||||
qt_internal_get_optimize_full_flags(optimize_full_flags)
|
||||
|
||||
set(compile_definitions
|
||||
QT_VERSION_STR="${PROJECT_VERSION}"
|
||||
QT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
|
||||
QT_VERSION_MINOR=${PROJECT_VERSION_MINOR}
|
||||
QT_VERSION_PATCH=${PROJECT_VERSION_PATCH}
|
||||
QT_NAMESPACE="${QT_NAMESPACE}"
|
||||
)
|
||||
|
||||
if(CMAKE_OSX_ARCHITECTURES)
|
||||
set(osx_architectures "-DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}")
|
||||
endif()
|
||||
qt_get_tool_target_name(target_name syncqt)
|
||||
qt_internal_add_configure_time_tool(${target_name}
|
||||
DEFINES ${compile_definitions}
|
||||
COMPILE_OPTIONS ${optimize_full_flags}
|
||||
TOOLS_TARGET Core
|
||||
INSTALL_DIRECTORY "${INSTALL_LIBEXECDIR}"
|
||||
CMAKE_FLAGS
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED:BOOL=TRUE
|
||||
-DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD}
|
||||
# std::filesystem API is only available in macOS 10.15+
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.15
|
||||
"${osx_architectures}"
|
||||
SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
|
||||
CONFIG RelWithDebInfo
|
||||
)
|
1567
src/tools/syncqt/main.cpp
Normal file
1567
src/tools/syncqt/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -145,6 +145,12 @@ if(IOS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(is_qt_build_platform TRUE)
|
||||
# macOS versions less than 10.15 are not supported for building Qt.
|
||||
if(CMAKE_HOST_APPLE AND CMAKE_HOST_SYSTEM_VERSION VERSION_LESS "19.0.0")
|
||||
set(is_qt_build_platform FALSE)
|
||||
endif()
|
||||
|
||||
_qt_internal_test_expect_pass(test_umbrella_config)
|
||||
_qt_internal_test_expect_pass(test_wrap_cpp_and_resources)
|
||||
if (NOT NO_WIDGETS)
|
||||
@ -274,21 +280,23 @@ elseif(QT6_INSTALL_BINS)
|
||||
endif()
|
||||
|
||||
# Test building and installing a few dummy Qt modules and plugins.
|
||||
set(mockplugins_test_args "")
|
||||
if(NOT QT_FEATURE_no_prefix)
|
||||
list(APPEND mockplugins_test_args
|
||||
BINARY "${CMAKE_COMMAND}"
|
||||
BINARY_ARGS
|
||||
"-DQT_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}/mockplugins"
|
||||
-P "${qt_install_prefix}/${qt_install_bin_dir}/qt-cmake-private-install.cmake"
|
||||
)
|
||||
endif()
|
||||
_qt_internal_test_expect_pass(mockplugins ${mockplugins_test_args})
|
||||
set_tests_properties(mockplugins PROPERTIES FIXTURES_SETUP build_mockplugins)
|
||||
if(is_qt_build_platform)
|
||||
set(mockplugins_test_args "")
|
||||
if(NOT QT_FEATURE_no_prefix)
|
||||
list(APPEND mockplugins_test_args
|
||||
BINARY "${CMAKE_COMMAND}"
|
||||
BINARY_ARGS
|
||||
"-DQT_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}/mockplugins"
|
||||
-P "${qt_install_prefix}/${qt_install_bin_dir}/qt-cmake-private-install.cmake"
|
||||
)
|
||||
endif()
|
||||
_qt_internal_test_expect_pass(mockplugins ${mockplugins_test_args})
|
||||
set_tests_properties(mockplugins PROPERTIES FIXTURES_SETUP build_mockplugins)
|
||||
|
||||
# Test importing the plugins built in the project above.
|
||||
_qt_internal_test_expect_pass(test_import_plugins BINARY ${CMAKE_CTEST_COMMAND} BINARY_ARGS -V)
|
||||
set_tests_properties(test_import_plugins PROPERTIES FIXTURES_REQUIRED build_mockplugins)
|
||||
# Test importing the plugins built in the project above.
|
||||
_qt_internal_test_expect_pass(test_import_plugins BINARY ${CMAKE_CTEST_COMMAND} BINARY_ARGS -V)
|
||||
set_tests_properties(test_import_plugins PROPERTIES FIXTURES_REQUIRED build_mockplugins)
|
||||
endif()
|
||||
|
||||
_qt_internal_test_expect_pass(test_versionless_targets)
|
||||
|
||||
@ -307,11 +315,13 @@ include(test_plugin_shared_static_flavor.cmake)
|
||||
_qt_internal_test_expect_pass(tst_qaddpreroutine
|
||||
BINARY tst_qaddpreroutine)
|
||||
|
||||
_qt_internal_test_expect_pass(test_static_resources
|
||||
BINARY "${CMAKE_CTEST_COMMAND}"
|
||||
BINARY_ARGS "-V")
|
||||
if(is_qt_build_platform)
|
||||
_qt_internal_test_expect_pass(test_static_resources
|
||||
BINARY "${CMAKE_CTEST_COMMAND}"
|
||||
BINARY_ARGS "-V")
|
||||
|
||||
_qt_internal_test_expect_pass(test_generating_cpp_exports)
|
||||
_qt_internal_test_expect_pass(test_generating_cpp_exports)
|
||||
endif()
|
||||
|
||||
_qt_internal_test_expect_pass(test_qt_extract_metatypes)
|
||||
|
||||
|
@ -1 +1,3 @@
|
||||
set(QT_REPO_MODULE_VERSION "6.5.0")
|
||||
|
||||
set(QT_USE_SYNCQT_CPP TRUE)
|
||||
|
@ -4,6 +4,7 @@
|
||||
qt_internal_add_module(MockPlugins1
|
||||
PLUGIN_TYPES mockplugin
|
||||
SOURCES
|
||||
qmockplugin.h
|
||||
fake.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
|
@ -4,6 +4,7 @@
|
||||
qt_internal_add_module(MockPlugins3
|
||||
PLUGIN_TYPES mockauxplugin
|
||||
SOURCES
|
||||
qmockauxplugin.h
|
||||
fake.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
|
Loading…
Reference in New Issue
Block a user