CMake: support reduced relocations for namespaced Qt

The dynlist files passed to the linker have hardcoded function names
that do not take namespacing into account.
We therefore generate the dynlist files at configure time from the qt
namespace.

Task-number: QTBUG-138543
Pick-to: 6.10
Change-Id: Ib3521b83942548cb09c11687e1701c2308f9d148
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Tim Blechmann 2025-08-07 10:12:26 +08:00
parent 58215a1821
commit 06464f027a
13 changed files with 66 additions and 35 deletions

View File

@ -24,7 +24,7 @@ SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
path = ["bin/*", "coin/**","libexec/*","**_clang-format", "**.cmake", "**.conf", "**.cmake.in",
"**.prf", "libexec/qt-internal-configure-*", "config.tests/.qmake.conf",
"**.pro", "**.pri", "**.yaml", "cmake/**.in", "cmake/ios/LaunchScreen.storyboard",
"cmake/**md", "**.yml", "**.dynlist", "cmake/**.plist",
"cmake/**md", "**.yml", "**.dynlist.in", "cmake/**.plist",
"src/corelib/global/qconfig.cpp.in", "src/corelib/Qt6CoreConfigureFileTemplate.in",
"**.cfg", "**/Makefile", "**/CMakeLists.txt", "**.qrc", ".tag"]
precedence = "closest"

View File

@ -34,6 +34,7 @@ macro(qt_internal_get_internal_add_module_keywords option_args single_args multi
RHI_HEADER_FILTERS
SSG_HEADER_FILTERS
HEADER_SYNC_SOURCE_DIRECTORY
ELF_LINKER_DYNAMIC_LIST
${__default_target_info_args}
${__qt_internal_sbom_single_args}
)
@ -653,6 +654,7 @@ function(qt_internal_add_module target)
FORWARD_PREFIX arg
FORWARD_OUT_VAR extend_target_args
FORWARD_SINGLE
ELF_LINKER_DYNAMIC_LIST
PRECOMPILED_HEADER
)

View File

@ -8,6 +8,8 @@
# Name of the precompiled header that is used for the target.
# EXTRA_ELF_LINKER_SCRIPT_CONTENT
# Extra content that should be appended to a target linker script. Applicable for ld only.
# ELF_LINKER_DYNAMIC_LIST
# Pass --dynamic-list to the linker.
# Multi-value Arguments:
# CONDITION
# The condition under which the target will be extended.
@ -46,6 +48,7 @@ function(qt_internal_extend_target target)
set(single_args
PRECOMPILED_HEADER
EXTRA_ELF_LINKER_SCRIPT_CONTENT
ELF_LINKER_DYNAMIC_LIST
${__qt_internal_sbom_single_args}
)
set(multi_args
@ -330,6 +333,9 @@ function(qt_internal_extend_target target)
set_target_properties(${target} PROPERTIES
_qt_extra_elf_linker_script_exports "${arg_EXTRA_ELF_LINKER_SCRIPT_EXPORTS}")
endif()
if(arg_ELF_LINKER_DYNAMIC_LIST)
qt_internal_apply_dynamic_list_linker_flags(${target} "${arg_ELF_LINKER_DYNAMIC_LIST}")
endif()
if(is_executable)
# If linking against Gui, make sure to also build the default QPA plugin.
@ -1832,3 +1838,35 @@ function(qt_internal_add_platform_internal_target target)
IMMEDIATE_FINALIZATION
)
endfunction()
# A small wrapper for passing --dynamic-list to the linker. It will ensure that the symbols will
# be mangled when qt is compiled in a namespace
function(qt_internal_apply_dynamic_list_linker_flags target dynlist_template)
if(NOT (QT_FEATURE_reduce_relocations AND UNIX AND GCC))
return()
endif()
string(REPLACE ".in" "" dynlist_file "${dynlist_template}")
set(dynlist_file_abspath "${CMAKE_CURRENT_BINARY_DIR}/${dynlist_file}")
if(QT_NAMESPACE)
set(QT_NAMESPACE_PREFIX "${QT_NAMESPACE}::")
set(QT_NAMESPACE_MANGLE_SUFFIX "_${QT_NAMESPACE}")
else()
set(QT_NAMESPACE_PREFIX "")
set(QT_NAMESPACE_MANGLE_SUFFIX "")
endif()
configure_file(
"${dynlist_template}"
"${dynlist_file_abspath}"
)
qt_internal_extend_target(${target}
SOURCES
"${dynlist_template}"
"${dynlist_file_abspath}"
)
target_link_options(${target} PRIVATE "LINKER:--dynamic-list=${dynlist_file_abspath}")
endfunction()

