summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexey Edelev <alexey.edelev@qt.io>2021-06-10 19:01:35 +0200
committerAlexey Edelev <semlanik@gmail.com>2021-06-17 17:54:12 +0200
commit8dca66c106b93dd695210b3907190e1a947997e5 (patch)
treed1d3254283599f7e96981038ae9639bcf768ca98 /src
parent9eff3072ed47c91d5e20099de9525149c4c8b7a8 (diff)
Check the impact of static link order for user projects
For user projects we run the static link order check once 'find_package(Qt6 ...)' is called. If linker can resolve circular dependencies between static libraries and object files we set the _qt_link_order_matters property of the Qt::Platform target. This indicates the use of finalizers is not required and we may rely on CMake-base propagation of resource libraries and resource object files. If linker could not resolve circular dependencies depending on the _qt_resource_objects_finalizer_mode value: - Finalizer will be called and collected resource objects will be linked to the target directly. - Finalizer will be omitted and resource objects will be linked using the target_sources function implicitly. This only propagates resource one level up if consumer links the static library PUBLICly, but all symbols will be resolved correctly since object files are placed in the beginning of the linker line. In the CMake version 3.21 we expect that CMake will take care about the order of the resource object files in a linker line, it's expected that all object files are located at the beginning of the linker line. TODO: Need to confirm that the CMake 3.21 meets the expectations. Amends 4e901a2f99cbfda3b479253ea54b16f02e1c3aa5 Task-number: QTBUG-93002 Task-number: QTBUG-94528 Change-Id: Ia68976df8182d3d3007b90c475c1e3928a305339 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> (cherry picked from commit 5fb99e3860eb43f4bacacec7f4a4626cb0159b14)
Diffstat (limited to 'src')
-rw-r--r--src/corelib/Qt6CoreMacros.cmake48
1 files changed, 32 insertions, 16 deletions
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index f904a85be7..80f896b6ba 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -592,7 +592,7 @@ function(_qt_internal_finalize_executable target)
# dependencies the target has, but those might be added later than the qt_add_executable call.
# Most of our examples are like that. Only enable finalizer mode when we are sure that the user
# manually called qt_finalize_target at the end of their CMake project, or it was automatically
- # done via a deferred call.
+ # done via a deferred call. This is also applicable to the resource object finalizer.
get_target_property(is_immediately_finalized "${target}" _qt_is_immediately_finalized)
if(NOT is_immediately_finalized)
__qt_internal_apply_plugin_imports_finalizer_mode("${target}")
@@ -1471,7 +1471,7 @@ function(__qt_propagate_generated_resource target resource_name generated_source
)
# Keep the implicit linking if finalizers are not used.
- set(finalizer_mode_condition
+ set(not_finalizer_mode_condition
"$<NOT:$<BOOL:$<TARGET_PROPERTY:_qt_resource_objects_finalizer_mode>>>"
)
# Do not litter the static libraries
@@ -1480,22 +1480,38 @@ function(__qt_propagate_generated_resource target resource_name generated_source
)
set(resource_objects "$<TARGET_OBJECTS:$<TARGET_NAME:${resource_target}>>")
- set(resource_linking_args ${target} INTERFACE
- "$<$<AND:${finalizer_mode_condition},${not_static_condition}>:${resource_objects}>"
+ set(platform_link_order_property
+ "$<TARGET_PROPERTY:${QT_CMAKE_EXPORT_NAMESPACE}::Platform,_qt_link_order_matters>"
+ )
+ set(platform_link_order_condition
+ "$<BOOL:${platform_link_order_property}>"
)
- # TODO: The QT_LINK_ORDER_MATTERS flag is not defined for user projects.
- # It makes sense to disable finalizers if linker may resolve circular dependencies
- # between objects and static libraries.
- # Follow-up changes should set _qt_resource_objects_finalizer_mode to FALSE by default
- # and use target_link_libraries for user projects if the order doesn't affect the
- # linker work.
- get_property(link_order_matters GLOBAL PROPERTY QT_LINK_ORDER_MATTERS)
- if(link_order_matters)
- target_sources(${resource_linking_args})
- else()
- target_link_libraries(${resource_linking_args})
- endif()
+ string(JOIN "" target_sources_genex
+ "$<"
+ "$<AND:"
+ "${not_finalizer_mode_condition},"
+ "${not_static_condition},"
+ "${platform_link_order_condition}"
+ ">"
+ ":${resource_objects}>"
+ )
+ target_sources(${target} INTERFACE
+ "${target_sources_genex}"
+ )
+
+ string(JOIN "" target_link_libraries_genex
+ "$<"
+ "$<AND:"
+ "${not_finalizer_mode_condition},"
+ "${not_static_condition},"
+ "$<NOT:${platform_link_order_condition}>"
+ ">"
+ ":${resource_objects}>"
+ )
+ target_link_libraries(${target} INTERFACE
+ "${target_link_libraries_genex}"
+ )
if(NOT target STREQUAL "Core")
# It's necessary to link the object library target, since we want to pass