diff options
author | Alexey Edelev <alexey.edelev@qt.io> | 2021-06-29 18:00:39 +0200 |
---|---|---|
committer | Alexey Edelev <alexey.edelev@qt.io> | 2021-07-02 15:17:06 +0200 |
commit | e80b0107952272aa3382a84aeb6d11b6047d775e (patch) | |
tree | ff9d69552133287129092298367eaf8d681e8660 /cmake | |
parent | c72b7b8e5e530fbd03b704380940f5fa86e5341d (diff) |
Use target_link_options to propagate object libraries
target_link_options are placed by CMake at the beginning of a linker
line. This gives us an opportunity to use the function to propagate
object libraries. This change adds one more check in the root
Config.cmake file. If CMP0099 policy is enabled, CMake enables
propagating of the linking options when linking two static libraries
using the PRIVATE linking visibility, so we can rely on the correct
linking order and expect object libraries to be propagated.
Note that on the platforms where cmake version is higher than 3.16
Qt uses CMP0099 NEW in functions like qt_add_executable. This means
that at the moment of creating an executable target the TARGET_POLICY
genex will also be NEW, so we do not take into the account the user
defined CMP0099.
If the CMP0099 policy is not available for a certain CMake version
we skip the TARGET_POLICY check and simply disable propagation of
the object libraries using target_link_options for both user and Qt
libraries. This is applicable for the CMake versions 3.16 and less.
Linking approaches have the following priorities(from higher to lower)
after this change:
- target_link_libraries - works if link order matters not or CMake
version greater equal 3.21.
- target_link_options - works if CMP0099 is set to NEW by user or
if the CMake version is greater than or equal to 3.17 and an
executable is created using Qt functions.
- object library finalizer - works if CMake version is greater equal
3.19 or qt6_finalize_target is called explicitly.
- target_sources - is used when all the other approaches could not
be used.
Amends a1fd4f51ada82854f35654158a334454e760a9f7
Amends 3329212815777e33dfb4697b748d10927d73f44c
Pick-to: 6.2
Change-Id: I14f88caeb04e357191c840abeab89b03e210b796
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/QtBuildInternals/QtBuildInternalsConfig.cmake | 19 | ||||
-rw-r--r-- | cmake/QtConfig.cmake.in | 5 | ||||
-rw-r--r-- | cmake/QtPublicTargetHelpers.cmake | 46 |
3 files changed, 66 insertions, 4 deletions
diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake index 2547282dca..8fa0e69c3e 100644 --- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake +++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake @@ -977,8 +977,27 @@ function(qt_internal_static_link_order_test) ) endfunction() +function(qt_internal_check_cmp0099_available) + # Don't care about CMP0099 in CMake versions greater than or equal to 3.21 + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) + return() + endif() + + __qt_internal_check_cmp0099_available(result) + if(result) + set(summary_message "yes") + else() + set(summary_message "no") + endif() + qt_configure_add_summary_entry(TYPE "message" + ARGS "CMake policy CMP0099 is supported" + MESSAGE "${summary_message}" + ) +endfunction() + function(qt_internal_run_common_config_tests) qt_configure_add_summary_section(NAME "Common build options") qt_internal_static_link_order_test() + qt_internal_check_cmp0099_available() qt_configure_end_summary_section() endfunction() diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in index cc3b2d7fce..92e47a04a0 100644 --- a/cmake/QtConfig.cmake.in +++ b/cmake/QtConfig.cmake.in @@ -126,4 +126,7 @@ if (_Qt_NOTFOUND_MESSAGE) endif() __qt_internal_defer_promote_targets_in_dir_scope_to_global() -__qt_internal_check_link_order_matters() +if(CMAKE_VERSION VERSION_LESS 3.21) + __qt_internal_check_link_order_matters() + __qt_internal_check_cmp0099_available() +endif() diff --git a/cmake/QtPublicTargetHelpers.cmake b/cmake/QtPublicTargetHelpers.cmake index a116d2dd5d..b84a874880 100644 --- a/cmake/QtPublicTargetHelpers.cmake +++ b/cmake/QtPublicTargetHelpers.cmake @@ -87,6 +87,37 @@ function(__qt_internal_check_link_order_matters) endif() endfunction() +# Constructs a TARGET_POLICY genex expression if the policy is available. +function(__qt_internal_get_cmp0099_genex_check result) + if(POLICY CMP0099) + set(${result} "$<BOOL:$<TARGET_POLICY:CMP0099>>" PARENT_SCOPE) + else() + set(${result} "$<BOOL:FALSE>" PARENT_SCOPE) + endif() +endfunction() + +function(__qt_internal_check_cmp0099_available) + set(platform_target ${QT_CMAKE_EXPORT_NAMESPACE}::Platform) + get_target_property(aliased_target ${platform_target} ALIASED_TARGET) + if(aliased_target) + set(platform_target "${aliased_target}") + endif() + + __qt_internal_get_cmp0099_genex_check(cmp0099_check) + set_target_properties(${platform_target} PROPERTIES + _qt_cmp0099_policy_check "${cmp0099_check}" + ) + + set(result TRUE) + if(NOT POLICY CMP0099) + set(result FALSE) + endif() + + if("${ARGC}" GREATER "0" AND NOT ARGV0 STREQUAL "") + set(${ARGV0} ${result} PARENT_SCOPE) + endif() +endfunction() + function(__qt_internal_process_dependency_object_libraries target) # The CMake versions greater than 3.21 take care about the order of object files in a # linker line, it's expected that all object files are located at the beginning of the linker @@ -134,17 +165,19 @@ function(__qt_internal_collect_dependency_object_libraries target out_var) ) set_property(GLOBAL PROPERTY _qt_processed_object_libraries "") + __qt_internal_get_cmp0099_genex_check(cmp0099_check) list(REMOVE_DUPLICATES object_libraries) set(objects "") foreach(dep IN LISTS object_libraries) - list(PREPEND objects "$<TARGET_OBJECTS:${dep}>") + list(PREPEND objects "$<$<NOT:${cmp0099_check}>:$<TARGET_OBJECTS:${dep}>>") endforeach() set(${out_var} "${plugin_objects};${objects}" PARENT_SCOPE) endfunction() function(__qt_internal_collect_dependency_plugin_object_libraries target plugin_targets out_var) + __qt_internal_get_cmp0099_genex_check(cmp0099_check) set(plugin_objects "") foreach(plugin_target IN LISTS plugin_targets) __qt_internal_collect_object_libraries_recursively(plugin_object_libraries @@ -154,9 +187,16 @@ function(__qt_internal_collect_dependency_plugin_object_libraries target plugin_ __qt_internal_get_static_plugin_condition_genex("${plugin_target}" plugin_condition) foreach(plugin_object_library IN LISTS plugin_object_libraries) - list(APPEND plugin_objects - "$<${plugin_condition}:$<TARGET_OBJECTS:${plugin_object_library}>>" + string(JOIN "" plugin_objects_genex + "$<" + "$<AND:" + "$<NOT:${cmp0099_check}>," + "${plugin_condition}" + ">" + ":$<TARGET_OBJECTS:${plugin_object_library}>" + ">" ) + list(APPEND plugin_objects "${plugin_objects_genex}") endforeach() endforeach() set(${out_var} "${plugin_objects}" PARENT_SCOPE) |