diff options
author | Leander Beernaert <leander.beernaert@qt.io> | 2020-02-07 14:12:27 +0100 |
---|---|---|
committer | Leander Beernaert <leander.beernaert@qt.io> | 2020-02-10 15:07:34 +0000 |
commit | c431e2d33c2b13dee8b43a08c267c20ec1ae9654 (patch) | |
tree | 16e788115741efde11f35319c9b6b152c066ac70 /src/corelib/Qt6CoreMacros.cmake | |
parent | 360d9fba237906e90559bf3477a39caf392af415 (diff) |
Refactor Metatypes dependency propagation
Every metatypes.json files is now added as an INTERFACE source file to a
target. This enables us later to correctly collect all the
metatypes.json files from dependent targets. This information is also
correctly exported via export()/install().
To avoid the metatypes.json appearing in every target's source list,
the file path is wrapped in a generator expression which will only be
evaluated when the consuming target has the property
QT_CONSUMES_METATYPES set to true. At the moment this is limited to
targets which need to interact with qmltyperegistrar.
Change-Id: I0ffebcd069a923383f7ed11cde2c94ecf2fb13f3
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'src/corelib/Qt6CoreMacros.cmake')
-rw-r--r-- | src/corelib/Qt6CoreMacros.cmake | 156 |
1 files changed, 40 insertions, 116 deletions
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index 1810fdeb65..2bc97c6d12 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -595,102 +595,7 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) endfunction() endif() -# Generate metatypes dependency file. This function extracts the list of -# metatypes files as well as the dependency file from the direct library -# dependencies of a target via generator expressions. -# Parameters: -# dep_file: Location where to generate the dependency file for build time -# dependencies. -# dep_file_install: Location where to generate the dependency file which -# is expected to be installed. -function(qt6_generate_meta_types_dep_file target dep_file dep_file_install) - # Due to generator expressions it is not possible to recursively evaluate - # the LINK_LIBRARIES of target. Therefore we generate a dependency file for - # every module with metatypes which can be evaluated at build time. - # When generating this file we need to take into account that there are two - # levels at which dependencies can be expressed: build and install. - # Build dependencies refer to targets which are being built along side the - # original target. These targets' install dependencies are not available - # at this point in time. We set a special property on these targets that's - # only available at build time. - # Install dependencies refer to targets which are found via a find_package() - # call. - # Both install and build targets have the - # INTERFACE_QT_META_TYPES_INSTALL_[DEP_FILE|FILE]. When building the target, - # INTERFACE_QT_META_TYPES_INSTALL_... refer to the expected install - # directory to be appended to CMAKE_INSTALL_PREFIX. - # Only build target have the INTERFACE_QT_META_TYPES_[DEP_FILE|FILE] which - # point to the files that have been produced during build time. - # Finally, to make sure the targets actually have a metatypes files, we - # check if they have the INTERFACE_QT_MODULE_HAS_META_TYPES property. - # - # Note: All properties start with INTERFACE_ since it is the only way to - # set properties on interface targets that get generated in the - # QtModuleConfig.in - # - get_target_property(link_dependencies ${target} LINK_LIBRARIES) - set(prop_dep "INTERFACE_QT_META_TYPES_BUILD_DEP_FILE") - set(prop_file "INTERFACE_QT_META_TYPES_BUILD_FILE") - set(prop_file_install "INTERFACE_QT_META_TYPES_INSTALL_FILE") - set(prop_dep_install "INTERFACE_QT_META_TYPES_INSTALL_DEP_FILE") - set(prop_is_local "INTERFACE_QT_MODULE_META_TYPES_FROM_BUILD") - set(prop_has_metatypes "INTERFACE_QT_MODULE_HAS_META_TYPES") - - set(gen_exp "") - set(gen_exp_install "") - foreach(dep IN LISTS link_dependencies) - # Skip over any flags starting with -, like -framework or -lboo. - if("${dep}" MATCHES "^-") - continue() - endif() - # replace LINK_ONLY with true, or we will get an error evaluating that - # generator expression - string(REPLACE "$<LINK_ONLY:" "$<1:" genex_target "$<GENEX_EVAL:${dep}>") - string(REPLACE "$<TARGET_OBJECTS:" "$<1:" genex_target "${genex_target}") - set(genex_check_is_local - "$<TARGET_GENEX_EVAL:${genex_target},$<TARGET_PROPERTY:${genex_target},${prop_is_local}>>" - ) - set(genex_is_target "$<TARGET_EXISTS:$<IF:$<BOOL:${genex_target}>,${genex_target},-NOTFOUND>>") - set(genex_has_metatypes - "$<TARGET_GENEX_EVAL:${genex_target},$<TARGET_PROPERTY:${genex_target},${prop_has_metatypes}>>" - ) - set(genex_get_metatypes - "$<TARGET_GENEX_EVAL:${genex_target},$<TARGET_PROPERTY:${genex_target},${prop_file}>>" - ) - set(genex_get_metatypes_dep - "$<TARGET_GENEX_EVAL:${genex_target},$<TARGET_PROPERTY:${genex_target},${prop_dep}>>" - ) - set(genex_get_metatypes_install - "$<TARGET_GENEX_EVAL:${genex_target},$<TARGET_PROPERTY:${genex_target},${prop_file_install}>>" - ) - set(genex_get_metatypes_install_dep - "$<TARGET_GENEX_EVAL:${genex_target},$<TARGET_PROPERTY:${genex_target},${prop_dep_install}>>" - ) - set(get_local_or_install - "$<IF:$<BOOL:${genex_check_is_local}>,${genex_get_metatypes}=${genex_get_metatypes_dep},${genex_get_metatypes_install}=${genex_get_metatypes_install_dep}>" - ) - - list(APPEND gen_exp - "$<$<AND:$<BOOL:${genex_target}>,$<BOOL:${genex_has_metatypes}>>:${get_local_or_install}>" - ) - - list(APPEND gen_exp_install - "$<$<AND:$<BOOL:${genex_target}>,$<BOOL:${genex_get_metatypes_install}>>:${genex_get_metatypes_install}=${genex_get_metatypes_install_dep}>" - ) - endforeach() - - file(GENERATE - OUTPUT "${dep_file}" - CONTENT "$<JOIN:$<GENEX_EVAL:${gen_exp}>,\n>" - ) - file(GENERATE - OUTPUT "${dep_file_install}" - CONTENT "$<JOIN:$<GENEX_EVAL:${gen_exp_install}>,\n>" - ) -endfunction() - -# # Generate Qt metatypes.json for a target. By default we check whether AUTOMOC # has been enabled and we extract the information from that target. Should you # not wish to use automoc you need to pass in all the generated json files via the @@ -808,36 +713,62 @@ function(qt6_generate_meta_types_json_file target) set(metatypes_file_name "qt6${target_lowercase}_metatypes.json") set(metatypes_file "${target_binary_dir}/meta_types/${metatypes_file_name}") + set(metatypes_file_gen "${target_binary_dir}/meta_types/${metatypes_file_name}.gen") set(metatypes_dep_file_name "qt6${target_lowercase}_metatypes_dep.txt") set(metatypes_dep_file "${target_binary_dir}/meta_types/${metatypes_dep_file_name}") - add_custom_command(OUTPUT ${metatypes_file} + # Due to generated source file dependency rules being tied to the directory + # scope in which they are created it is not possible for other targets which + # are defined in a separate scope to see these rules. This leads to failures + # in locating the generated source files. + # To work around this we write a dummy file to disk to make sure targets + # which link against the current target do not produce the error. This dummy + # file is then replaced with the contents of the generated file during + # build. + if (NOT EXISTS ${metatypes_file}) + file(MAKE_DIRECTORY "${target_binary_dir}/meta_types") + file(TOUCH ${metatypes_file}) + endif() + add_custom_command(OUTPUT ${metatypes_file_gen} ${metatypes_file} DEPENDS ${QT_CMAKE_EXPORT_NAMESPACE}::moc ${automoc_dependencies} ${manual_dependencies} COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::moc - -o ${metatypes_file} + -o ${metatypes_file_gen} --collect-json ${automoc_args} ${manual_args} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${metatypes_file_gen} + ${metatypes_file} COMMENT "Runing automoc with --collect-json" ) - target_sources(${target} PRIVATE ${metatypes_file}) + # We still need to add this file as a source of Core, otherwise the file + # rule above is not triggered. INTERFACE_SOURCES do not properly register + # as dependencies to build the current target. + target_sources(${target} PRIVATE ${metatypes_file_gen}) + set(metatypes_file_genex_build) + set(metatypes_file_genex_install) + if (arg_COPY_OVER_INSTALL) + set(metatypes_file_genex_build + "$<BUILD_INTERFACE:$<$<BOOL:$<TARGET_PROPERTY:QT_CONSUMES_METATYPES>>:${arg_INSTALL_DIR}/${metatypes_file_name}>>" + ) + else() + set(metatypes_file_genex_build + "$<BUILD_INTERFACE:$<$<BOOL:$<TARGET_PROPERTY:QT_CONSUMES_METATYPES>>:${metatypes_file}>>" + ) + set(metatypes_file_genex_install + "$<INSTALL_INTERFACE:$<$<BOOL:$<TARGET_PROPERTY:QT_CONSUMES_METATYPES>>:$<INSTALL_PREFIX>/${arg_INSTALL_DIR}/${metatypes_file_name}>>" + ) + endif() set_source_files_properties(${metatypes_file} PROPERTIES HEADER_FILE_ONLY TRUE) - # Set the required properties. See documentation of - # qt6_generate_meta_types_dep_file() set_target_properties(${target} PROPERTIES INTERFACE_QT_MODULE_HAS_META_TYPES YES INTERFACE_QT_MODULE_META_TYPES_FROM_BUILD YES INTERFACE_QT_META_TYPES_BUILD_FILE ${metatypes_file} - INTERFACE_QT_META_TYPES_BUILD_DEP_FILE ${metatypes_dep_file} - INTERFACE_QT_META_TYPES_INSTALL_FILE "${arg_INSTALL_DIR}/${metatypes_file_name}" - INTERFACE_QT_META_TYPES_INSTALL_DEP_FILE "${arg_INSTALL_DIR}/${metatypes_dep_file_name}" + QT_MODULE_META_TYPES_FILE_GENEX_BUILD "${metatypes_file_genex_build}" + QT_MODULE_META_TYPES_FILE_GENEX_INSTALL "${metatypes_file_genex_install}" ) - - qt6_generate_meta_types_dep_file(${target} - "${metatypes_dep_file}" - "${metatypes_dep_file}.install" - ) + target_sources(${target} INTERFACE ${metatypes_file_genex_build} ${metatypes_file_genex_install}) if (arg_COPY_OVER_INSTALL) get_target_property(target_type ${target} TYPE) @@ -845,13 +776,10 @@ function(qt6_generate_meta_types_json_file target) COMMAND ${CMAKE_COMMAND} -E copy_if_different "${metatypes_file}" "${arg_INSTALL_DIR}/${metatypes_file_name}" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${metatypes_dep_file}.install" - "${arg_INSTALL_DIR}/${metatypes_dep_file_name}" ) if (target_type STREQUAL "OBJECT_LIBRARY") add_custom_target(${target}_metatypes_copy - DEPENDS "${metatypes_file}" "${metatypes_dep_file}" + DEPENDS "${metatypes_file}" ${command_args} ) add_dependencies(${target} ${target}_metatypes_copy) @@ -864,10 +792,6 @@ function(qt6_generate_meta_types_json_file target) install(FILES "${metatypes_file}" DESTINATION "${arg_INSTALL_DIR}" ) - install(FILES "${metatypes_dep_file}.install" - DESTINATION "${arg_INSTALL_DIR}" - RENAME "${metatypes_dep_file_name}" - ) endif() endfunction() |