1 | // Copyright (C) 2022 Intel Corporation. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qglobal.h" |
5 | #include "qversiontagging.h" |
6 | |
7 | extern "C" { |
8 | #define SYM QT_MANGLE_NAMESPACE(qt_version_tag) |
9 | #define SSYM QT_STRINGIFY(SYM) |
10 | |
11 | // With compilers that have the "alias" attribute, the macro creates a global |
12 | // variable "qt_version_tag_M_m" (M: major, m: minor) as an alias to either |
13 | // qt_version_tag or _qt_version_tag. Everywhere else, we simply create a new |
14 | // global variable qt_version_tag_M_m without aliasing to a single variable. |
15 | // |
16 | // Additionally, on systems using ELF binaries (Linux, FreeBSD, etc.), we |
17 | // create ELF versions by way of the .symver assembly directive[1]. |
18 | // |
19 | // Unfortunately, Clang on Darwin systems says it supports the "alias" |
20 | // attribute, but fails when used. That's a Clang bug (as of XCode 12). |
21 | // |
22 | // [1] https://sourceware.org/binutils/docs/as/Symver.html |
23 | |
24 | #if defined(Q_CC_GNU) && defined(Q_OF_ELF) |
25 | # define make_versioned_symbol2(sym, m, n, separator) \ |
26 | Q_CORE_EXPORT extern __attribute__((alias("_" SSYM))) const char sym ## _ ## m ## _ ## n; \ |
27 | asm(".symver " QT_STRINGIFY(sym) "_" QT_STRINGIFY(m) "_" QT_STRINGIFY(n) ", " \ |
28 | QT_STRINGIFY(sym) separator "Qt_" QT_STRINGIFY(m) "." QT_STRINGIFY(n)) |
29 | |
30 | extern const char QT_MANGLE_NAMESPACE(_qt_version_tag) = 0; |
31 | #elif __has_attribute(alias) && !defined(Q_OS_DARWIN) |
32 | # define make_versioned_symbol2(sym, m, n, separator) \ |
33 | Q_CORE_EXPORT extern __attribute__((alias(SSYM))) const char sym ## _ ## m ## _ ## n |
34 | extern const char SYM = 0; |
35 | #else |
36 | # define make_versioned_symbol2(sym, m, n, separator) \ |
37 | Q_CORE_EXPORT extern const char sym ## _ ## m ## _ ## n = 0; |
38 | #endif |
39 | #define make_versioned_symbol(sym, m, n, separator) make_versioned_symbol2(sym, m, n, separator) |
40 | |
41 | #if QT_VERSION_MINOR > 0 |
42 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 0, "@" ); |
43 | #endif |
44 | #if QT_VERSION_MINOR > 1 |
45 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 1, "@" ); |
46 | #endif |
47 | #if QT_VERSION_MINOR > 2 |
48 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 2, "@" ); |
49 | #endif |
50 | #if QT_VERSION_MINOR > 3 |
51 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 3, "@" ); |
52 | #endif |
53 | #if QT_VERSION_MINOR > 4 |
54 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 4, "@" ); |
55 | #endif |
56 | #if QT_VERSION_MINOR > 5 |
57 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 5, "@" ); |
58 | #endif |
59 | #if QT_VERSION_MINOR > 6 |
60 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 6, "@" ); |
61 | #endif |
62 | #if QT_VERSION_MINOR > 7 |
63 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 7, "@" ); |
64 | #endif |
65 | #if QT_VERSION_MINOR > 8 |
66 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 8, "@" ); |
67 | #endif |
68 | #if QT_VERSION_MINOR > 9 |
69 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 9, "@" ); |
70 | #endif |
71 | #if QT_VERSION_MINOR > 10 |
72 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 10, "@" ); |
73 | #endif |
74 | #if QT_VERSION_MINOR > 11 |
75 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 11, "@" ); |
76 | #endif |
77 | #if QT_VERSION_MINOR > 12 |
78 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 12, "@" ); |
79 | #endif |
80 | #if QT_VERSION_MINOR > 13 |
81 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 13, "@" ); |
82 | #endif |
83 | #if QT_VERSION_MINOR > 14 |
84 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 14, "@" ); |
85 | #endif |
86 | #if QT_VERSION_MINOR > 15 |
87 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, 15, "@" ); |
88 | #endif |
89 | #if QT_VERSION_MINOR > 16 |
90 | # error "Please update this file with more Qt versions." |
91 | #endif |
92 | |
93 | // the default version: |
94 | make_versioned_symbol(SYM, QT_VERSION_MAJOR, QT_VERSION_MINOR, "@@" ); |
95 | } |
96 | |
97 | QT_BEGIN_NAMESPACE |
98 | |
99 | static_assert(std::is_trivially_destructible_v<QtPrivate::QVersionTag>); |
100 | |
101 | QT_END_NAMESPACE |
102 | |