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>
This commit is contained in:
Alexey Edelev 2021-03-29 15:28:16 +02:00
parent 9224f8e99f
commit 4ed9402d7a
2 changed files with 25 additions and 4 deletions

View File

@ -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)

View File

@ -1191,6 +1191,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.
@ -1206,9 +1213,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.