From d66fe82e645fc42c00c3aef720b22691443764c1 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 29 Nov 2016 15:42:34 +0100 Subject: Add VS 2017 support Task-number: QBS-1025 Change-Id: Ib08373b6b45fa0b728e68466d08d43a14f864d72 Reviewed-by: Christian Kandeler --- src/app/qbs-setup-qt/setupqt.cpp | 2 + src/app/qbs-setup-toolchains/msvcprobe.cpp | 137 ++++++++++++++++------ src/lib/corelib/tools/msvcinfo.h | 2 + src/lib/corelib/tools/visualstudioversioninfo.cpp | 2 + src/lib/corelib/tools/vsenvironmentdetector.cpp | 30 ++++- src/lib/corelib/tools/vsenvironmentdetector.h | 1 + 6 files changed, 132 insertions(+), 42 deletions(-) diff --git a/src/app/qbs-setup-qt/setupqt.cpp b/src/app/qbs-setup-qt/setupqt.cpp index 25dd233be..b9531566a 100644 --- a/src/app/qbs-setup-qt/setupqt.cpp +++ b/src/app/qbs-setup-qt/setupqt.cpp @@ -427,6 +427,8 @@ static Version msvcCompilerVersionForYear(int year) return Version(18); case 2015: return Version(19); + case 2017: + return Version(19, 1); default: return Version(); } diff --git a/src/app/qbs-setup-toolchains/msvcprobe.cpp b/src/app/qbs-setup-toolchains/msvcprobe.cpp index e956b20bc..bb1838f2b 100644 --- a/src/app/qbs-setup-toolchains/msvcprobe.cpp +++ b/src/app/qbs-setup-toolchains/msvcprobe.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -91,9 +92,17 @@ static void addMSVCPlatform(Settings *settings, QList &profiles, QStrin profiles << p; } -static QStringList findSupportedArchitectures(MSVC *msvc) +struct MSVCArchInfo { - static const QStringList knownArchitectures = QStringList() + QString arch; + QString binPath; +}; + +static QVector findSupportedArchitectures(const MSVC &msvc) +{ + QVector result; + if (msvc.internalVsVersion.majorVersion() < 15) { + static const QStringList knownArchitectures = QStringList() << QStringLiteral("x86") << QStringLiteral("amd64_x86") << QStringLiteral("amd64") @@ -102,10 +111,30 @@ static QStringList findSupportedArchitectures(MSVC *msvc) << QStringLiteral("x86_ia64") << QStringLiteral("x86_arm") << QStringLiteral("amd64_arm"); - QStringList result; - for (const QString &knownArchitecture : knownArchitectures) { - if (QFile::exists(msvc->clPathForArchitecture(knownArchitecture))) - result += knownArchitecture; + for (const QString &knownArchitecture : knownArchitectures) { + MSVCArchInfo ai; + ai.arch = knownArchitecture; + ai.binPath = msvc.binPathForArchitecture(knownArchitecture); + if (QFile::exists(ai.binPath + QLatin1String("/cl.exe"))) + result += ai; + } + } else { + QDir vcInstallDir(msvc.vcInstallPath); + foreach (QString hostArch, vcInstallDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + QDir subdir = vcInstallDir; + if (!subdir.cd(hostArch)) + continue; + const QString shortHostArch = hostArch.mid(4).toLower(); + foreach (const QString &arch, subdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + MSVCArchInfo ai; + ai.binPath = subdir.absoluteFilePath(arch); + if (shortHostArch == arch) + ai.arch = arch; + else + ai.arch = shortHostArch + QLatin1Char('_') + arch; + result += ai; + } + } } return result; } @@ -119,6 +148,58 @@ static QString wow6432Key() #endif } +static QVector installedMSVCs() +{ + QVector msvcs; + const QSettings vsRegistry( + QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE") + wow6432Key() + + QLatin1String("\\Microsoft\\VisualStudio\\SxS\\VS7"), + QSettings::NativeFormat); + foreach (const QString &vsName, vsRegistry.childKeys()) { + MSVC msvc; + msvc.internalVsVersion = Version::fromString(vsName); + if (!msvc.internalVsVersion.isValid()) + continue; + + QDir vsInstallDir(vsRegistry.value(vsName).toString()); + msvc.vsInstallPath = vsInstallDir.absolutePath(); + if (!vsInstallDir.cd(QStringLiteral("VC"))) + continue; + + msvc.version = QString::number(Internal::VisualStudioVersionInfo( + Internal::Version::fromString(vsName)).marketingVersion()); + if (msvc.version.isEmpty()) { + qbsWarning() << Tr::tr("Unknown MSVC version %1 found.").arg(vsName); + continue; + } + + if (msvc.internalVsVersion.majorVersion() < 15) { + QDir vcInstallDir = vsInstallDir; + if (!vcInstallDir.cd(QStringLiteral("bin"))) + continue; + msvc.vcInstallPath = vcInstallDir.absolutePath(); + msvcs.append(msvc); + } else { + QDir vcInstallDir = vsInstallDir; + vcInstallDir.cd(QStringLiteral("Tools/MSVC")); + foreach (const QString &vcVersionStr, + vcInstallDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + const Version vcVersion = Version::fromString(vcVersionStr); + if (!vcVersion.isValid()) + continue; + QDir specificVcInstallDir = vcInstallDir; + if (!specificVcInstallDir.cd(vcVersionStr) + || !specificVcInstallDir.cd(QStringLiteral("bin"))) { + continue; + } + msvc.vcInstallPath = specificVcInstallDir.absolutePath(); + msvcs.append(msvc); + } + } + } + return msvcs; +} + void msvcProbe(Settings *settings, QList &profiles) { qbsInfo() << Tr::tr("Detecting MSVC toolchains..."); @@ -143,10 +224,10 @@ void msvcProbe(Settings *settings, QList &profiles) sdk.vcInstallPath.chop(1); if (sdk.isDefault) defaultWinSDK = sdk; - foreach (const QString &arch, findSupportedArchitectures(&sdk)) { + foreach (const MSVCArchInfo &ai, findSupportedArchitectures(sdk)) { WinSDK specificSDK = sdk; - specificSDK.architecture = arch; - specificSDK.binPath = specificSDK.binPathForArchitecture(arch); + specificSDK.architecture = ai.arch; + specificSDK.binPath = ai.binPath; winSDKs += specificSDK; } } @@ -161,38 +242,18 @@ void msvcProbe(Settings *settings, QList &profiles) // 2) Installed MSVCs QVector msvcs; - const QSettings vsRegistry( - QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE") + wow6432Key() - + QLatin1String("\\Microsoft\\VisualStudio\\SxS\\VC7"), - QSettings::NativeFormat); - foreach (const QString &vsName, vsRegistry.allKeys()) { - // Scan for version major.minor - const int dotPos = vsName.indexOf(QLatin1Char('.')); - if (dotPos == -1) - continue; - - MSVC msvc; - msvc.vcInstallPath = vsRegistry.value(vsName).toString(); - if (!msvc.vcInstallPath.endsWith(QLatin1Char('\\'))) - msvc.vcInstallPath += QLatin1Char('\\'); - msvc.vcInstallPath += QLatin1String("bin"); - - msvc.version = QString::number(Internal::VisualStudioVersionInfo( - Internal::Version::fromString(vsName)).marketingVersion()); - if (msvc.version.isEmpty()) { - qbsWarning() << Tr::tr("Unknown MSVC version %1 found.").arg(vsName); - continue; + foreach (MSVC msvc, installedMSVCs()) { + if (msvc.internalVsVersion.majorVersion() < 15) { + // Check existence of various install scripts + const QString vcvars32bat = msvc.vcInstallPath + QLatin1String("/vcvars32.bat"); + if (!QFileInfo(vcvars32bat).isFile()) + continue; } - // Check existence of various install scripts - const QString vcvars32bat = msvc.vcInstallPath + QLatin1String("/vcvars32.bat"); - if (!QFileInfo(vcvars32bat).isFile()) - continue; - - foreach (const QString &arch, findSupportedArchitectures(&msvc)) { + foreach (const MSVCArchInfo &ai, findSupportedArchitectures(msvc)) { MSVC specificMSVC = msvc; - specificMSVC.architecture = arch; - specificMSVC.binPath = specificMSVC.binPathForArchitecture(arch); + specificMSVC.architecture = ai.arch; + specificMSVC.binPath = ai.binPath; msvcs += specificMSVC; } } diff --git a/src/lib/corelib/tools/msvcinfo.h b/src/lib/corelib/tools/msvcinfo.h index be64bf9cb..61c70fc4a 100644 --- a/src/lib/corelib/tools/msvcinfo.h +++ b/src/lib/corelib/tools/msvcinfo.h @@ -61,7 +61,9 @@ class MSVC { public: QString version; + Version internalVsVersion; Version compilerVersion; + QString vsInstallPath; QString vcInstallPath; QString binPath; QString pathPrefix; diff --git a/src/lib/corelib/tools/visualstudioversioninfo.cpp b/src/lib/corelib/tools/visualstudioversioninfo.cpp index 09c8d5d27..1022c250b 100644 --- a/src/lib/corelib/tools/visualstudioversioninfo.cpp +++ b/src/lib/corelib/tools/visualstudioversioninfo.cpp @@ -118,6 +118,8 @@ int VisualStudioVersionInfo::marketingVersion() const return 2013; case 14: return 2015; + case 15: + return 2017; default: qWarning() << QStringLiteral("unrecognized Visual Studio version: ") << m_version.toString(); diff --git a/src/lib/corelib/tools/vsenvironmentdetector.cpp b/src/lib/corelib/tools/vsenvironmentdetector.cpp index c4db89fec..291c150c9 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.cpp +++ b/src/lib/corelib/tools/vsenvironmentdetector.cpp @@ -98,12 +98,34 @@ bool VsEnvironmentDetector::start(QVector msvcs) return true; } +QString VsEnvironmentDetector::findVcVarsAllBat(const MSVC &msvc) const +{ + // ### We can only rely on MSVC.vcInstallPath being set + // when this is called from utilitiesextension.cpp :-( + // If we knew the vsInstallPath at this point we could just use that + // instead of searching for vcvarsall.bat candidates. + QDir dir(msvc.vcInstallPath); + for (;;) { + if (!dir.cdUp()) + return QString(); + if (dir.dirName() == QLatin1String("VC")) + break; + } + const QString vcvarsallbat = QStringLiteral("vcvarsall.bat"); + QString path = vcvarsallbat; + if (dir.exists(path)) + return dir.absoluteFilePath(path); + path = QLatin1String("Auxiliary/Build/") + vcvarsallbat; + if (dir.exists(path)) + return dir.absoluteFilePath(path); + return QString(); +} + bool VsEnvironmentDetector::startDetection(const QVector &compatibleMSVCs) { - const QString vcvarsallbat = QDir::cleanPath(compatibleMSVCs.first()->vcInstallPath - + QLatin1String("/../vcvarsall.bat")); - if (!QFile::exists(vcvarsallbat)) { - m_errorString = Tr::tr("Cannot find '%1'.").arg(QDir::toNativeSeparators(vcvarsallbat)); + const QString vcvarsallbat = findVcVarsAllBat(*compatibleMSVCs.first()); + if (vcvarsallbat.isEmpty()) { + m_errorString = Tr::tr("Cannot find 'vcvarsall.bat'."); return false; } diff --git a/src/lib/corelib/tools/vsenvironmentdetector.h b/src/lib/corelib/tools/vsenvironmentdetector.h index 114f792ee..bf715b28c 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.h +++ b/src/lib/corelib/tools/vsenvironmentdetector.h @@ -64,6 +64,7 @@ public: QString errorString() const { return m_errorString; } private: + QString findVcVarsAllBat(const MSVC &msvc) const; bool startDetection(const QVector &compatibleMSVCs); void writeBatchFile(QIODevice *device, const QString &vcvarsallbat, const QVector &msvcs) const; void parseBatOutput(const QByteArray &output, QVector msvcs); -- cgit v1.2.3