From dfda6f14b3e210a33b71ef1c6fa3c75a9c866cce Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Wed, 21 Jun 2017 13:21:05 +0200
Subject: [PATCH] windeployqt: Deploy MSVC2017 redistributable files

Factor out a function looking for the files.

Task-number: QTBUG-61549
Change-Id: If6938d67d479e85655937465670bb72b50a44650
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
---
 src/windeployqt/main.cpp | 71 +++++++++++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 23 deletions(-)

diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp
index 6d1bad9de..67577c5f2 100644
--- a/src/windeployqt/main.cpp
+++ b/src/windeployqt/main.cpp
@@ -1017,6 +1017,42 @@ static QString libraryPath(const QString &libraryLocation, const char *name,
     return result;
 }
 
+static QString vcDebugRedistDir() { return QStringLiteral("Debug_NonRedist"); }
+
+static QString vcRedistDir()
+{
+    const char vcDirVar[] = "VCINSTALLDIR";
+    const QChar slash(QLatin1Char('/'));
+    QString vcRedistDirName = QDir::cleanPath(QFile::decodeName(qgetenv(vcDirVar)));
+    if (vcRedistDirName.isEmpty()) {
+        std::wcerr << "Warning: Cannot find Visual Studio installation directory, " << vcDirVar
+            << " is not set.\n";
+        return QString();
+    }
+    if (!vcRedistDirName.endsWith(slash))
+        vcRedistDirName.append(slash);
+    vcRedistDirName.append(QStringLiteral("redist"));
+    if (!QFileInfo(vcRedistDirName).isDir()) {
+        std::wcerr << "Warning: Cannot find Visual Studio redist directory, "
+            << QDir::toNativeSeparators(vcRedistDirName).toStdWString() << ".\n";
+        return QString();
+    }
+    const QString vc2017RedistDirName = vcRedistDirName + QStringLiteral("/MSVC");
+    if (!QFileInfo(vc2017RedistDirName).isDir())
+        return vcRedistDirName; // pre 2017
+    // Look in reverse order for folder containing the debug redist folder
+    const QFileInfoList subDirs =
+        QDir(vc2017RedistDirName).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
+    for (const QFileInfo &f : subDirs) {
+        const QString path = f.absoluteFilePath();
+        if (QFileInfo(path + slash + vcDebugRedistDir()).isDir())
+            return path;
+    }
+    std::wcerr << "Warning: Cannot find Visual Studio redist directory under "
+        << QDir::toNativeSeparators(vc2017RedistDirName).toStdWString() << ".\n";
+    return QString();
+}
+
 static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned wordSize)
 {
     QStringList result;
@@ -1040,27 +1076,15 @@ static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned
     }
         break;
     case Windows: { // MSVC/Desktop: Add redistributable packages.
-        const char vcDirVar[] = "VCINSTALLDIR";
-        const QChar slash(QLatin1Char('/'));
-        QString vcRedistDirName = QDir::cleanPath(QFile::decodeName(qgetenv(vcDirVar)));
-        if (vcRedistDirName.isEmpty()) {
-             std::wcerr << "Warning: Cannot find Visual Studio installation directory, " << vcDirVar << " is not set.\n";
+        QString vcRedistDirName = vcRedistDir();
+        if (vcRedistDirName.isEmpty())
              break;
-        }
-        if (!vcRedistDirName.endsWith(slash))
-            vcRedistDirName.append(slash);
-        vcRedistDirName.append(QStringLiteral("redist"));
-        QDir vcRedistDir(vcRedistDirName);
-        if (!vcRedistDir.exists()) {
-            std::wcerr << "Warning: Cannot find Visual Studio redist directory, "
-                       << QDir::toNativeSeparators(vcRedistDirName).toStdWString() << ".\n";
-            break;
-        }
         QStringList redistFiles;
+        QDir vcRedistDir(vcRedistDirName);
         const QString wordSizeString(QLatin1String(wordSize > 32 ? "x64" : "x86"));
         if (isDebug) {
             // Append DLLs from Debug_NonRedist\x??\Microsoft.VC<version>.DebugCRT.
-            if (vcRedistDir.cd(QLatin1String("Debug_NonRedist")) && vcRedistDir.cd(wordSizeString)) {
+            if (vcRedistDir.cd(vcDebugRedistDir()) && vcRedistDir.cd(wordSizeString)) {
                 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")));
@@ -1069,14 +1093,15 @@ static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned
                 }
             }
         } else { // release: Bundle vcredist<>.exe
+            QString releaseRedistDir = vcRedistDirName;
             const QStringList countryCodes = vcRedistDir.entryList(QStringList(QStringLiteral("[0-9]*")), QDir::Dirs);
-            if (!countryCodes.isEmpty()) {
-                const QFileInfo fi(vcRedistDirName + slash + countryCodes.first() + slash
-                                   + QStringLiteral("vcredist_") + wordSizeString
-                                   + QStringLiteral(".exe"));
-                if (fi.isFile())
-                    redistFiles.append(fi.absoluteFilePath());
-            }
+            if (!countryCodes.isEmpty()) // Pre MSVC2017
+                releaseRedistDir += QLatin1Char('/') + countryCodes.constFirst();
+            const QFileInfo fi(releaseRedistDir + QLatin1Char('/')
+                               + QStringLiteral("vcredist_") + wordSizeString
+                               + QStringLiteral(".exe"));
+            if (fi.isFile())
+                redistFiles.append(fi.absoluteFilePath());
         }
         if (redistFiles.isEmpty()) {
             std::wcerr << "Warning: Cannot find Visual Studio " << (isDebug ? "debug" : "release")
-- 
GitLab