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>
This commit is contained in:
parent
1e7a52005b
commit
893ee16352
@ -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()
|
||||
|
@ -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}
|
||||
|
@ -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()
|
||||
|
@ -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}
|
||||
|
@ -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()
|
||||
|
@ -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"
|
||||
|
@ -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})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user