diff options
Diffstat (limited to 'src/corelib/global/qlibraryinfo.cpp')
-rw-r--r-- | src/corelib/global/qlibraryinfo.cpp | 476 |
1 files changed, 289 insertions, 187 deletions
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index b48b1b5d95..92729b06f1 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2021 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qdir.h" #include "qstringlist.h" @@ -45,19 +9,19 @@ #include "qsettings.h" #endif #include "qlibraryinfo.h" +#include "qlibraryinfo_p.h" #include "qscopedpointer.h" #include "qcoreapplication.h" #include "private/qglobal_p.h" +#include "archdetect.cpp" #include "qconfig.cpp" #ifdef Q_OS_DARWIN # include "private/qcore_mac_p.h" #endif // Q_OS_DARWIN -#include "archdetect.cpp" - #if QT_CONFIG(relocatable) && QT_CONFIG(dlopen) && !QT_CONFIG(framework) # include <dlfcn.h> #endif @@ -68,69 +32,75 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + extern void qDumpCPUFeatures(); // in qsimd.cpp #if QT_CONFIG(settings) +static QSettings *findConfiguration(); + struct QLibrarySettings { QLibrarySettings(); void load(); + bool havePaths(); + QSettings *configuration(); QScopedPointer<QSettings> settings; + bool paths; bool reloadOnQAppAvailable; }; Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings) -class QLibraryInfoPrivate +QLibrarySettings::QLibrarySettings() : paths(false), reloadOnQAppAvailable(false) { -public: - static QSettings *findConfiguration(); - static QSettings *configuration() - { - QLibrarySettings *ls = qt_library_settings(); - if (ls) { - if (ls->reloadOnQAppAvailable && QCoreApplication::instance() != nullptr) - ls->load(); - return ls->settings.data(); - } else { - return nullptr; - } - } -}; + load(); +} -QLibrarySettings::QLibrarySettings() +QSettings *QLibrarySettings::configuration() { - load(); + if (reloadOnQAppAvailable && QCoreApplication::instance() != nullptr) + load(); + return settings.data(); +} + +bool QLibrarySettings::havePaths() +{ + if (reloadOnQAppAvailable && QCoreApplication::instance() != nullptr) + load(); + return paths; } void QLibrarySettings::load() { // If we get any settings here, those won't change when the application shows up. - settings.reset(QLibraryInfoPrivate::findConfiguration()); + settings.reset(findConfiguration()); reloadOnQAppAvailable = (settings.data() == nullptr && QCoreApplication::instance() == nullptr); - bool haveDevicePaths; - bool haveEffectivePaths; - bool havePaths; + if (settings) { // This code needs to be in the regular library, as otherwise a qt.conf that // works for qmake would break things for dynamically built Qt tools. QStringList children = settings->childGroups(); - haveDevicePaths = children.contains(QLatin1String("DevicePaths")); - // EffectiveSourcePaths is for the Qt build only, so needs no backwards compat trickery. - bool haveEffectiveSourcePaths = false; - haveEffectivePaths = haveEffectiveSourcePaths || children.contains(QLatin1String("EffectivePaths")); - // Backwards compat: an existing but empty file is claimed to contain the Paths section. - havePaths = (!haveDevicePaths && !haveEffectivePaths - && !children.contains(QLatin1String(platformsSection))) - || children.contains(QLatin1String("Paths")); - if (!havePaths) - settings.reset(nullptr); + paths = !children.contains("Platforms"_L1) + || children.contains("Paths"_L1); } } -QSettings *QLibraryInfoPrivate::findConfiguration() +namespace { +const QString *qtconfManualPath = nullptr; +} + +void QLibraryInfoPrivate::setQtconfManualPath(const QString *path) { + qtconfManualPath = path; +} + +static QSettings *findConfiguration() +{ + if (qtconfManualPath) + return new QSettings(*qtconfManualPath, QSettings::IniFormat); + QString qtconfig = QStringLiteral(":/qt/etc/qt.conf"); if (QFile::exists(qtconfig)) return new QSettings(qtconfig, QSettings::IniFormat); @@ -138,7 +108,7 @@ QSettings *QLibraryInfoPrivate::findConfiguration() CFBundleRef bundleRef = CFBundleGetMainBundle(); if (bundleRef) { QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef, - QCFString(QLatin1String("qt.conf")), + QCFString("qt.conf"_L1), 0, 0); if (urlRef) { @@ -151,16 +121,33 @@ QSettings *QLibraryInfoPrivate::findConfiguration() #endif if (QCoreApplication::instance()) { QDir pwd(QCoreApplication::applicationDirPath()); - qtconfig = pwd.filePath(QLatin1String("qt" QT_STRINGIFY(QT_VERSION_MAJOR) ".conf")); + qtconfig = pwd.filePath(u"qt" QT_STRINGIFY(QT_VERSION_MAJOR) ".conf"_s); if (QFile::exists(qtconfig)) return new QSettings(qtconfig, QSettings::IniFormat); - qtconfig = pwd.filePath(QLatin1String("qt.conf")); + qtconfig = pwd.filePath("qt.conf"_L1); if (QFile::exists(qtconfig)) return new QSettings(qtconfig, QSettings::IniFormat); } return nullptr; //no luck } +QSettings *QLibraryInfoPrivate::configuration() +{ + QLibrarySettings *ls = qt_library_settings(); + return ls ? ls->configuration() : nullptr; +} + +void QLibraryInfoPrivate::reload() +{ + if (qt_library_settings.exists()) + qt_library_settings->load(); +} + +static bool havePaths() { + QLibrarySettings *ls = qt_library_settings(); + return ls && ls->havePaths(); +} + #endif // settings /*! @@ -191,42 +178,8 @@ QSettings *QLibraryInfoPrivate::findConfiguration() QLibraryInfo::QLibraryInfo() { } -#if defined(Q_CC_INTEL) // must be before GNU, Clang and MSVC because ICC/ICL claim to be them -# ifdef __INTEL_CLANG_COMPILER -# define ICC_COMPAT "Clang" -# elif defined(__INTEL_MS_COMPAT_LEVEL) -# define ICC_COMPAT "Microsoft" -# elif defined(__GNUC__) -# define ICC_COMPAT "GCC" -# else -# define ICC_COMPAT "no" -# endif -# if __INTEL_COMPILER == 1300 -# define ICC_VERSION "13.0" -# elif __INTEL_COMPILER == 1310 -# define ICC_VERSION "13.1" -# elif __INTEL_COMPILER == 1400 -# define ICC_VERSION "14.0" -# elif __INTEL_COMPILER == 1500 -# define ICC_VERSION "15.0" -# else -# define ICC_VERSION QT_STRINGIFY(__INTEL_COMPILER) -# endif -# ifdef __INTEL_COMPILER_UPDATE -# define COMPILER_STRING "Intel(R) C++ " ICC_VERSION "." QT_STRINGIFY(__INTEL_COMPILER_UPDATE) \ - " build " QT_STRINGIFY(__INTEL_COMPILER_BUILD_DATE) " [" \ - ICC_COMPAT " compatibility]" -# else -# define COMPILER_STRING "Intel(R) C++ " ICC_VERSION \ - " build " QT_STRINGIFY(__INTEL_COMPILER_BUILD_DATE) " [" \ - ICC_COMPAT " compatibility]" -# endif -#elif defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too -# ifdef __apple_build_version__ // Apple clang has other version numbers -# define COMPILER_STRING "Clang " __clang_version__ " (Apple)" -# else -# define COMPILER_STRING "Clang " __clang_version__ -# endif +#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too +# define COMPILER_STRING __VERSION__ /* already includes the compiler's name */ #elif defined(Q_CC_GHS) # define COMPILER_STRING "GHS " QT_STRINGIFY(__GHS_VERSION_NUMBER) #elif defined(Q_CC_GNU) @@ -236,8 +189,10 @@ QLibraryInfo::QLibraryInfo() # define COMPILER_STRING "MSVC 2015" # elif _MSC_VER < 1917 # define COMPILER_STRING "MSVC 2017" -# elif _MSC_VER < 2000 +# elif _MSC_VER < 1930 # define COMPILER_STRING "MSVC 2019" +# elif _MSC_VER < 2000 +# define COMPILER_STRING "MSVC 2022" # else # define COMPILER_STRING "MSVC _MSC_VER " QT_STRINGIFY(_MSC_VER) # endif @@ -254,7 +209,10 @@ QLibraryInfo::QLibraryInfo() #else # define SHARED_STRING " static" #endif -#define QT_BUILD_STR "Qt " QT_VERSION_STR " (" ARCH_FULL SHARED_STRING DEBUG_STRING " build; by " COMPILER_STRING ")" +static const char *qt_build_string() noexcept +{ + return "Qt " QT_VERSION_STR " (" ARCH_FULL SHARED_STRING DEBUG_STRING " build; by " COMPILER_STRING ")"; +} /*! Returns a string describing how this version of Qt was built. @@ -266,7 +224,7 @@ QLibraryInfo::QLibraryInfo() const char *QLibraryInfo::build() noexcept { - return QT_BUILD_STR; + return qt_build_string(); } /*! @@ -275,7 +233,7 @@ const char *QLibraryInfo::build() noexcept false if it was built in release mode. */ bool -QLibraryInfo::isDebugBuild() +QLibraryInfo::isDebugBuild() noexcept { #ifdef QT_DEBUG return true; @@ -284,7 +242,19 @@ QLibraryInfo::isDebugBuild() #endif } -#ifndef QT_BOOTSTRAPPED +/*! + \since 6.5 + Returns \c true if this is a shared (dynamic) build of Qt. +*/ +bool QLibraryInfo::isSharedBuild() noexcept +{ +#ifdef QT_SHARED + return true; +#else + return false; +#endif +} + /*! \since 5.8 Returns the version of the Qt library. @@ -295,7 +265,6 @@ QVersionNumber QLibraryInfo::version() noexcept { return QVersionNumber(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH); } -#endif // QT_BOOTSTRAPPED static QString prefixFromAppDirHelper() { @@ -309,7 +278,7 @@ static QString prefixFromAppDirHelper() if (urlRef) { QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); #ifdef Q_OS_MACOS - QString bundleContentsDir = QString(path) + QLatin1String("/Contents/"); + QString bundleContentsDir = QString(path) + "/Contents/"_L1; if (QDir(bundleContentsDir).exists()) return QDir::cleanPath(bundleContentsDir); #else @@ -334,8 +303,7 @@ static QString prefixFromQtCoreLibraryHelper(const QString &qtCoreLibraryPath) { const QString qtCoreLibrary = QDir::fromNativeSeparators(qtCoreLibraryPath); const QString libDir = QFileInfo(qtCoreLibrary).absolutePath(); - const QString prefixDir = libDir + QLatin1Char('/') - + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH); + const QString prefixDir = libDir + "/" QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH; return QDir::cleanPath(prefixDir); } #endif @@ -351,7 +319,7 @@ static HMODULE getWindowsModuleHandle() } #endif // Q_OS_WIN -static QString getRelocatablePrefix() +static QString getRelocatablePrefix(QLibraryInfoPrivate::UsageMode usageMode) { QString prefixPath; @@ -359,7 +327,14 @@ static QString getRelocatablePrefix() // For regular builds, the prefix will be relative to the location of the QtCore shared library. #if defined(QT_STATIC) prefixPath = prefixFromAppDirHelper(); + if (usageMode == QLibraryInfoPrivate::UsedFromQtBinDir) { + // For Qt tools in a static build, we must chop off the bin directory. + constexpr QByteArrayView binDir = qt_configure_strs.viewAt(QLibraryInfo::BinariesPath - 1); + constexpr size_t binDirLength = binDir.size() + 1; + prefixPath.chop(binDirLength); + } #elif defined(Q_OS_DARWIN) && QT_CONFIG(framework) + Q_UNUSED(usageMode); #ifndef QT_LIBINFIX #define QT_LIBINFIX "" #endif @@ -394,16 +369,22 @@ static QString getRelocatablePrefix() const QCFString libDirCFString = CFURLCopyFileSystemPath(libDirCFPath, kCFURLPOSIXPathStyle); - const QString prefixDir = QString(libDirCFString) + QLatin1Char('/') - + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH); + const QString prefixDir = QString(libDirCFString) + "/" QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH; prefixPath = QDir::cleanPath(prefixDir); +#elif defined(Q_OS_WASM) + // Emscripten expects to find shared libraries at the root of the in-memory + // file system when resolving dependencies for for dlopen() calls. So that's + // where libqt6core.so would be. + prefixPath = QStringLiteral("/"); #elif QT_CONFIG(dlopen) + Q_UNUSED(usageMode); Dl_info info; int result = dladdr(reinterpret_cast<void *>(&QLibraryInfo::isDebugBuild), &info); if (result > 0 && info.dli_fname) prefixPath = prefixFromQtCoreLibraryHelper(QString::fromLocal8Bit(info.dli_fname)); #elif defined(Q_OS_WIN) + Q_UNUSED(usageMode); HMODULE hModule = getWindowsModuleHandle(); const int kBufferSize = 4096; wchar_t buffer[kBufferSize]; @@ -417,7 +398,7 @@ static QString getRelocatablePrefix() // executable within the QT_HOST_BIN directory. We're detecting the latter case by checking // whether there's an import library corresponding to our QtCore DLL in PREFIX/lib. const QString libdir = QString::fromLocal8Bit( - qt_configure_strs + qt_configure_str_offsets[QLibraryInfo::LibrariesPath - 1]); + qt_configure_strs.viewAt(QLibraryInfo::LibrariesPath - 1)); const QLatin1Char slash('/'); #if defined(Q_CC_MINGW) const QString implibPrefix = QStringLiteral("lib"); @@ -429,7 +410,7 @@ static QString getRelocatablePrefix() const QString qtCoreImpLibFileName = implibPrefix + QFileInfo(qtCoreFilePath).completeBaseName() + implibSuffix; const QString qtCoreImpLibPath = qtCoreDirPath - + slash + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH) + + slash + QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH + slash + libdir + slash + qtCoreImpLibFileName; if (!QFileInfo::exists(qtCoreImpLibPath)) { @@ -449,7 +430,7 @@ static QString getRelocatablePrefix() // See "Hardware capabilities" in the ld.so documentation and the Qt 5.3.0 // changelog regarding SSE2 support. const QString libdir = QString::fromLocal8Bit( - qt_configure_strs + qt_configure_str_offsets[QLibraryInfo::LibrariesPath - 1]); + qt_configure_strs.viewAt(QLibraryInfo::LibrariesPath - 1)); QDir prefixDir(prefixPath); while (!prefixDir.exists(libdir)) { prefixDir.cdUp(); @@ -467,20 +448,69 @@ static QString getRelocatablePrefix() } #endif -static QString getPrefix() +static QString getPrefix(QLibraryInfoPrivate::UsageMode usageMode) { #if QT_CONFIG(relocatable) - return getRelocatablePrefix(); + return getRelocatablePrefix(usageMode); #else + Q_UNUSED(usageMode); return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH); #endif } +QLibraryInfoPrivate::LocationInfo QLibraryInfoPrivate::locationInfo(QLibraryInfo::LibraryPath loc) +{ + /* + * To add a new entry in QLibraryInfo::LibraryPath, add it to the enum + * in qtbase/src/corelib/global/qlibraryinfo.h and: + * - add its relative path in the qtConfEntries[] array below + * (the key is what appears in a qt.conf file) + */ + static constexpr auto qtConfEntries = qOffsetStringArray( + "Prefix", ".", + "Documentation", "doc", // should be ${Data}/doc + "Headers", "include", + "Libraries", "lib", +#ifdef Q_OS_WIN + "LibraryExecutables", "bin", +#else + "LibraryExecutables", "libexec", // should be ${ArchData}/libexec +#endif + "Binaries", "bin", + "Plugins", "plugins", // should be ${ArchData}/plugins + + "QmlImports", "qml", // should be ${ArchData}/qml + + "ArchData", ".", + "Data", ".", + "Translations", "translations", // should be ${Data}/translations + "Examples", "examples", + "Tests", "tests" + ); + [[maybe_unused]] + constexpr QByteArrayView dot{"."}; + + LocationInfo result; + + if (int(loc) < qtConfEntries.count()) { + result.key = QLatin1StringView(qtConfEntries.viewAt(loc * 2)); + result.defaultValue = QLatin1StringView(qtConfEntries.viewAt(loc * 2 + 1)); + if (result.key == u"QmlImports") + result.fallbackKey = u"Qml2Imports"_s; +#ifndef Q_OS_WIN // On Windows we use the registry + } else if (loc == QLibraryInfo::SettingsPath) { + result.key = "Settings"_L1; + result.defaultValue = QLatin1StringView(dot); +#endif + } + + return result; +} + /*! \fn QString QLibraryInfo::location(LibraryLocation loc) - \obsolete Use path() instead. + \deprecated [6.0] Use path() instead. Returns the path specified by \a loc. - \sa path() */ /*! @@ -489,50 +519,58 @@ static QString getPrefix() */ QString QLibraryInfo::path(LibraryPath p) { - const LibraryPath loc = p; + return QLibraryInfoPrivate::path(p); +} + + +/* + Returns the path specified by \a p. + + The usage mode can be set to UsedFromQtBinDir to enable special handling for executables that + live in <install-prefix>/bin. + */ +QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMode) +{ + const QLibraryInfo::LibraryPath loc = p; QString ret; bool fromConf = false; #if QT_CONFIG(settings) - if (QLibraryInfoPrivate::configuration()) - { + if (havePaths()) { fromConf = true; - QString key; - QString defaultValue; - if (unsigned(loc) < sizeof(qtConfEntries)/sizeof(qtConfEntries[0])) { - key = QLatin1String(qtConfEntries[loc].key); - defaultValue = QLatin1String(qtConfEntries[loc].value); - } -#ifndef Q_OS_WIN // On Windows we use the registry - else if (loc == SettingsPath) { - key = QLatin1String("Settings"); - defaultValue = QLatin1String("."); - } -#endif - - if (!key.isNull()) { + auto li = QLibraryInfoPrivate::locationInfo(loc); + if (!li.key.isNull()) { QSettings *config = QLibraryInfoPrivate::configuration(); - config->beginGroup(QLatin1String("Paths")); + Q_ASSERT(config != nullptr); + config->beginGroup("Paths"_L1); + + if (li.fallbackKey.isNull()) { + ret = config->value(li.key, li.defaultValue).toString(); + } else { + QVariant v = config->value(li.key); + if (!v.isValid()) + v = config->value(li.fallbackKey, li.defaultValue); + ret = v.toString(); + } - ret = config->value(key, defaultValue).toString(); - int startIndex = 0; - forever { - startIndex = ret.indexOf(QLatin1Char('$'), startIndex); + qsizetype startIndex = 0; + while (true) { + startIndex = ret.indexOf(u'$', startIndex); if (startIndex < 0) break; - if (ret.length() < startIndex + 3) + if (ret.size() < startIndex + 3) break; - if (ret.at(startIndex + 1) != QLatin1Char('(')) { + if (ret.at(startIndex + 1) != u'(') { startIndex++; continue; } - int endIndex = ret.indexOf(QLatin1Char(')'), startIndex + 2); + qsizetype endIndex = ret.indexOf(u')', startIndex + 2); if (endIndex < 0) break; auto envVarName = QStringView{ret}.mid(startIndex + 2, endIndex - startIndex - 2); QString value = QString::fromLocal8Bit(qgetenv(envVarName.toLocal8Bit().constData())); ret.replace(startIndex, endIndex - startIndex + 1, value); - startIndex += value.length(); + startIndex += value.size(); } config->endGroup(); @@ -543,35 +581,31 @@ QString QLibraryInfo::path(LibraryPath p) #endif // settings if (!fromConf) { - // "volatile" here is a hack to prevent compilers from doing a - // compile-time strlen() on "path". The issue is that Qt installers - // will binary-patch the Qt installation paths -- in such scenarios, Qt - // will be built with a dummy path, thus the compile-time result of - // strlen is meaningless. - const char * volatile path = nullptr; - if (loc == PrefixPath) { - ret = getPrefix(); - } else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) { - path = qt_configure_strs + qt_configure_str_offsets[loc - 1]; + if (loc == QLibraryInfo::PrefixPath) { + ret = getPrefix(usageMode); + } else if (int(loc) <= qt_configure_strs.count()) { + ret = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1)); #ifndef Q_OS_WIN // On Windows we use the registry - } else if (loc == SettingsPath) { - path = QT_CONFIGURE_SETTINGS_PATH; + } else if (loc == QLibraryInfo::SettingsPath) { + // Use of volatile is a hack to discourage compilers from calling + // strlen(), in the inlined fromLocal8Bit(const char *)'s body, at + // compile-time, as Qt installers binary-patch the path, replacing + // the dummy path seen at compile-time, typically changing length. + const char *volatile path = QT_CONFIGURE_SETTINGS_PATH; + ret = QString::fromLocal8Bit(path); #endif } - - if (path) - ret = QString::fromLocal8Bit(path); } if (!ret.isEmpty() && QDir::isRelativePath(ret)) { QString baseDir; - if (loc == PrefixPath) { + if (loc == QLibraryInfo::PrefixPath) { baseDir = prefixFromAppDirHelper(); } else { // we make any other path absolute to the prefix directory - baseDir = path(PrefixPath); + baseDir = path(QLibraryInfo::PrefixPath, usageMode); } - ret = QDir::cleanPath(baseDir + QLatin1Char('/') + ret); + ret = QDir::cleanPath(baseDir + u'/' + ret); } return ret; } @@ -592,12 +626,11 @@ QString QLibraryInfo::path(LibraryPath p) QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) { #if QT_CONFIG(settings) - QScopedPointer<const QSettings> settings(QLibraryInfoPrivate::findConfiguration()); + QScopedPointer<const QSettings> settings(findConfiguration()); if (!settings.isNull()) { - const QString key = QLatin1String(platformsSection) - + QLatin1Char('/') + const QString key = "Platforms/"_L1 + platformName - + QLatin1String("Arguments"); + + "Arguments"_L1; return settings->value(key).toStringList(); } #else @@ -621,7 +654,7 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) \value BinariesPath The path to installed Qt binaries (tools and applications). \value PluginsPath The path to installed Qt plugins. \value QmlImportsPath The path to installed QML extensions to import. - \value Qml2ImportsPath The path to installed QML extensions to import. + \value Qml2ImportsPath This value is deprecated. Use QmlImportsPath instead. \value ArchDataPath The path to general architecture-dependent Qt data. \value DataPath The path to general architecture-independent Qt data. \value TranslationsPath The path to translation information for Qt strings. @@ -634,37 +667,106 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) /*! \typealias QLibraryInfo::LibraryLocation - \obsolete Use LibraryPath with QLibraryInfo::path() instead. + \deprecated Use LibraryPath with QLibraryInfo::path() instead. +*/ + +/*! + \macro QT_VERSION_STR + \relates <QtVersion> + + This macro expands to a string that specifies Qt's version number (for + example, "6.1.2"). This is the version with which the application is + compiled. This may be a different version than the version the application + will find itself using at \e runtime. + + \sa qVersion(), QT_VERSION */ +/*! + \relates <QtVersion> + + Returns the version number of Qt at runtime as a string (for example, + "6.1.2"). This is the version of the Qt library in use at \e runtime, + which need not be the version the application was \e compiled with. + + \sa QT_VERSION_STR, QLibraryInfo::version() +*/ + +const char *qVersion() noexcept +{ + return QT_VERSION_STR; +} + +#if QT_DEPRECATED_SINCE(6, 9) + +bool qSharedBuild() noexcept +{ + return QLibraryInfo::isSharedBuild(); +} + +#endif // QT_DEPRECATED_SINCE(6, 9) + QT_END_NAMESPACE #if defined(Q_CC_GNU) && defined(ELF_INTERPRETER) +# include <elf.h> # include <stdio.h> # include <stdlib.h> #include "private/qcoreapplication_p.h" +QT_WARNING_DISABLE_GCC("-Wformat-overflow") QT_WARNING_DISABLE_GCC("-Wattributes") QT_WARNING_DISABLE_CLANG("-Wattributes") QT_WARNING_DISABLE_INTEL(2621) +# if defined(Q_OS_LINUX) +# include "minimum-linux_p.h" +# endif +# ifdef QT_ELF_NOTE_OS_TYPE +struct ElfNoteAbiTag +{ + static_assert(sizeof(Elf32_Nhdr) == sizeof(Elf64_Nhdr), + "The size of an ELF note is wrong (should be 12 bytes)"); + struct Payload { + Elf32_Word ostype = QT_ELF_NOTE_OS_TYPE; + Elf32_Word major = QT_ELF_NOTE_OS_MAJOR; + Elf32_Word minor = QT_ELF_NOTE_OS_MINOR; +# ifdef QT_ELF_NOTE_OS_PATCH + Elf32_Word patch = QT_ELF_NOTE_OS_PATCH; +# endif + }; + + Elf32_Nhdr header = { + .n_namesz = sizeof(name), + .n_descsz = sizeof(Payload), + .n_type = NT_GNU_ABI_TAG + }; + char name[sizeof ELF_NOTE_GNU] = ELF_NOTE_GNU; // yes, include the null terminator + Payload payload = {}; +}; +__attribute__((section(".note.ABI-tag"), aligned(4), used)) +extern constexpr ElfNoteAbiTag QT_MANGLE_NAMESPACE(qt_abi_tag) = {}; +# endif + extern const char qt_core_interpreter[] __attribute__((section(".interp"))) = ELF_INTERPRETER; extern "C" void qt_core_boilerplate() __attribute__((force_align_arg_pointer)); void qt_core_boilerplate() { - printf("This is the QtCore library version " QT_BUILD_STR "\n" - "Copyright (C) 2016 The Qt Company Ltd.\n" - "Contact: http://www.qt.io/licensing/\n" + printf("This is the QtCore library version %s\n" + "%s\n" + "Contact: https://www.qt.io/licensing/\n" "\n" "Installation prefix: %s\n" "Library path: %s\n" "Plugin path: %s\n", - qt_configure_prefix_path_str + 12, - qt_configure_strs + qt_configure_str_offsets[QT_PREPEND_NAMESPACE(QLibraryInfo)::LibrariesPath - 1], - qt_configure_strs + qt_configure_str_offsets[QT_PREPEND_NAMESPACE(QLibraryInfo)::PluginsPath - 1]); + QT_PREPEND_NAMESPACE(qt_build_string)(), + QT_COPYRIGHT, + QT_CONFIGURE_PREFIX_PATH, + qt_configure_strs[QT_PREPEND_NAMESPACE(QLibraryInfo)::LibrariesPath - 1], + qt_configure_strs[QT_PREPEND_NAMESPACE(QLibraryInfo)::PluginsPath - 1]); QT_PREPEND_NAMESPACE(qDumpCPUFeatures)(); |