diff --git a/src/tools/windeployqt/main.cpp b/src/tools/windeployqt/main.cpp index adea965810..2db166d54e 100644 --- a/src/tools/windeployqt/main.cpp +++ b/src/tools/windeployqt/main.cpp @@ -162,6 +162,7 @@ struct Options { bool quickImports = true; bool translations = true; bool systemD3dCompiler = true; + bool systemDxc = true; bool compilerRunTime = false; QStringList disabledPluginTypes; bool softwareRasterizer = true; @@ -416,6 +417,10 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse QStringLiteral("Skip deployment of the system D3D compiler.")); parser->addOption(noSystemD3DCompilerOption); + QCommandLineOption noSystemDxcOption(QStringLiteral("no-system-dxc-compiler"), + QStringLiteral("Skip deployment of the system DXC (dxcompiler.dll, dxil.dll).")); + parser->addOption(noSystemDxcOption); + QCommandLineOption compilerRunTimeOption(QStringLiteral("compiler-runtime"), QStringLiteral("Deploy compiler runtime (Desktop only).")); @@ -489,6 +494,7 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse if (parser->isSet(translationOption)) options->languages = parser->value(translationOption).split(u','); options->systemD3dCompiler = !parser->isSet(noSystemD3DCompilerOption); + options->systemDxc = !parser->isSet(noSystemDxcOption); options->quickImports = !parser->isSet(noQuickImportOption); // default to deployment of compiler runtime for windows desktop configurations @@ -1448,6 +1454,13 @@ static DeployResult deploy(const Options &options, const QMap deployedQtLibraries.push_back(d3dCompiler); } } + if (options.systemDxc) { + const QStringList dxcLibs = findDxc(options.platform, qtBinDir, wordSize); + if (!dxcLibs.isEmpty()) + deployedQtLibraries.append(dxcLibs); + else + std::wcerr << "Warning: Cannot find any version of the dxcompiler.dll and dxil.dll.\n"; + } } // Windows // Update libraries diff --git a/src/tools/windeployqt/utils.cpp b/src/tools/windeployqt/utils.cpp index cf3356b007..09e820abef 100644 --- a/src/tools/windeployqt/utils.cpp +++ b/src/tools/windeployqt/utils.cpp @@ -896,6 +896,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 +957,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=." diff --git a/src/tools/windeployqt/utils.h b/src/tools/windeployqt/utils.h index 5bf2cde111..71f964d034 100644 --- a/src/tools/windeployqt/utils.h +++ b/src/tools/windeployqt/utils.h @@ -201,6 +201,7 @@ inline QStringList findDependentLibraries(const QString &executableFileName, Pla } QString findD3dCompiler(Platform platform, const QString &qtBinDir, unsigned wordSize); +QStringList findDxc(Platform platform, const QString &qtBinDir, unsigned wordSize); bool patchQtCore(const QString &path, QString *errorMessage);