diff options
Diffstat (limited to 'src/tools/windeployqt/utils.cpp')
-rw-r--r-- | src/tools/windeployqt/utils.cpp | 112 |
1 files changed, 73 insertions, 39 deletions
diff --git a/src/tools/windeployqt/utils.cpp b/src/tools/windeployqt/utils.cpp index cf3356b007..5141119254 100644 --- a/src/tools/windeployqt/utils.cpp +++ b/src/tools/windeployqt/utils.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "utils.h" -#include "elfreader.h" #include <QtCore/QString> #include <QtCore/QDebug> @@ -95,7 +94,7 @@ QStringList findSharedLibraries(const QDir &directory, Platform platform, nameFilter += u'*'; if (debugMatchMode == MatchDebug && platformHasDebugSuffix(platform)) nameFilter += u'd'; - nameFilter += sharedLibrarySuffix(platform); + nameFilter += sharedLibrarySuffix(); QStringList result; QString errorMessage; const QFileInfoList &dlls = directory.entryInfoList(QStringList(nameFilter), QDir::Files); @@ -424,14 +423,18 @@ const char *qmakeInfixKey = "QT_INFIX"; QMap<QString, QString> queryQtPaths(const QString &qtpathsBinary, QString *errorMessage) { const QString binary = !qtpathsBinary.isEmpty() ? qtpathsBinary : QStringLiteral("qtpaths"); + const QString colonSpace = QStringLiteral(": "); QByteArray stdOut; QByteArray stdErr; unsigned long exitCode = 0; - if (!runProcess(binary, QStringList(QStringLiteral("-query")), QString(), &exitCode, &stdOut, &stdErr, errorMessage)) + if (!runProcess(binary, QStringList(QStringLiteral("-query")), QString(), &exitCode, &stdOut, + &stdErr, errorMessage)) { + *errorMessage = QStringLiteral("Error running binary ") + binary + colonSpace + *errorMessage; return QMap<QString, QString>(); + } if (exitCode) { *errorMessage = binary + QStringLiteral(" returns ") + QString::number(exitCode) - + QStringLiteral(": ") + QString::fromLocal8Bit(stdErr); + + colonSpace + QString::fromLocal8Bit(stdErr); return QMap<QString, QString>(); } const QString output = QString::fromLocal8Bit(stdOut).trimmed().remove(u'\r'); @@ -467,7 +470,7 @@ QMap<QString, QString> queryQtPaths(const QString &qtpathsBinary, QString *error } } else { std::wcerr << "Warning: Unable to read " << QDir::toNativeSeparators(qconfigPriFile.fileName()) - << ": " << qconfigPriFile.errorString()<< '\n'; + << colonSpace << qconfigPriFile.errorString()<< '\n'; } return result; } @@ -553,37 +556,6 @@ bool updateFile(const QString &sourceFileName, const QStringList &nameFilters, return true; } -bool readElfExecutable(const QString &elfExecutableFileName, QString *errorMessage, - QStringList *dependentLibraries, unsigned *wordSize, - bool *isDebug) -{ - ElfReader elfReader(elfExecutableFileName); - const ElfData data = elfReader.readHeaders(); - if (data.sectionHeaders.isEmpty()) { - *errorMessage = QStringLiteral("Unable to read ELF binary \"") - + QDir::toNativeSeparators(elfExecutableFileName) + QStringLiteral("\": ") - + elfReader.errorString(); - return false; - } - if (wordSize) - *wordSize = data.elfclass == Elf_ELFCLASS64 ? 64 : 32; - if (dependentLibraries) { - dependentLibraries->clear(); - const QList<QByteArray> libs = elfReader.dependencies(); - if (libs.isEmpty()) { - *errorMessage = QStringLiteral("Unable to read dependenices of ELF binary \"") - + QDir::toNativeSeparators(elfExecutableFileName) + QStringLiteral("\": ") - + elfReader.errorString(); - return false; - } - for (const QByteArray &l : libs) - dependentLibraries->push_back(QString::fromLocal8Bit(l)); - } - if (isDebug) - *isDebug = data.symbolsType != UnknownSymbols && data.symbolsType != NoSymbols; - return true; -} - #ifdef Q_OS_WIN static inline QString stringFromRvaPtr(const void *rvaPtr) @@ -705,13 +677,23 @@ static inline MsvcDebugRuntimeResult checkMsvcDebugRuntime(const QStringList &de qsizetype pos = 0; if (lib.startsWith("MSVCR"_L1, Qt::CaseInsensitive) || lib.startsWith("MSVCP"_L1, Qt::CaseInsensitive) - || lib.startsWith("VCRUNTIME"_L1, Qt::CaseInsensitive)) { + || lib.startsWith("VCRUNTIME"_L1, Qt::CaseInsensitive) + || lib.startsWith("VCCORLIB"_L1, Qt::CaseInsensitive) + || lib.startsWith("CONCRT"_L1, Qt::CaseInsensitive) + || lib.startsWith("UCRTBASE"_L1, Qt::CaseInsensitive)) { qsizetype lastDotPos = lib.lastIndexOf(u'.'); pos = -1 == lastDotPos ? 0 : lastDotPos - 1; } - if (pos > 0 && lib.contains("_app"_L1, Qt::CaseInsensitive)) - pos -= 4; + if (pos > 0) { + const auto removeExtraSuffix = [&lib, &pos](const QString &suffix) -> void { + if (lib.contains(suffix, Qt::CaseInsensitive)) + pos -= suffix.size(); + }; + removeExtraSuffix("_app"_L1); + removeExtraSuffix("_atomic_wait"_L1); + removeExtraSuffix("_codecvt_ids"_L1); + } if (pos) return lib.at(pos).toLower() == u'd' ? MsvcDebugRuntime : MsvcReleaseRuntime; @@ -896,6 +878,53 @@ QString findD3dCompiler(Platform platform, const QString &qtBinDir, unsigned wor return QString(); } +QStringList findDxc(Platform platform, const QString &qtBinDir, unsigned wordSize) +{ + QStringList results; + const QString kitDir = QString::fromLocal8Bit(qgetenv("WindowsSdkDir")); + const QString suffix = QLatin1StringView(windowsSharedLibrarySuffix); + for (QString prefix : { QStringLiteral("dxcompiler"), QStringLiteral("dxil") }) { + QString name = prefix + suffix; + if (!kitDir.isEmpty()) { + QString redistDirPath = QDir::cleanPath(kitDir) + QStringLiteral("/Redist/D3D/"); + if (platform.testFlag(ArmBased)) { + redistDirPath += wordSize == 32 ? QStringLiteral("arm") : QStringLiteral("arm64"); + } else { + redistDirPath += wordSize == 32 ? QStringLiteral("x86") : QStringLiteral("x64"); + } + QDir redistDir(redistDirPath); + if (redistDir.exists()) { + const QFileInfoList files = redistDir.entryInfoList(QStringList(prefix + u'*' + suffix), QDir::Files); + if (!files.isEmpty()) { + results.append(files.front().absoluteFilePath()); + continue; + } + } + } + // Check the bin directory of the Qt SDK (in case it is shadowed by the + // Windows system directory in PATH). + const QFileInfo fi(qtBinDir + u'/' + name); + if (fi.isFile()) { + results.append(fi.absoluteFilePath()); + continue; + } + // Try to find it in the PATH (e.g. the Vulkan SDK ships these, even if Windows itself doesn't). + if (platform.testFlag(IntelBased)) { + QString errorMessage; + unsigned detectedWordSize; + const QString dll = findInPath(name); + if (!dll.isEmpty() + && readPeExecutable(dll, &errorMessage, 0, &detectedWordSize, 0) + && detectedWordSize == wordSize) + { + results.append(dll); + continue; + } + } + } + return results; +} + #else // Q_OS_WIN bool readPeExecutable(const QString &, QString *errorMessage, @@ -910,6 +939,11 @@ QString findD3dCompiler(Platform, const QString &, unsigned) return QString(); } +QStringList findDxc(Platform, const QString &, unsigned) +{ + return QStringList(); +} + #endif // !Q_OS_WIN // Search for "qt_prfxpath=xxxx" in \a path, and replace it with "qt_prfxpath=." |