diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-02-09 17:53:23 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-03-14 18:26:13 -0800 |
commit | 07b176ce70009f62fbce603c0495fa36c23b10d7 (patch) | |
tree | bf2e2ee686133dfde9bdd6e1a1c84ce0ab10727b | |
parent | dda4186842d566fe30dabe1491f35357c02dfe85 (diff) |
qversiontagging: merge the qt_version_tag symbols
The symbols all still exist, but they all have the same address. For
example, in my Linux debug build:
$ eu-readelf --dyn-syms lib/libQt6Core.t.so | grep qt_version_tag
4352: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag_6_0@@Qt_6
4356: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag_6_1@@Qt_6
4358: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag_6_2@@Qt_6
4362: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag_6_3@@Qt_6
4364: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag_6_4@@Qt_6
6458: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag@@Qt_6.4
6460: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag@Qt_6.0
6462: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag@Qt_6.2
6463: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag@Qt_6.3
6466: 00000000005e3e74 1 OBJECT GLOBAL DEFAULT 18 qt_version_tag@Qt_6.1
(The part after the @ is the ELF version; two @ indicates the default
version)
Saves N bytes where N is the Qt minor version number. The exclusion of
Darwin (macOS) is because clang says that it has the "alias" attribute,
but then fails when you use it.
Change-Id: I74249c52dc02478ba93cfffd16d249d77d6f7565
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/global/qversiontagging.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp index e79cf9f1b5..1c4a3e5dff 100644 --- a/src/corelib/global/qversiontagging.cpp +++ b/src/corelib/global/qversiontagging.cpp @@ -40,24 +40,40 @@ #include "qglobal.h" #include "qversiontagging.h" +extern "C" { #define SYM QT_MANGLE_NAMESPACE(qt_version_tag) -//#define SSYM QT_STRINGIFY(SYM) +#define SSYM QT_STRINGIFY(SYM) + +// With compilers that have the "alias" attribute, the macro creates a global +// variable "qt_version_tag_M_m" (M: major, m: minor) as an alias to either +// qt_version_tag or _qt_version_tag. Everywhere else, we simply create a new +// global variable qt_version_tag_M_m without aliasing to a single variable. +// +// Additionally, on systems using ELF binaries (Linux, FreeBSD, etc.), we +// create ELF versions by way of the .symver assembly directive[1]. +// +// Unfortunately, Clang on Darwin systems says it supports the "alias" +// attribute, but fails when used. That's a Clang bug (as of XCode 12). +// +// [1] https://sourceware.org/binutils/docs/as/Symver.html #if defined(Q_CC_GNU) && defined(Q_OF_ELF) # define make_versioned_symbol2(sym, m, n, separator) \ - Q_CORE_EXPORT extern const char sym ## _ ## m ## _ ## n = 0; \ + Q_CORE_EXPORT extern __attribute__((alias("_" SSYM))) const char sym ## _ ## m ## _ ## n; \ asm(".symver " QT_STRINGIFY(sym) "_" QT_STRINGIFY(m) "_" QT_STRINGIFY(n) ", " \ QT_STRINGIFY(sym) separator "Qt_" QT_STRINGIFY(m) "." QT_STRINGIFY(n)) +extern const char QT_MANGLE_NAMESPACE(_qt_version_tag) = 0; +#elif __has_attribute(alias) && !defined(Q_OS_DARWIN) +# define make_versioned_symbol2(sym, m, n, separator) \ + Q_CORE_EXPORT extern __attribute__((alias(SSYM))) const char sym ## _ ## m ## _ ## n +extern const char SYM = 0; #else # define make_versioned_symbol2(sym, m, n, separator) \ Q_CORE_EXPORT extern const char sym ## _ ## m ## _ ## n = 0; #endif #define make_versioned_symbol(sym, m, n, separator) make_versioned_symbol2(sym, m, n, separator) -QT_BEGIN_NAMESPACE - -extern "C" { #if QT_VERSION_MINOR > 0 make_versioned_symbol(SYM, QT_VERSION_MAJOR, 0, "@"); #endif @@ -114,6 +130,8 @@ make_versioned_symbol(SYM, QT_VERSION_MAJOR, 15, "@"); make_versioned_symbol(SYM, QT_VERSION_MAJOR, QT_VERSION_MINOR, "@@"); } +QT_BEGIN_NAMESPACE + static_assert(std::is_trivially_destructible_v<QtPrivate::QVersionTag>); QT_END_NAMESPACE |