diff options
author | Ivan Komissarov <abbapoh@gmail.com> | 2021-04-24 02:20:06 +0300 |
---|---|---|
committer | Ivan Komissarov <abbapoh@gmail.com> | 2021-04-24 02:20:06 +0300 |
commit | a8bbaf016dc3092f6f6ad0c4a333e595da665983 (patch) | |
tree | 6b1b74bbca7850ed75da01cba5a72618f3cfa94b /src/lib/corelib | |
parent | 001bf31623c02ba8249dd066777d014d546eb7f9 (diff) | |
parent | 2f6eecdc96fcd693cecef8011d8f9500c7872fc7 (diff) |
Merge branch '1.19' into master
Change-Id: Ic6087168a1d93c2a2b46de825f5c3b9655634e8e
Diffstat (limited to 'src/lib/corelib')
-rw-r--r-- | src/lib/corelib/jsextensions/utilitiesextension.cpp | 32 | ||||
-rw-r--r-- | src/lib/corelib/tools/msvcinfo.cpp | 32 | ||||
-rw-r--r-- | src/lib/corelib/tools/msvcinfo.h | 7 | ||||
-rw-r--r-- | src/lib/corelib/tools/set.h | 4 | ||||
-rw-r--r-- | src/lib/corelib/tools/stlutils.h | 15 | ||||
-rw-r--r-- | src/lib/corelib/tools/vsenvironmentdetector.cpp | 9 | ||||
-rw-r--r-- | src/lib/corelib/tools/vsenvironmentdetector.h | 3 |
7 files changed, 85 insertions, 17 deletions
diff --git a/src/lib/corelib/jsextensions/utilitiesextension.cpp b/src/lib/corelib/jsextensions/utilitiesextension.cpp index 6c693cb61..282362382 100644 --- a/src/lib/corelib/jsextensions/utilitiesextension.cpp +++ b/src/lib/corelib/jsextensions/utilitiesextension.cpp @@ -468,9 +468,10 @@ static std::pair<QVariantMap /*result*/, QString /*error*/> msvcCompilerInfoHelp const QString &compilerFilePath, MSVC::CompilerLanguage language, const QString &vcvarsallPath, - const QString &arch) + const QString &arch, + const QString &sdkVersion) { - MSVC msvc(compilerFilePath, arch); + MSVC msvc(compilerFilePath, arch, sdkVersion); VsEnvironmentDetector envdetector(vcvarsallPath); if (!envdetector.start(&msvc)) return { {}, QStringLiteral("Detecting the MSVC build environment failed: ") @@ -501,12 +502,16 @@ QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QS return context->throwError(QScriptContext::UnknownError, QStringLiteral("msvcCompilerInfo is not available on this platform")); #else - if (Q_UNLIKELY(context->argumentCount() < 2)) + if (Q_UNLIKELY(context->argumentCount() < 3)) return context->throwError(QScriptContext::SyntaxError, - QStringLiteral("msvcCompilerInfo expects 2 arguments")); + QStringLiteral("msvcCompilerInfo expects 3 arguments")); const QString compilerFilePath = context->argument(0).toString(); const QString compilerLanguage = context->argument(1).toString(); + const QString sdkVersion = + !context->argument(2).isNull() && !context->argument(2).isUndefined() + ? context->argument(2).toString() + : QString(); MSVC::CompilerLanguage language; if (compilerLanguage == QStringLiteral("c")) language = MSVC::CLanguage; @@ -517,7 +522,11 @@ QScriptValue UtilitiesExtension::js_msvcCompilerInfo(QScriptContext *context, QS QStringLiteral("msvcCompilerInfo expects \"c\" or \"cpp\" as its second argument")); const auto result = msvcCompilerInfoHelper( - compilerFilePath, language, {}, MSVC::architectureFromClPath(compilerFilePath)); + compilerFilePath, + language, + {}, + MSVC::architectureFromClPath(compilerFilePath), + sdkVersion); if (result.first.isEmpty()) return context->throwError(QScriptContext::UnknownError, result.second); return engine->toScriptValue(result.first); @@ -531,9 +540,9 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context, return context->throwError(QScriptContext::UnknownError, QStringLiteral("clangClCompilerInfo is not available on this platform")); #else - if (Q_UNLIKELY(context->argumentCount() < 4)) + if (Q_UNLIKELY(context->argumentCount() < 5)) return context->throwError(QScriptContext::SyntaxError, - QStringLiteral("clangClCompilerInfo expects 4 arguments")); + QStringLiteral("clangClCompilerInfo expects 5 arguments")); const QString compilerFilePath = context->argument(0).toString(); // architecture cannot be empty as vcvarsall.bat requires at least 1 arg, so fallback @@ -542,9 +551,14 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context, ? context->argument(1).toString() : QString::fromStdString(HostOsInfo::hostOSArchitecture()); QString vcvarsallPath = context->argument(2).toString(); - const QString compilerLanguage = context->argumentCount() > 3 + const QString compilerLanguage = + !context->argument(3).isNull() && !context->argument(3).isUndefined() ? context->argument(3).toString() : QString(); + const QString sdkVersion = + !context->argument(4).isNull() && !context->argument(4).isUndefined() + ? context->argument(4).toString() + : QString(); MSVC::CompilerLanguage language; if (compilerLanguage == QStringLiteral("c")) language = MSVC::CLanguage; @@ -555,7 +569,7 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context, QStringLiteral("clangClCompilerInfo expects \"c\" or \"cpp\" as its fourth argument")); const auto result = msvcCompilerInfoHelper( - compilerFilePath, language, vcvarsallPath, arch); + compilerFilePath, language, vcvarsallPath, arch, sdkVersion); if (result.first.isEmpty()) return context->throwError(QScriptContext::UnknownError, result.second); return engine->toScriptValue(result.first); diff --git a/src/lib/corelib/tools/msvcinfo.cpp b/src/lib/corelib/tools/msvcinfo.cpp index 42cfefe7b..58cd458c3 100644 --- a/src/lib/corelib/tools/msvcinfo.cpp +++ b/src/lib/corelib/tools/msvcinfo.cpp @@ -43,6 +43,7 @@ #include <logging/logger.h> #include <tools/error.h> #include <tools/profile.h> +#include <tools/stlutils.h> #include <tools/stringconstants.h> #include <QtCore/qbytearray.h> @@ -471,12 +472,20 @@ static std::vector<MSVC> installedCompilersHelper(Logger &logger) QDir vcInstallDir = vsInstallDir; vcInstallDir.cd(QStringLiteral("Tools/MSVC")); const auto vcVersionStrs = vcInstallDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + std::vector<Version> vcVersions; + vcVersions.reserve(vcVersionStrs.size()); for (const QString &vcVersionStr : vcVersionStrs) { const Version vcVersion = Version::fromString(vcVersionStr); if (!vcVersion.isValid()) continue; + vcVersions.push_back(vcVersion); + } + // sort the versions so the new one comes first + std::sort(vcVersions.begin(), vcVersions.end(), std::greater<>()); + + for (const Version &vcVersion : vcVersions) { QDir specificVcInstallDir = vcInstallDir; - if (!specificVcInstallDir.cd(vcVersionStr) + if (!specificVcInstallDir.cd(vcVersion.toString()) || !specificVcInstallDir.cd(QStringLiteral("bin"))) { continue; } @@ -501,11 +510,32 @@ QString MSVC::architectureFromClPath(const QString &clPath) { const auto parentDir = QFileInfo(clPath).absolutePath(); const auto parentDirName = QFileInfo(parentDir).fileName().toLower(); + // can be the case when cl.exe is present within the Windows SDK installation... but can it? if (parentDirName == QLatin1String("bin")) return QStringLiteral("x86"); return parentDirName; } +QString MSVC::vcVariablesVersionFromBinPath(const QString &binPath) +{ + const auto binDirName = QFileInfo(binPath).fileName().toLower(); + // the case when cl.exe is present within the Windows SDK installation + if (binDirName == QLatin1String("bin")) + return {}; + // binPath is something like + // Microsoft Visual Studio 14.0/VC/bin/amd64_x86 + // or + // Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29910/bin/Hostx64/x64 + QDir dir(binPath); + dir.cdUp(); + // older Visual Studios do not support multiple compiler versions + if (dir.dirName().toLower() == QLatin1String("bin")) + return {}; + dir.cdUp(); + dir.cdUp(); + return dir.dirName(); +} + QString MSVC::canonicalArchitecture(const QString &arch) { if (arch == QLatin1String("x64") || arch == QLatin1String("amd64")) diff --git a/src/lib/corelib/tools/msvcinfo.h b/src/lib/corelib/tools/msvcinfo.h index de4470bf0..efaf0b6c2 100644 --- a/src/lib/corelib/tools/msvcinfo.h +++ b/src/lib/corelib/tools/msvcinfo.h @@ -81,12 +81,14 @@ public: QString binPath; QString pathPrefix; QString architecture; + QString sdkVersion; QProcessEnvironment environment; MSVC() = default; - MSVC(const QString &clPath, QString arch): - architecture(std::move(arch)) + MSVC(const QString &clPath, QString arch, QString sdkVersion = {}): + architecture(std::move(arch)), + sdkVersion(std::move(sdkVersion)) { QDir parentDir = QFileInfo(clPath).dir(); binPath = parentDir.absolutePath(); @@ -98,6 +100,7 @@ public: QBS_EXPORT void init(); QBS_EXPORT static QString architectureFromClPath(const QString &clPath); + QBS_EXPORT static QString vcVariablesVersionFromBinPath(const QString &binPath); QBS_EXPORT static QString canonicalArchitecture(const QString &arch); QBS_EXPORT static std::pair<QString, QString> getHostTargetArchPair(const QString &arch); QBS_EXPORT QString binPathForArchitecture(const QString &arch) const; diff --git a/src/lib/corelib/tools/set.h b/src/lib/corelib/tools/set.h index 75db0528b..463d3beb6 100644 --- a/src/lib/corelib/tools/set.h +++ b/src/lib/corelib/tools/set.h @@ -112,8 +112,8 @@ public: Set &operator&=(const Set &other) { return intersect(other); } Set &operator&=(const T &v) { return intersect(Set{ v }); } - iterator find(const T &v) { return std::find(m_data.begin(), m_data.end(), v); } - const_iterator find(const T &v) const { return std::find(m_data.cbegin(), m_data.cend(), v); } + iterator find(const T &v) { return binaryFind(m_data.begin(), m_data.end(), v); } + const_iterator find(const T &v) const { return binaryFind(m_data.cbegin(), m_data.cend(), v); } std::pair<iterator, bool> insert(const T &v); Set &operator+=(const T &v) { insert(v); return *this; } Set &operator|=(const T &v) { return operator+=(v); } diff --git a/src/lib/corelib/tools/stlutils.h b/src/lib/corelib/tools/stlutils.h index 1b6d7278f..d4c569a95 100644 --- a/src/lib/corelib/tools/stlutils.h +++ b/src/lib/corelib/tools/stlutils.h @@ -123,6 +123,21 @@ bool none_of(const Container &container, const UnaryPredicate &predicate) return std::none_of(std::begin(container), std::end(container), predicate); } +template <class It, class T, class Compare> +It binaryFind(It begin, It end, const T &value, Compare comp) +{ + const auto it = std::lower_bound(begin, end, value, comp); + if (it == end || comp(value, *it)) + return end; + return it; +} + +template <class It, class T> +It binaryFind(It begin, It end, const T &value) +{ + return binaryFind(begin, end, value, std::less<T>()); +} + template <class C> C &operator<<(C &container, const typename C::value_type &v) { diff --git a/src/lib/corelib/tools/vsenvironmentdetector.cpp b/src/lib/corelib/tools/vsenvironmentdetector.cpp index b0788823f..82dff578f 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.cpp +++ b/src/lib/corelib/tools/vsenvironmentdetector.cpp @@ -241,8 +241,13 @@ void VsEnvironmentDetector::writeBatchFile(QIODevice *device, const QString &vcv << "setlocal" << endl; batClearVars(s, varnames); s << "set PATH=" << m_windowsSystemDirPath << endl; // vcvarsall.bat needs tools from here - s << "call \"" << vcvarsallbat << "\" " << vcArchitecture(msvc) - << " || exit /b 1" << endl; + s << "call \"" << vcvarsallbat << "\" " << vcArchitecture(msvc); + if (!msvc->sdkVersion.isEmpty()) + s << " " << msvc->sdkVersion; + const auto vcVarsVer = MSVC::vcVariablesVersionFromBinPath(msvc->binPath); + if (!vcVarsVer.isEmpty()) + s << " -vcvars_ver=" << vcVarsVer; + s << " || exit /b 1" << endl; batPrintVars(s, varnames); s << "endlocal" << endl; } diff --git a/src/lib/corelib/tools/vsenvironmentdetector.h b/src/lib/corelib/tools/vsenvironmentdetector.h index 7fa152cb6..39bea07d6 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.h +++ b/src/lib/corelib/tools/vsenvironmentdetector.h @@ -57,7 +57,7 @@ class MSVC; class QBS_EXPORT VsEnvironmentDetector { public: - explicit VsEnvironmentDetector(QString vcvarsallPath = QString()); + explicit VsEnvironmentDetector(QString vcvarsallPath = {}); bool start(MSVC *msvc); bool start(std::vector<MSVC *> msvcs); @@ -71,6 +71,7 @@ private: const QString m_windowsSystemDirPath; const QString m_vcvarsallPath; + const QString m_vcVariablesVersion; QString m_errorString; }; |