Fix prefix determination for windeployqt'ed applications

Qt5Core.dll of windeployqt'ed applications is right next to the
executable, and the prefix is considered the directory where the
application is located. QLibraryInfo of a relocatable Qt5Core.dll would
return a wrong prefix (by default <app dir>/..), because it determines
the prefix with QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH (by default "..").

We now detect whether the executable was windeployqt'ed by checking
whether Qt5Core.dll is next to the executable.

However, we must not do that for applications in QT_HOST_BINS, because
they are not windeployqt'ed and must still use the standard prefix.
We detect this case by checking whether for Qt5Core.dll exists a
corresponding Qt5Core.lib in the libdir below the detected prefix.

Fixes: QTBUG-79318
Change-Id: I1c9b971b282c6b9b19a93f1819ba8aee74be5be4
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
Joerg Bornemann 2019-11-22 09:24:55 +01:00
parent 578a020e65
commit a131d6100c

View File

@ -562,9 +562,31 @@ static QString getRelocatablePrefix()
HMODULE hModule = getWindowsModuleHandle();
const int kBufferSize = 4096;
wchar_t buffer[kBufferSize];
const int pathSize = GetModuleFileName(hModule, buffer, kBufferSize);
if (pathSize > 0)
prefixPath = prefixFromQtCoreLibraryHelper(QString::fromWCharArray(buffer, pathSize));
DWORD pathSize = GetModuleFileName(hModule, buffer, kBufferSize);
const QString qtCoreFilePath = QString::fromWCharArray(buffer, int(pathSize));
const QString qtCoreDirPath = QFileInfo(qtCoreFilePath).absolutePath();
pathSize = GetModuleFileName(NULL, buffer, kBufferSize);
const QString exeDirPath = QFileInfo(QString::fromWCharArray(buffer, int(pathSize))).absolutePath();
if (QFileInfo(exeDirPath) == QFileInfo(qtCoreDirPath)) {
// QtCore DLL is next to the executable. This is either a windeployqt'ed executable or an
// 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::fromLatin1(
qt_configure_strs + qt_configure_str_offsets[QLibraryInfo::LibrariesPath - 1]);
const QLatin1Char slash('/');
const QString qtCoreImpLibPath
= qtCoreDirPath
+ slash + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH)
+ slash + libdir
+ slash + QFileInfo(qtCoreFilePath).completeBaseName() + QLatin1String(".lib");
if (!QFileInfo::exists(qtCoreImpLibPath)) {
// We did not find a corresponding import library and conclude that this is a
// windeployqt'ed executable.
return exeDirPath;
}
}
if (!qtCoreFilePath.isEmpty())
prefixPath = prefixFromQtCoreLibraryHelper(qtCoreFilePath);
#else
#error "The chosen platform / config does not support querying for a dynamic prefix."
#endif