View File

@ -12,7 +12,7 @@
"file_pattern_ending": ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf",
"configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in",
"Makefile", ".conf", ".yml", ".cfg", ".yaml",
".tag", ".dynlist", ".qrc"],
".tag", ".dynlist.in", ".qrc"],
"location": {
"": {
"comment": "Default",

View File

@ -388,6 +388,8 @@ qt_internal_add_module(Core
../3rdparty/sha3
../3rdparty/rfc6234
../3rdparty/tinycbor
ELF_LINKER_DYNAMIC_LIST
QtCore.dynlist.in
)
_qt_internal_setup_deploy_support()
@ -479,11 +481,6 @@ qt_internal_add_simd_part(Core SIMD mips_dsp
text/qstring_mips_dsp_asm.S
)
if(QT_FEATURE_reduce_relocations AND UNIX AND GCC)
target_link_options(Core PRIVATE
"LINKER:--dynamic-list=${CMAKE_CURRENT_LIST_DIR}/QtCore.dynlist")
endif()
if(ANDROID)
_qt_internal_add_android_executable_finalizer(Core)
set_property(TARGET Core APPEND PROPERTY QT_ANDROID_BUNDLED_JAR_DEPENDENCIES

View File

@ -1,8 +0,0 @@
{
extern "C" {
"qt_startup_hook";
};
extern "C++" {
"QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)";
};
};

View File

@ -0,0 +1,8 @@
{
extern "C" {
"qt_startup_hook@QT_NAMESPACE_MANGLE_SUFFIX@";
};
extern "C++" {
"@QT_NAMESPACE_PREFIX@QEventLoop::exec(@QT_NAMESPACE_PREFIX@QFlags<@QT_NAMESPACE_PREFIX@QEventLoop::ProcessEventsFlag>)";
};
};

View File

@ -310,6 +310,8 @@ qt_internal_add_module(Gui
../3rdparty/VulkanMemoryAllocator
# Used by qbrush.cpp -> painting/webgradients.cpp which is generated by the JS script
../../util/gradientgen
ELF_LINKER_DYNAMIC_LIST
QtGui.dynlist.in
)
# Resources:
@ -347,11 +349,6 @@ qt_internal_add_resource(Gui "gui_shaders"
"painting/shaders/backingstorecompose.frag.qsb"
)
if(QT_FEATURE_reduce_relocations AND UNIX AND GCC)
target_link_options(Gui PRIVATE
"LINKER:--dynamic-list=${CMAKE_CURRENT_LIST_DIR}/QtGui.dynlist")
endif()
qt_internal_extend_target(Gui CONDITION QT_FEATURE_standarditemmodel
SOURCES
itemmodels/qstandarditemmodel.cpp itemmodels/qstandarditemmodel.h itemmodels/qstandarditemmodel_p.h

View File

@ -1,5 +0,0 @@
{
extern "C++" {
"QGuiApplication::notify(QObject*, QEvent*)";
};
};

5
src/gui/QtGui.dynlist.in Normal file
View File

@ -0,0 +1,5 @@
{
extern "C++" {
"@QT_NAMESPACE_PREFIX@QGuiApplication::notify(@QT_NAMESPACE_PREFIX@QObject*, @QT_NAMESPACE_PREFIX@QEvent*)";
};
};

View File

@ -69,6 +69,8 @@ qt_internal_add_module(Widgets
"kernel/qt_widgets_pch.h"
NO_PCH_SOURCES
compat/removed_api.cpp
ELF_LINKER_DYNAMIC_LIST
QtWidgets.dynlist.in
)
qt_internal_extend_target(Widgets CONDITION APPLE
@ -359,11 +361,6 @@ qt_internal_add_resource(Widgets "qstyle_fusion"
${qstyle_resource_fusion_files}
)
if(QT_FEATURE_reduce_relocations AND UNIX AND GCC)
target_link_options(Widgets PRIVATE
"LINKER:--dynamic-list=${CMAKE_CURRENT_LIST_DIR}/QtWidgets.dynlist")
endif()
## Scopes:
#####################################################################

View File

@ -1,5 +0,0 @@
{
extern "C++" {
"QApplication::notify(QObject*, QEvent*)";
};
};

View File

@ -0,0 +1,5 @@
{
extern "C++" {
"@QT_NAMESPACE_PREFIX@QApplication::notify(@QT_NAMESPACE_PREFIX@QObject*, @QT_NAMESPACE_PREFIX@QEvent*)";
};
};