summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2020-09-22 22:16:20 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2020-09-25 17:02:52 +0200
commit893ee163528731375cf2bc5115d73a3e8c018d17 (patch)
tree75fdf6a7b2b195772711864ab050bae32fde0d94
parent1e7a52005b6bc92f78afee28d7e9792a2d3dfc46 (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.in1
-rw-r--r--cmake/Qt3rdPartyLibraryHelpers.cmake6
-rw-r--r--cmake/QtModuleConfig.cmake.in1
-rw-r--r--cmake/QtModuleHelpers.cmake5
-rw-r--r--cmake/QtPluginConfig.cmake.in1
-rw-r--r--cmake/QtPluginHelpers.cmake4
-rw-r--r--cmake/QtTargetHelpers.cmake97
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})