summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtModuleConfig.cmake.in2
-rw-r--r--cmake/QtModuleHelpers.cmake5
-rw-r--r--cmake/QtTargetHelpers.cmake154
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()