summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2022-05-03 16:04:46 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2022-05-12 21:45:59 +0200
commitf4e998125981038e5e50dab8cc56039faaa0b750 (patch)
tree58df64cd3309aa459b5ffbcfc1ca568723a22368 /cmake
parent1c7ed7e73eb49fcaba7ef6b964152d75e445b573 (diff)
CMake: Fix static library link order when using qmake
qmake adds QMAKE_PRL_LIBS values on the link line after the currently processed library. Because CMake adds resource object files into QMAKE_PRL_LIBS, they end up on the link line after the library. This causes issues on Linux with GNU ld and ld.gold, because the linker discards symbols from the library which are then later referenced by the object files. Work around that by placing the path to the library directly into QMAKE_PRL_LIBS after the resource object files. This ensures the linker doesn't discard the symbols required by the resource object files. This means that each library encountered in qmake's LIBS variable will be temporarily referenced twice in qmake's project state: once from LIBS / QMAKE_PRL_TARGET, and once when the QMAKE_PRL_LIBS values are added. On the link line it will appear only once though, because qmake does library deduplication during prl file processing, which only keeps the last occurrence. Amends 4ab54320817ebbb465af343514d21139a654aed3 Pick-to: 6.2 6.3 Fixes: QTBUG-103002 Change-Id: I97647b64de22b158424850915fee62b5fea5f995 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/QtFinishPrlFile.cmake19
-rw-r--r--cmake/QtPrlHelpers.cmake1
2 files changed, 19 insertions, 1 deletions
diff --git a/cmake/QtFinishPrlFile.cmake b/cmake/QtFinishPrlFile.cmake
index 04ae2c9a43..78c7d15770 100644
--- a/cmake/QtFinishPrlFile.cmake
+++ b/cmake/QtFinishPrlFile.cmake
@@ -32,6 +32,8 @@ set(qt_framework_search_path_inserted FALSE)
foreach(line ${lines})
if(line MATCHES "^RCC_OBJECTS = (.*)")
set(rcc_objects ${CMAKE_MATCH_1})
+ elseif(line MATCHES "^QMAKE_PRL_TARGET_PATH_FOR_CMAKE = (.*)")
+ set(target_library_path "${CMAKE_MATCH_1}")
elseif(line MATCHES "^QMAKE_PRL_LIBS_FOR_CMAKE = (.*)")
unset(adjusted_libs)
foreach(lib ${CMAKE_MATCH_1})
@@ -74,7 +76,22 @@ foreach(line ${lines})
endif()
endforeach()
if(rcc_objects)
- list(PREPEND adjusted_libs ${rcc_objects})
+ set(libs_to_prepend ${rcc_objects})
+
+ # By default, when qmake processes prl files, it first puts the processed library
+ # on the link line, followed by all values specified in QMAKE_PRL_LIBS.
+ # Because we add the resource object files into QMAKE_PRL_LIBS, this means they will
+ # also appear on the link line after the library.
+ # This causes issues on Linux because the linker may discard unreferenced symbols from
+ # the library, which are referenced by the resource object files.
+ # We can't control the placement of the library in relation to QMAKE_PRL_LIBS, but we
+ # can add the library one more time in QMAKE_PRL_LIBS, after the object files.
+ # qmake's UnixMakefileGenerator::findLibraries then takes care of deduplication, which
+ # keeps the last occurrence of the library on the link line, the one after the object
+ # files.
+ list(APPEND libs_to_prepend "${target_library_path}")
+
+ list(PREPEND adjusted_libs ${libs_to_prepend})
endif()
list(JOIN adjusted_libs " " adjusted_libs_for_qmake)
string(APPEND content "QMAKE_PRL_LIBS = ${adjusted_libs_for_qmake}\n")
diff --git a/cmake/QtPrlHelpers.cmake b/cmake/QtPrlHelpers.cmake
index 18b230deb1..c467e9a634 100644
--- a/cmake/QtPrlHelpers.cmake
+++ b/cmake/QtPrlHelpers.cmake
@@ -107,6 +107,7 @@ function(qt_generate_prl_file target install_dir)
"RCC_OBJECTS = ${rcc_objects}
QMAKE_PRL_BUILD_DIR = ${CMAKE_CURRENT_BINARY_DIR}
QMAKE_PRL_TARGET = $<TARGET_LINKER_FILE_NAME:${target}>
+QMAKE_PRL_TARGET_PATH_FOR_CMAKE = $<TARGET_LINKER_FILE:${target}>
QMAKE_PRL_CONFIG = ${prl_config}
QMAKE_PRL_VERSION = ${PROJECT_VERSION}
${prl_step1_content_libs}