diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-09-22 22:16:20 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-09-25 17:02:52 +0200 |
commit | 893ee163528731375cf2bc5115d73a3e8c018d17 (patch) | |
tree | 75fdf6a7b2b195772711864ab050bae32fde0d94 | |
parent | 1e7a52005b6bc92f78afee28d7e9792a2d3dfc46 (diff) |
CMake: Fix build of Release user projects against RelWithDebInfo Qt
Building a user project in Release configuration against a Qt built with
CMAKE_CONFIGURATION_TYPES=RelWithDebInfo;Debug led to the user project
being linked against the Debug Qt libraries. This is especially painful
with MSVC where debug and release runtimes are incompatible.
We now create *AdditionalTargetInfo.cmake files along the
exported *Targets.cmake files that set the IMPORT_*_<CONFIG> properties
to the values of the release config Qt was built with.
User projects built with an unknown
configuration (CMAKE_BUILD_TYPE=ArbitraryName) will link against a
release Qt. This can be controlled by setting the variable
QT_DEFAULT_IMPORT_CONFIGURATION to, for example, DEBUG in the user
project.
Fixes: QTBUG-86743
Change-Id: I12c4b065a9845c7317f6acddab46b649f2732c9e
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r-- | cmake/Qt3rdPartyLibraryConfig.cmake.in | 1 | ||||
-rw-r--r-- | cmake/Qt3rdPartyLibraryHelpers.cmake | 6 | ||||
-rw-r--r-- | cmake/QtModuleConfig.cmake.in | 1 | ||||
-rw-r--r-- | cmake/QtModuleHelpers.cmake | 5 | ||||
-rw-r--r-- | cmake/QtPluginConfig.cmake.in | 1 | ||||
-rw-r--r-- | cmake/QtPluginHelpers.cmake | 4 | ||||
-rw-r--r-- | cmake/QtTargetHelpers.cmake | 97 |
7 files changed, 115 insertions, 0 deletions
diff --git a/cmake/Qt3rdPartyLibraryConfig.cmake.in b/cmake/Qt3rdPartyLibraryConfig.cmake.in index 0facce906f..f0489b7fe1 100644 --- a/cmake/Qt3rdPartyLibraryConfig.cmake.in +++ b/cmake/Qt3rdPartyLibraryConfig.cmake.in @@ -16,6 +16,7 @@ endif() if (NOT QT_NO_CREATE_TARGETS) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake") endif() diff --git a/cmake/Qt3rdPartyLibraryHelpers.cmake b/cmake/Qt3rdPartyLibraryHelpers.cmake index a593c389f0..41c4ad6fa7 100644 --- a/cmake/Qt3rdPartyLibraryHelpers.cmake +++ b/cmake/Qt3rdPartyLibraryHelpers.cmake @@ -232,6 +232,12 @@ function(qt_internal_add_3rdparty_library target) DESTINATION "${config_install_dir}" ) + qt_internal_export_additional_targets_file( + TARGETS ${target} + EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} + CONFIG_INSTALL_DIR "${config_install_dir}" + ) + qt_internal_export_modern_cmake_config_targets_file( TARGETS ${target} EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} diff --git a/cmake/QtModuleConfig.cmake.in b/cmake/QtModuleConfig.cmake.in index f34bafb948..96e68e0caf 100644 --- a/cmake/QtModuleConfig.cmake.in +++ b/cmake/QtModuleConfig.cmake.in @@ -22,6 +22,7 @@ endif() if (NOT QT_NO_CREATE_TARGETS) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") 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 f5e43d7b30..a1f7f84b7b 100644 --- a/cmake/QtModuleHelpers.cmake +++ b/cmake/QtModuleHelpers.cmake @@ -511,6 +511,11 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})") NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE}:: DESTINATION ${config_install_dir}) + qt_internal_export_additional_targets_file( + TARGETS ${exported_targets} + EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} + CONFIG_INSTALL_DIR "${config_install_dir}") + qt_internal_export_modern_cmake_config_targets_file( TARGETS ${exported_targets} EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} diff --git a/cmake/QtPluginConfig.cmake.in b/cmake/QtPluginConfig.cmake.in index 7b9eacc766..03314d3d40 100644 --- a/cmake/QtPluginConfig.cmake.in +++ b/cmake/QtPluginConfig.cmake.in @@ -14,4 +14,5 @@ if (NOT QT_NO_CREATE_TARGETS) endif() include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") endif() diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake index 4258555d98..f00fcbd2a6 100644 --- a/cmake/QtPluginHelpers.cmake +++ b/cmake/QtPluginHelpers.cmake @@ -217,6 +217,10 @@ function(qt_internal_add_plugin target) qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix}) qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix}) + qt_internal_export_additional_targets_file( + TARGETS ${target} + EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target} + CONFIG_INSTALL_DIR "${config_install_dir}") configure_package_config_file( "${QT_CMAKE_DIR}/QtPluginConfig.cmake.in" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" diff --git a/cmake/QtTargetHelpers.cmake b/cmake/QtTargetHelpers.cmake index dd23e8c95b..7d86a6f996 100644 --- a/cmake/QtTargetHelpers.cmake +++ b/cmake/QtTargetHelpers.cmake @@ -304,6 +304,103 @@ function(qt_internal_strip_target_directory_scope_token target out_var) set("${out_var}" "${target}" PARENT_SCOPE) endfunction() +function(qt_internal_export_additional_targets_file) + cmake_parse_arguments(arg "" "EXPORT_NAME_PREFIX;CONFIG_INSTALL_DIR" "TARGETS" ${ARGN}) + + # Determine the release configurations we're currently building + if(QT_GENERATOR_IS_MULTI_CONFIG) + set(active_configurations ${CMAKE_CONFIGURATION_TYPES}) + else() + set(active_configurations ${CMAKE_BUILD_TYPE}) + endif() + unset(active_release_configurations) + foreach(config ${active_configurations}) + string(TOUPPER ${config} ucconfig) + if(NOT ucconfig STREQUAL "DEBUG") + list(APPEND active_release_configurations ${config}) + endif() + endforeach() + + # Determine the output file path + qt_path_join(output_file "${arg_CONFIG_INSTALL_DIR}" + "${arg_EXPORT_NAME_PREFIX}AdditionalTargetInfo.cmake") + if(NOT IS_ABSOLUTE "${output_file}") + qt_path_join(output_file "${QT_BUILD_DIR}" "${output_file}") + endif() + + # There's no active release configuration. Generate a dummy file. + if(NOT active_release_configurations) + qt_configure_file(OUTPUT "${output_file}" CONTENT "# Nothing to see here") + qt_install(FILES "${output_file}" DESTINATION "${arg_CONFIG_INSTALL_DIR}") + return() + endif() + + # Use the first active release configuration as *the* release config for imported targets + list(GET active_release_configurations 0 release_cfg) + string(TOUPPER ${release_cfg} uc_release_cfg) + + # Determine the release configurations we do *not* build currently + set(inactive_configurations Release;RelWithDebInfo;MinSizeRel) + list(REMOVE_ITEM inactive_configurations ${active_configurations}) + + set(content "# Additional target information for ${arg_EXPORT_NAME_PREFIX} +if(NOT DEFINED QT_DEFAULT_IMPORT_CONFIGURATION) + set(QT_DEFAULT_IMPORT_CONFIGURATION ${uc_release_cfg}) +endif() +") + foreach(target ${arg_TARGETS}) + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + continue() + endif() + set(full_target ${QT_CMAKE_EXPORT_NAMESPACE}::${target}) + set(properties_retrieved TRUE) + string(APPEND content "get_target_property(_qt_imported_location ${full_target} IMPORTED_LOCATION_${uc_release_cfg})\n") + string(APPEND content "get_target_property(_qt_imported_location_default ${full_target} IMPORTED_LOCATION_$\\{QT_DEFAULT_IMPORT_CONFIGURATION})\n") + string(APPEND content "get_target_property(_qt_imported_implib ${full_target} IMPORTED_IMPLIB_${uc_release_cfg})\n") + string(APPEND content "get_target_property(_qt_imported_implib_default ${full_target} IMPORTED_IMPLIB_$\\{QT_DEFAULT_IMPORT_CONFIGURATION})\n") + string(APPEND content "get_target_property(_qt_imported_soname ${full_target} IMPORTED_SONAME_${uc_release_cfg})\n") + string(APPEND content "get_target_property(_qt_imported_soname_default ${full_target} IMPORTED_SONAME_$\\{QT_DEFAULT_IMPORT_CONFIGURATION})\n") + foreach(config ${inactive_configurations} "") + string(TOUPPER "${config}" ucconfig) + if("${config}" STREQUAL "") + set(property_suffix "") + set(var_suffix "_default") + string(APPEND content "\n# Default configuration") + else() + set(property_suffix "_${ucconfig}") + set(var_suffix "") + string(APPEND content " +# Import target \"${full_target}\" for configuration \"${config}\" +set_property(TARGET ${full_target} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${ucconfig}) +") + endif() + string(APPEND content " +if(_qt_imported_location${var_suffix}) + set_property(TARGET ${full_target} PROPERTY IMPORTED_LOCATION${property_suffix} \"$\\{_qt_imported_location${var_suffix}}\") +endif() +if(_qt_imported_implib${var_suffix}) + set_property(TARGET ${full_target} PROPERTY IMPORTED_IMPLIB${property_suffix} \"$\\{_qt_imported_implib${var_suffix}}\") +endif() +if(_qt_imported_soname${var_suffix}) + set_property(TARGET ${full_target} PROPERTY IMPORTED_SONAME${property_suffix} \"$\\{_qt_imported_soname${var_suffix}}\") +endif() +") + endforeach() + endforeach() + + if(properties_retrieved) + string(APPEND content " +unset(_qt_imported_location) +unset(_qt_imported_location_default) +unset(_qt_imported_soname) +unset(_qt_imported_soname_default)") + endif() + + qt_configure_file(OUTPUT "${output_file}" CONTENT "${content}") + qt_install(FILES "${output_file}" DESTINATION "${arg_CONFIG_INSTALL_DIR}") +endfunction() + function(qt_internal_export_modern_cmake_config_targets_file) cmake_parse_arguments(__arg "" "EXPORT_NAME_PREFIX;CONFIG_INSTALL_DIR" "TARGETS" ${ARGN}) |