summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Edelev <alexey.edelev@qt.io>2021-03-29 15:28:16 +0200
committerAlexey Edelev <alexey.edelev@qt.io>2021-04-27 15:12:39 +0200
commit1219dbb9f33a75ee68a6b2cac2d865e4622708cf (patch)
treebad38c3c993c533c9c506daf698477ec70944ef5
parent704c99f885d69085f3bae76e197a295adf6eab57 (diff)
Fix linking order of the resource objects
The generated object resource library depends on the Qt::Core library because uses the functions defined in qresource.cpp. Dummy linking of the Qt::Core to an object library has an effect only when the object library is linked directly to the executable as a target. If we link the object library as INTERFACE library we miss out all the objects that need to be linked to the executable. This behavior is explained here: https://bit.ly/3sFWKvI Thus, the only option to link the object library objects to the endpoint executable is to use TARGET_OBJECTS property in genex, as it's already done. But that means we are losing all profits that target actually has, especially linking the object library dependencies. The combination of both of the above methods does the job. The only thing that looks fragile so far is order. Currently, the order we use in the target_link_library call applies to the linker command line. This means the object library objects must always appear before the object library target. Change-Id: If1f0e35e0445d5e96a1f2249ab44114cd36630e9 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> (cherry picked from commit 4ed9402d7a752c739a371706fd5cd82e4626539e)
-rw-r--r--cmake/QtPrlHelpers.cmake2
-rw-r--r--src/corelib/Qt6CoreMacros.cmake27
2 files changed, 25 insertions, 4 deletions
diff --git a/cmake/QtPrlHelpers.cmake b/cmake/QtPrlHelpers.cmake
index 0c0b7a2aec..0aab301053 100644
--- a/cmake/QtPrlHelpers.cmake
+++ b/cmake/QtPrlHelpers.cmake
@@ -187,7 +187,7 @@ function(qt_internal_walk_libs
if(lib_rcc_objects_${target})
qt_merge_libs(rcc_objects ${lib_rcc_objects_${target}})
endif()
- else()
+ elseif(NOT lib_target_type STREQUAL "OBJECT_LIBRARY")
qt_merge_libs(libs "$<TARGET_LINKER_FILE:${lib_target}>")
get_target_property(target_rcc_objects "${lib_target}" _qt_rcc_objects)
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 7e65ca79d3..bc14839462 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -1326,6 +1326,13 @@ function(__qt_propagate_generated_resource target resource_name generated_source
target_compile_definitions("${resource_target}" PRIVATE
"$<TARGET_PROPERTY:${QT_CMAKE_EXPORT_NAMESPACE}::Core,INTERFACE_COMPILE_DEFINITIONS>"
)
+ # Special handling is required for the Core library resources. The linking of the Core
+ # library to the resources adds a circular dependency. This leads to the wrong
+ # objects/library order in the linker command line, since the Core library target is resolved
+ # first.
+ if(NOT target STREQUAL "Core")
+ target_link_libraries(${resource_target} INTERFACE ${QT_CMAKE_EXPORT_NAMESPACE}::Core)
+ endif()
set_property(TARGET ${resource_target} APPEND PROPERTY _qt_resource_name ${resource_name})
# Save the path to the generated source file, relative to the the current build dir.
@@ -1341,9 +1348,23 @@ function(__qt_propagate_generated_resource target resource_name generated_source
# Use TARGET_NAME genex to map to the correct prefixed target name when it is exported
# via qt_install(EXPORT), so that the consumers of the target can find the object library
- # as well.
- target_link_libraries(${target} INTERFACE
- "$<TARGET_OBJECTS:$<TARGET_NAME:${resource_target}>>")
+ # as well. It's also necessary to link the object library target, since we want to pass
+ # the object library dependencies to the target.
+ if(NOT target STREQUAL "Core")
+ target_link_libraries(${target} INTERFACE
+ "$<TARGET_OBJECTS:$<TARGET_NAME:${resource_target}>>"
+ ${resource_target}
+ )
+ else()
+ # Since linking of the Core library to the own resources adds a circular dependency
+ # we need to add the Core library resources as the target sources but not link the
+ # resource objects to the Core library. This places the resource objects to the
+ # correct position in linker line, but doesn't affect correctness of the Core library
+ # exports.
+ target_sources(${target} INTERFACE
+ "$<TARGET_OBJECTS:$<TARGET_NAME:${resource_target}>>"
+ )
+ endif()
set(${output_generated_target} "${resource_target}" PARENT_SCOPE)
# No need to compile Q_IMPORT_PLUGIN-containing files for non-executables.