diff options
author | Thomas Miller <thomaslmiller91@gmail.com> | 2018-11-08 14:23:09 -0800 |
---|---|---|
committer | Thomas Miller <thomaslmiller91@gmail.com> | 2018-12-07 20:18:45 +0000 |
commit | bb35a2d244accde7908ddaaa17571b971eb564f0 (patch) | |
tree | d99c5d130482e5d9a5f61f82470eb2c4c00ce8c4 | |
parent | c52ac7fa312ffbe5d9dd9d388395061d5d2ea81e (diff) | |
download | qttools-bb35a2d244accde7908ddaaa17571b971eb564f0.tar.gz |
Enable Windeployqt to package arm64 desktop apps
Change-Id: I8ef5ca54488e3e5cd89bd5a6e7be4958c74fe60d
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | src/shared/winutils/utils.cpp | 26 | ||||
-rw-r--r-- | src/shared/winutils/utils.h | 13 | ||||
-rw-r--r-- | src/windeployqt/main.cpp | 28 |
3 files changed, 50 insertions, 17 deletions
diff --git a/src/shared/winutils/utils.cpp b/src/shared/winutils/utils.cpp index cdf017715..195d8efd5 100644 --- a/src/shared/winutils/utils.cpp +++ b/src/shared/winutils/utils.cpp @@ -840,7 +840,7 @@ inline void determineDebugAndDependentLibs(const ImageNtHeader *nth, const void // and debug flags. bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage, QStringList *dependentLibrariesIn, unsigned *wordSizeIn, - bool *isDebugIn, bool isMinGW) + bool *isDebugIn, bool isMinGW, unsigned short *machineArchIn) { bool result = false; HANDLE hFile = NULL; @@ -890,6 +890,9 @@ bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage fileMemory, isMinGW, dependentLibrariesIn, isDebugIn, errorMessage); } + if (machineArchIn) + *machineArchIn = ntHeaders->FileHeader.Machine; + result = true; if (optVerboseLevel > 1) { std::wcout << __FUNCTION__ << ": " << QDir::toNativeSeparators(peExecutableFileName) @@ -970,7 +973,7 @@ QString findD3dCompiler(Platform platform, const QString &qtBinDir, unsigned wor #else // Q_OS_WIN bool readPeExecutable(const QString &, QString *errorMessage, - QStringList *, unsigned *, bool *, bool) + QStringList *, unsigned *, bool *, bool, unsigned short *) { *errorMessage = QStringLiteral("Not implemented."); return false; @@ -1032,4 +1035,23 @@ bool patchQtCore(const QString &path, QString *errorMessage) return true; } +#ifdef Q_OS_WIN +QString getArchString(unsigned short machineArch) +{ + switch (machineArch) { + case IMAGE_FILE_MACHINE_I386: + return QStringLiteral("x86"); + case IMAGE_FILE_MACHINE_ARM: + return QStringLiteral("arm"); + case IMAGE_FILE_MACHINE_AMD64: + return QStringLiteral("x64"); + case IMAGE_FILE_MACHINE_ARM64: + return QStringLiteral("arm64"); + default: + break; + } + return QString(); +} +#endif // Q_OS_WIN + QT_END_NAMESPACE diff --git a/src/shared/winutils/utils.h b/src/shared/winutils/utils.h index a5e6f01f7..4cede6b55 100644 --- a/src/shared/winutils/utils.h +++ b/src/shared/winutils/utils.h @@ -185,21 +185,28 @@ bool runElevatedBackgroundProcess(const QString &binary, const QStringList &args bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage, QStringList *dependentLibraries = 0, unsigned *wordSize = 0, - bool *isDebug = 0, bool isMinGW = false); + bool *isDebug = 0, bool isMinGW = false, unsigned short *machineArch = nullptr); bool readElfExecutable(const QString &elfExecutableFileName, QString *errorMessage, QStringList *dependentLibraries = 0, unsigned *wordSize = 0, bool *isDebug = 0); inline bool readExecutable(const QString &executableFileName, Platform platform, QString *errorMessage, QStringList *dependentLibraries = 0, - unsigned *wordSize = 0, bool *isDebug = 0) + unsigned *wordSize = 0, bool *isDebug = 0, unsigned short *machineArch = nullptr) { return platform == Unix ? readElfExecutable(executableFileName, errorMessage, dependentLibraries, wordSize, isDebug) : readPeExecutable(executableFileName, errorMessage, dependentLibraries, wordSize, isDebug, - (platform == WindowsDesktopMinGW)); + (platform == WindowsDesktopMinGW), machineArch); } +#ifdef Q_OS_WIN +# if !defined(IMAGE_FILE_MACHINE_ARM64) +# define IMAGE_FILE_MACHINE_ARM64 0xAA64 +# endif +QString getArchString (unsigned short machineArch); +#endif // Q_OS_WIN + // Return dependent modules of executable files. inline QStringList findDependentLibraries(const QString &executableFileName, Platform platform, QString *errorMessage) diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp index 4d5586148..e9823bb16 100644 --- a/src/windeployqt/main.cpp +++ b/src/windeployqt/main.cpp @@ -40,6 +40,7 @@ #include <QtCore/QOperatingSystemVersion> #include <QtCore/QSharedPointer> #include <QtCore/QVector> +#include <QtCore/qt_windows.h> #include <algorithm> #include <iostream> @@ -680,13 +681,13 @@ static inline bool isQtModule(const QString &libName) // Helper for recursively finding all dependent Qt libraries. static bool findDependentQtLibraries(const QString &qtBinDir, const QString &binary, Platform platform, QString *errorMessage, QStringList *result, - unsigned *wordSize = 0, bool *isDebug = 0, + unsigned *wordSize = 0, bool *isDebug = 0, unsigned short *machineArch = 0, int *directDependencyCount = 0, int recursionDepth = 0) { QStringList dependentLibs; if (directDependencyCount) *directDependencyCount = 0; - if (!readExecutable(binary, platform, errorMessage, &dependentLibs, wordSize, isDebug)) { + if (!readExecutable(binary, platform, errorMessage, &dependentLibs, wordSize, isDebug, machineArch)) { errorMessage->prepend(QLatin1String("Unable to find dependent libraries of ") + QDir::toNativeSeparators(binary) + QLatin1String(" :")); return false; @@ -706,7 +707,7 @@ static bool findDependentQtLibraries(const QString &qtBinDir, const QString &bin *directDependencyCount = end - start; // Recurse for (int i = start; i < end; ++i) - if (!findDependentQtLibraries(qtBinDir, result->at(i), platform, errorMessage, result, 0, 0, 0, recursionDepth + 1)) + if (!findDependentQtLibraries(qtBinDir, result->at(i), platform, errorMessage, result, 0, 0, 0, 0, recursionDepth + 1)) return false; return true; } @@ -1039,6 +1040,7 @@ static QString libraryPath(const QString &libraryLocation, const char *name, } static QString vcDebugRedistDir() { return QStringLiteral("Debug_NonRedist"); } +static QString onecoreRedistDir() { return QStringLiteral("onecore"); } static QString vcRedistDir() { @@ -1080,7 +1082,7 @@ static QString vcRedistDir() return QString(); } -static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned wordSize) +static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned short machineArch) { QStringList result; switch (platform) { @@ -1108,10 +1110,10 @@ static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned break; QStringList redistFiles; QDir vcRedistDir(vcRedistDirName); - const QString wordSizeString(QLatin1String(wordSize > 32 ? "x64" : "x86")); + const QString machineArchString = getArchString(machineArch); if (isDebug) { // Append DLLs from Debug_NonRedist\x??\Microsoft.VC<version>.DebugCRT. - if (vcRedistDir.cd(vcDebugRedistDir()) && vcRedistDir.cd(wordSizeString)) { + if (vcRedistDir.cd(vcDebugRedistDir()) && vcRedistDir.cd(machineArchString)) { const QStringList names = vcRedistDir.entryList(QStringList(QStringLiteral("Microsoft.VC*.DebugCRT")), QDir::Dirs); if (!names.isEmpty() && vcRedistDir.cd(names.first())) { const QFileInfoList &dlls = vcRedistDir.entryInfoList(QStringList(QLatin1String("*.dll"))); @@ -1125,10 +1127,10 @@ static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned if (!countryCodes.isEmpty()) // Pre MSVC2017 releaseRedistDir += QLatin1Char('/') + countryCodes.constFirst(); QFileInfo fi(releaseRedistDir + QLatin1Char('/') + QStringLiteral("vc_redist.") - + wordSizeString + QStringLiteral(".exe")); + + machineArchString + QStringLiteral(".exe")); if (!fi.isFile()) { // Pre MSVC2017/15.5 fi.setFile(releaseRedistDir + QLatin1Char('/') + QStringLiteral("vcredist_") - + wordSizeString + QStringLiteral(".exe")); + + machineArchString + QStringLiteral(".exe")); } if (fi.isFile()) redistFiles.append(fi.absoluteFilePath()); @@ -1201,9 +1203,10 @@ static DeployResult deploy(const Options &options, QStringList dependentQtLibs; bool detectedDebug; unsigned wordSize; + unsigned short machineArch; int directDependencyCount = 0; if (!findDependentQtLibraries(libraryLocation, options.binaries.first(), options.platform, errorMessage, &dependentQtLibs, &wordSize, - &detectedDebug, &directDependencyCount)) { + &detectedDebug, &machineArch, &directDependencyCount)) { return result; } for (int b = 1; b < options.binaries.size(); ++b) { @@ -1298,7 +1301,7 @@ static DeployResult deploy(const Options &options, qmlScanResult.append(scanResult); // Additional dependencies of QML plugins. for (const QString &plugin : qAsConst(qmlScanResult.plugins)) { - if (!findDependentQtLibraries(libraryLocation, plugin, options.platform, errorMessage, &dependentQtLibs, &wordSize, &detectedDebug)) + if (!findDependentQtLibraries(libraryLocation, plugin, options.platform, errorMessage, &dependentQtLibs, &wordSize, &detectedDebug, &machineArch)) return result; } if (optVerboseLevel >= 1) { @@ -1392,7 +1395,8 @@ static DeployResult deploy(const Options &options, deployedQtLibraries.append(libEglFullPath); } // Find the system D3d Compiler matching the D3D library. - if (options.systemD3dCompiler && !options.isWinRt()) { + // Any arm64 OS will be new enough to be shipped with the D3DCompiler inbox. + if (options.systemD3dCompiler && !options.isWinRt() && machineArch != IMAGE_FILE_MACHINE_ARM64) { const QString d3dCompiler = findD3dCompiler(options.platform, qtBinDir, wordSize); if (d3dCompiler.isEmpty()) { std::wcerr << "Warning: Cannot find any version of the d3dcompiler DLL.\n"; @@ -1441,7 +1445,7 @@ static DeployResult deploy(const Options &options, options.directory : options.libraryDirectory; QStringList libraries = deployedQtLibraries; if (options.compilerRunTime) - libraries.append(compilerRunTimeLibs(options.platform, isDebug, wordSize)); + libraries.append(compilerRunTimeLibs(options.platform, isDebug, machineArch)); for (const QString &qtLib : qAsConst(libraries)) { if (!updateLibrary(qtLib, targetPath, options, errorMessage)) return result; |