Fix qmake/qtpaths -query for static relocatable builds

The install prefix was determined incorrectly for static relocatable
builds.  The reason was that for those builds, QLibraryInfo::path()
returns the application directory, which is <prefix>/bin for qmake and
qtpaths.

Fix this by removing the bin directory part from the installation prefix
that QLibraryInfo returns if qmake/qtpaths are used.

Fixes: QTBUG-102877
Change-Id: I2e9ff96ded0ee2a7802b265741a3cfbe2bf0a4ba
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Joerg Bornemann 2022-04-28 14:37:15 +02:00
parent 277c23956c
commit fc16855eaa
3 changed files with 45 additions and 11 deletions

View File

@ -169,17 +169,22 @@ static QLibraryInfoPrivate::LocationInfo defaultLocationInfo(int loc)
return result; return result;
} }
static QString libraryInfoPath(QLibraryInfo::LibraryPath location)
{
return QLibraryInfoPrivate::path(location, QLibraryInfoPrivate::UsedFromQtBinDir);
}
static QString storedPath(int loc) static QString storedPath(int loc)
{ {
QString result; QString result;
if (loc < QMakeLibraryInfo::FirstHostPath) { if (loc < QMakeLibraryInfo::FirstHostPath) {
result = QLibraryInfo::path(static_cast<QLibraryInfo::LibraryPath>(loc)); result = libraryInfoPath(static_cast<QLibraryInfo::LibraryPath>(loc));
} else if (loc <= QMakeLibraryInfo::LastHostPath) { } else if (loc <= QMakeLibraryInfo::LastHostPath) {
if (loc == QMakeLibraryInfo::HostDataPath) { if (loc == QMakeLibraryInfo::HostDataPath) {
// Handle QT_HOST_DATADIR specially. It is not necessarily equal to QT_INSTALL_DATA. // Handle QT_HOST_DATADIR specially. It is not necessarily equal to QT_INSTALL_DATA.
result = QT_HOST_DATADIR; result = QT_HOST_DATADIR;
} else { } else {
result = QLibraryInfo::path(hostToTargetPathEnum(loc)); result = libraryInfoPath(hostToTargetPathEnum(loc));
} }
} else if (loc == QMakeLibraryInfo::SysrootPath) { } else if (loc == QMakeLibraryInfo::SysrootPath) {
// empty result // empty result

View File

@ -369,7 +369,7 @@ static HMODULE getWindowsModuleHandle()
} }
#endif // Q_OS_WIN #endif // Q_OS_WIN
static QString getRelocatablePrefix() static QString getRelocatablePrefix(QLibraryInfoPrivate::UsageMode usageMode)
{ {
QString prefixPath; QString prefixPath;
@ -377,7 +377,14 @@ static QString getRelocatablePrefix()
// For regular builds, the prefix will be relative to the location of the QtCore shared library. // For regular builds, the prefix will be relative to the location of the QtCore shared library.
#if defined(QT_STATIC) #if defined(QT_STATIC)
prefixPath = prefixFromAppDirHelper(); 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) #elif defined(Q_OS_DARWIN) && QT_CONFIG(framework)
Q_UNUSED(usageMode);
#ifndef QT_LIBINFIX #ifndef QT_LIBINFIX
#define QT_LIBINFIX "" #define QT_LIBINFIX ""
#endif #endif
@ -416,11 +423,13 @@ static QString getRelocatablePrefix()
prefixPath = QDir::cleanPath(prefixDir); prefixPath = QDir::cleanPath(prefixDir);
#elif QT_CONFIG(dlopen) #elif QT_CONFIG(dlopen)
Q_UNUSED(usageMode);
Dl_info info; Dl_info info;
int result = dladdr(reinterpret_cast<void *>(&QLibraryInfo::isDebugBuild), &info); int result = dladdr(reinterpret_cast<void *>(&QLibraryInfo::isDebugBuild), &info);
if (result > 0 && info.dli_fname) if (result > 0 && info.dli_fname)
prefixPath = prefixFromQtCoreLibraryHelper(QString::fromLocal8Bit(info.dli_fname)); prefixPath = prefixFromQtCoreLibraryHelper(QString::fromLocal8Bit(info.dli_fname));
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
Q_UNUSED(usageMode);
HMODULE hModule = getWindowsModuleHandle(); HMODULE hModule = getWindowsModuleHandle();
const int kBufferSize = 4096; const int kBufferSize = 4096;
wchar_t buffer[kBufferSize]; wchar_t buffer[kBufferSize];
@ -484,11 +493,12 @@ static QString getRelocatablePrefix()
} }
#endif #endif
static QString getPrefix() static QString getPrefix(QLibraryInfoPrivate::UsageMode usageMode)
{ {
#if QT_CONFIG(relocatable) #if QT_CONFIG(relocatable)
return getRelocatablePrefix(); return getRelocatablePrefix(usageMode);
#else #else
Q_UNUSED(usageMode);
return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH); return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH);
#endif #endif
} }
@ -555,7 +565,19 @@ QLibraryInfoPrivate::LocationInfo QLibraryInfoPrivate::locationInfo(QLibraryInfo
*/ */
QString QLibraryInfo::path(LibraryPath p) 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; QString ret;
bool fromConf = false; bool fromConf = false;
#if QT_CONFIG(settings) #if QT_CONFIG(settings)
@ -605,12 +627,12 @@ QString QLibraryInfo::path(LibraryPath p)
#endif // settings #endif // settings
if (!fromConf) { if (!fromConf) {
if (loc == PrefixPath) { if (loc == QLibraryInfo::PrefixPath) {
ret = getPrefix(); ret = getPrefix(usageMode);
} else if (int(loc) <= qt_configure_strs.count()) { } else if (int(loc) <= qt_configure_strs.count()) {
ret = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1)); ret = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1));
#ifndef Q_OS_WIN // On Windows we use the registry #ifndef Q_OS_WIN // On Windows we use the registry
} else if (loc == SettingsPath) { } else if (loc == QLibraryInfo::SettingsPath) {
// Use of volatile is a hack to discourage compilers from calling // Use of volatile is a hack to discourage compilers from calling
// strlen(), in the inlined fromLocal8Bit(const char *)'s body, at // strlen(), in the inlined fromLocal8Bit(const char *)'s body, at
// compile-time, as Qt installers binary-patch the path, replacing // compile-time, as Qt installers binary-patch the path, replacing
@ -623,11 +645,11 @@ QString QLibraryInfo::path(LibraryPath p)
if (!ret.isEmpty() && QDir::isRelativePath(ret)) { if (!ret.isEmpty() && QDir::isRelativePath(ret)) {
QString baseDir; QString baseDir;
if (loc == PrefixPath) { if (loc == QLibraryInfo::PrefixPath) {
baseDir = prefixFromAppDirHelper(); baseDir = prefixFromAppDirHelper();
} else { } else {
// we make any other path absolute to the prefix directory // we make any other path absolute to the prefix directory
baseDir = path(PrefixPath); baseDir = path(QLibraryInfo::PrefixPath, usageMode);
} }
ret = QDir::cleanPath(baseDir + u'/' + ret); ret = QDir::cleanPath(baseDir + u'/' + ret);
} }

View File

@ -79,6 +79,13 @@ public:
}; };
static LocationInfo locationInfo(QLibraryInfo::LibraryPath loc); static LocationInfo locationInfo(QLibraryInfo::LibraryPath loc);
enum UsageMode {
RegularUsage,
UsedFromQtBinDir
};
static QString path(QLibraryInfo::LibraryPath p, UsageMode usageMode = RegularUsage);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE