diff options
-rw-r--r-- | cmake/QtModuleConfig.cmake.in | 2 | ||||
-rw-r--r-- | cmake/QtModuleHelpers.cmake | 5 | ||||
-rw-r--r-- | cmake/QtTargetHelpers.cmake | 154 |
3 files changed, 161 insertions, 0 deletions
diff --git a/cmake/QtModuleConfig.cmake.in b/cmake/QtModuleConfig.cmake.in index 55402f50ca..cdb79f4bbb 100644 --- a/cmake/QtModuleConfig.cmake.in +++ b/cmake/QtModuleConfig.cmake.in @@ -27,6 +27,8 @@ endif() if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@ExtraProperties.cmake" + OPTIONAL) if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake") endif() diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake index f7c5c4b11b..1c9efc6e2d 100644 --- a/cmake/QtModuleHelpers.cmake +++ b/cmake/QtModuleHelpers.cmake @@ -800,6 +800,11 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)") EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} CONFIG_INSTALL_DIR "${config_install_dir}") + qt_internal_export_genex_properties(TARGETS ${target} + EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} + CONFIG_INSTALL_DIR "${config_install_dir}" + ) + ### fixme: cmake is missing a built-in variable for this. We want to apply it only to modules and plugins # that belong to Qt. if(NOT arg_HEADER_MODULE) diff --git a/cmake/QtTargetHelpers.cmake b/cmake/QtTargetHelpers.cmake index 80dfff7cc1..930fbc884f 100644 --- a/cmake/QtTargetHelpers.cmake +++ b/cmake/QtTargetHelpers.cmake @@ -1142,3 +1142,157 @@ function(qt_internal_get_target_sources_property out_var) endif() set(${out_var} "${${out_var}}" PARENT_SCOPE) endfunction() + +# This function collects target properties that contain generator expressions and needs to be +# exported. This function is needed since the CMake EXPORT_PROPERTIES property doesn't support +# properties that contain generator expressions. +# Usage: qt_internal_add_genex_properties_export(target properties...) +function(qt_internal_add_genex_properties_export target) + get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG) + + set(config_check_begin "") + set(config_check_end "") + if(is_multi_config) + list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type) + + # The genex snippet is evaluated to '$<NOT:$<BOOL:$<CONFIG>>>' in the generated cmake file. + # The check is only applicable to the 'main' configuration. If user project doesn't use + # multi-config generator, then the check supposed to return true and the value from the + # 'main' configuration supposed to be used. + string(JOIN "" check_if_config_empty + "$<1:$><NOT:" + "$<1:$><BOOL:" + "$<1:$><CONFIG$<ANGLE-R>" + "$<ANGLE-R>" + "$<ANGLE-R>" + ) + + # The genex snippet is evaluated to '$<CONFIG:'Qt config type'>' in the generated cmake + # file and checks if the config that user uses matches the generated cmake file config. + string(JOIN "" check_user_config + "$<1:$><CONFIG:$<CONFIG>$<ANGLE-R>" + ) + + # The genex snippet is evaluated to '$<$<OR:$<CONFIG:'Qt config type'>>:'Property content'> + # for non-main Qt configs and to + # $<$<OR:$<CONFIG:'Qt config type'>,$<NOT:$<BOOL:$<CONFIG>>>>:'Property content'> for the + # main Qt config. This guard is required to choose the correct value of the property for the + # user project according to the user config type. + # All genexes need to be escaped properly to protect them from evaluation by the + # file(GENERATE call in the qt_internal_export_genex_properties function. + string(JOIN "" config_check_begin + "$<1:$><" + "$<1:$><OR:" + "${check_user_config}" + "$<$<CONFIG:${first_config_type}>:$<COMMA>${check_if_config_empty}>" + "$<ANGLE-R>:" + ) + set(config_check_end "$<ANGLE-R>") + endif() + set(target_name "${QT_CMAKE_EXPORT_NAMESPACE}::${target}") + foreach(property IN LISTS ARGN) + set(target_property_genex "$<TARGET_PROPERTY:${target_name},${property}>") + # All properties that contain lists need to be protected of processing by JOIN genex calls. + # So this escapes the semicolons for these list. + set(target_property_list_escape + "$<JOIN:$<GENEX_EVAL:${target_property_genex}>,\;>") + set(property_value + "\"${config_check_begin}${target_property_list_escape}${config_check_end}\"") + set_property(TARGET ${target} APPEND PROPERTY _qt_export_genex_properties_content + "${property} ${property_value}") + endforeach() +endfunction() + +# This function executes generator expressions for the properties that are added by the +# qt_internal_add_genex_properties_export function and sets the calculated values to the +# corresponding properties in the generated ExtraProperties.cmake file. The file then needs to be +# included after the target creation routines in Config.cmake files. It also supports Multi-Config +# builds. +# Arguments: +# EXPORT_NAME_PREFIX: +# The portion of the file name before ExtraProperties.cmake +# CONFIG_INSTALL_DIR: +# Installation location for the file. +# TARGETS: +# The internal target names. +function(qt_internal_export_genex_properties) + set(option_args "") + set(single_args + EXPORT_NAME_PREFIX + CONFIG_INSTALL_DIR + ) + set(multi_args TARGETS) + cmake_parse_arguments(arg "${option_args}" "${single_args}" "${multi_args}" ${ARGN}) + + if(NOT arg_EXPORT_NAME_PREFIX) + message(FATAL_ERROR "qt_internal_export_genex_properties: " + "Missing EXPORT_NAME_PREFIX argument.") + endif() + + if(NOT arg_TARGETS) + message(FATAL_ERROR "qt_internal_export_genex_properties: " + "TARGETS argument must contain at least one target") + endif() + + foreach(target IN LISTS arg_TARGETS) + get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG) + + set(output_file_base_name "${arg_EXPORT_NAME_PREFIX}ExtraProperties") + set(should_append "") + set(config_suffix "") + if(is_multi_config) + list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type) + set(config_suffix "$<$<NOT:$<CONFIG:${first_config_type}>>:-$<CONFIG>>") + # If the generated file belongs to the 'main' config type, we should set property + # but not append it. + string(JOIN "" should_append + "$<$<NOT:$<CONFIG:${first_config_type}>>: APPEND>") + endif() + set(file_name "${output_file_base_name}${config_suffix}.cmake") + + qt_path_join(output_file "${arg_CONFIG_INSTALL_DIR}" + "${file_name}") + + if(NOT IS_ABSOLUTE "${output_file}") + qt_path_join(output_file "${QT_BUILD_DIR}" "${output_file}") + endif() + + set(target_name "${QT_CMAKE_EXPORT_NAMESPACE}::${target}") + + string(JOIN "" set_property_begin "set_property(TARGET " + "${target_name}${should_append} PROPERTY " + ) + set(set_property_end ")") + set(set_property_glue "${set_property_end}\n${set_property_begin}") + set(property_list + "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_export_genex_properties_content>>") + string(JOIN "" set_property_content "${set_property_begin}" + "$<JOIN:${property_list},${set_property_glue}>" + "${set_property_end}") + + if(is_multi_config) + set(config_includes "") + foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES) + if(NOT first_config_type STREQUAL config) + set(include_file_name + "${output_file_base_name}-${config}.cmake") + list(APPEND config_includes + "include(\"\${CMAKE_CURRENT_LIST_DIR}/${include_file_name}\")") + endif() + endforeach() + list(JOIN config_includes "\n" config_includes_string) + set(config_includes_string + "\n$<$<CONFIG:${first_config_type}>:${config_includes_string}>") + endif() + + file(GENERATE OUTPUT "${output_file}" + CONTENT "$<$<BOOL:${property_list}>:${set_property_content}${config_includes_string}>" + CONDITION "$<BOOL:${property_list}>" + ) + endforeach() + + qt_install(FILES "$<$<BOOL:${property_list}>:${output_file}>" + DESTINATION "${arg_CONFIG_INSTALL_DIR}" + COMPONENT Devel + ) +endfunction() |