summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qlibraryinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qlibraryinfo.cpp')
-rw-r--r--src/corelib/global/qlibraryinfo.cpp288
1 files changed, 152 insertions, 136 deletions
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index c31e1fdecf..1b03733d2a 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2021 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"
@@ -68,6 +32,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
extern void qDumpCPUFeatures(); // in qsimd.cpp
#if QT_CONFIG(settings)
@@ -116,15 +82,24 @@ void QLibrarySettings::load()
// 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();
- paths = !children.contains(QLatin1String("Platforms"))
- || children.contains(QLatin1String("Paths"));
+ paths = !children.contains("Platforms"_L1)
+ || children.contains("Paths"_L1);
}
}
+namespace {
+const QString *qtconfManualPath = nullptr;
+}
+
+void QLibraryInfoPrivate::setQtconfManualPath(const QString *path)
+{
+ qtconfManualPath = path;
+}
+
static QSettings *findConfiguration()
{
- if (!QLibraryInfoPrivate::qtconfManualPath.isEmpty())
- return new QSettings(QLibraryInfoPrivate::qtconfManualPath, QSettings::IniFormat);
+ if (qtconfManualPath)
+ return new QSettings(*qtconfManualPath, QSettings::IniFormat);
QString qtconfig = QStringLiteral(":/qt/etc/qt.conf");
if (QFile::exists(qtconfig))
@@ -133,7 +108,7 @@ static QSettings *findConfiguration()
CFBundleRef bundleRef = CFBundleGetMainBundle();
if (bundleRef) {
QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef,
- QCFString(QLatin1String("qt.conf")),
+ QCFString("qt.conf"_L1),
0,
0);
if (urlRef) {
@@ -146,18 +121,16 @@ static QSettings *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
}
-QString QLibraryInfoPrivate::qtconfManualPath;
-
QSettings *QLibraryInfoPrivate::configuration()
{
QLibrarySettings *ls = qt_library_settings();
@@ -205,42 +178,8 @@ static bool havePaths() {
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)
@@ -270,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.
@@ -282,7 +224,7 @@ QLibraryInfo::QLibraryInfo()
const char *QLibraryInfo::build() noexcept
{
- return QT_BUILD_STR;
+ return qt_build_string();
}
/*!
@@ -291,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;
@@ -301,6 +243,19 @@ QLibraryInfo::isDebugBuild()
}
/*!
+ \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.
@@ -323,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
@@ -348,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
@@ -365,7 +319,7 @@ static HMODULE getWindowsModuleHandle()
}
#endif // Q_OS_WIN
-static QString getRelocatablePrefix()
+static QString getRelocatablePrefix(QLibraryInfoPrivate::UsageMode usageMode)
{
QString prefixPath;
@@ -373,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
@@ -408,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];
@@ -443,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)) {
@@ -481,11 +448,12 @@ 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
}
@@ -519,21 +487,20 @@ QLibraryInfoPrivate::LocationInfo QLibraryInfoPrivate::locationInfo(QLibraryInfo
"Examples", "examples",
"Tests", "tests"
);
- static constexpr QByteArrayView dot = qtConfEntries.viewAt(1);
- static_assert(dot.size() == 1);
- static_assert(dot[0] == '.');
+ [[maybe_unused]]
+ constexpr QByteArrayView dot{"."};
LocationInfo result;
if (int(loc) < qtConfEntries.count()) {
- result.key = QLatin1String(qtConfEntries.viewAt(loc * 2));
- result.defaultValue = QLatin1String(qtConfEntries.viewAt(loc * 2 + 1));
+ result.key = QLatin1StringView(qtConfEntries.viewAt(loc * 2));
+ result.defaultValue = QLatin1StringView(qtConfEntries.viewAt(loc * 2 + 1));
if (result.key == u"QmlImports")
- result.fallbackKey = u"Qml2Imports"_qs;
+ result.fallbackKey = u"Qml2Imports"_s;
#ifndef Q_OS_WIN // On Windows we use the registry
} else if (loc == QLibraryInfo::SettingsPath) {
- result.key = QLatin1String("Settings");
- result.defaultValue = QLatin1String(dot);
+ result.key = "Settings"_L1;
+ result.defaultValue = QLatin1StringView(dot);
#endif
}
@@ -552,7 +519,19 @@ QLibraryInfoPrivate::LocationInfo QLibraryInfoPrivate::locationInfo(QLibraryInfo
*/
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)
@@ -563,7 +542,7 @@ QString QLibraryInfo::path(LibraryPath p)
if (!li.key.isNull()) {
QSettings *config = QLibraryInfoPrivate::configuration();
Q_ASSERT(config != nullptr);
- config->beginGroup(QLatin1String("Paths"));
+ config->beginGroup("Paths"_L1);
if (li.fallbackKey.isNull()) {
ret = config->value(li.key, li.defaultValue).toString();
@@ -574,24 +553,28 @@ QString QLibraryInfo::path(LibraryPath p)
ret = v.toString();
}
- int startIndex = 0;
- forever {
- startIndex = ret.indexOf(QLatin1Char('$'), startIndex);
+ qsizetype startIndex = 0;
+ /* We support placeholders of the form $(<ENV_VAR>) in qt.conf.
+ The loop below tries to find all such placeholders, and replaces
+ them with the actual value of the ENV_VAR environment variable
+ */
+ 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();
@@ -602,35 +585,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();
+ if (loc == QLibraryInfo::PrefixPath) {
+ ret = getPrefix(usageMode);
} else if (int(loc) <= qt_configure_strs.count()) {
- path = qt_configure_strs[loc - 1];
+ 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;
}
@@ -653,10 +632,9 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
#if QT_CONFIG(settings)
QScopedPointer<const QSettings> settings(findConfiguration());
if (!settings.isNull()) {
- const QString key = QLatin1String("Platforms")
- + QLatin1Char('/')
+ const QString key = "Platforms/"_L1
+ platformName
- + QLatin1String("Arguments");
+ + "Arguments"_L1;
return settings->value(key).toStringList();
}
#else
@@ -696,6 +674,42 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
\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)
@@ -745,13 +759,15 @@ extern const char qt_core_interpreter[] __attribute__((section(".interp")))
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_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]);