aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/projectexplorer/msvctoolchain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/projectexplorer/msvctoolchain.cpp')
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp169
1 files changed, 69 insertions, 100 deletions
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 9748b52f7f..2b46aaff67 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -67,7 +67,6 @@ using namespace Utils;
static const char varsBatKeyC[] = KEY_ROOT "VarsBat";
static const char varsBatArgKeyC[] = KEY_ROOT "VarsBatArg";
static const char supportedAbiKeyC[] = KEY_ROOT "SupportedAbi";
-static const char supportedAbisKeyC[] = KEY_ROOT "SupportedAbis";
static const char environModsKeyC[] = KEY_ROOT "environmentModifications";
enum { debug = 0 };
@@ -653,7 +652,7 @@ Macros MsvcToolChain::msvcPredefinedMacros(const QStringList &cxxflags,
// For _MSV_VER values, see https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2017.
//
Utils::LanguageVersion MsvcToolChain::msvcLanguageVersion(const QStringList & /*cxxflags*/,
- const Core::Id &language,
+ const Utils::Id &language,
const Macros &macros) const
{
using Utils::LanguageVersion;
@@ -775,55 +774,6 @@ void MsvcToolChain::updateEnvironmentModifications(Utils::EnvironmentItems modif
}
}
-void MsvcToolChain::detectInstalledAbis()
-{
- static QMap<QString, Abis> abiCache;
- const QString vcVarsBase
- = QDir::fromNativeSeparators(m_vcvarsBat).left(m_vcvarsBat.lastIndexOf('/'));
- if (abiCache.contains(vcVarsBase)) {
- m_supportedAbis = abiCache.value(vcVarsBase);
- } else {
- // Clear previously detected m_supportedAbis to repopulate it.
- m_supportedAbis.clear();
- const Abi baseAbi = targetAbi();
- for (MsvcPlatform platform : platforms) {
- bool toolchainInstalled = false;
- QString perhapsVcVarsPath = vcVarsBase + QLatin1Char('/') + QLatin1String(platform.bat);
- const Platform p = platform.platform;
- if (QFileInfo(perhapsVcVarsPath).isFile()) {
- toolchainInstalled = true;
- } else {
- // MSVC 2015 and below had various versions of vcvars scripts in subfolders. Try these
- // as fallbacks.
- perhapsVcVarsPath = vcVarsBase + platform.prefix + QLatin1Char('/')
- + QLatin1String(platform.bat);
- toolchainInstalled = QFileInfo(perhapsVcVarsPath).isFile();
- }
- if (hostSupportsPlatform(platform.platform) && toolchainInstalled) {
- Abi newAbi(archForPlatform(p),
- baseAbi.os(),
- baseAbi.osFlavor(),
- baseAbi.binaryFormat(),
- wordWidthForPlatform(p));
- if (!m_supportedAbis.contains(newAbi))
- m_supportedAbis.append(newAbi);
- }
- }
-
- abiCache.insert(vcVarsBase, m_supportedAbis);
- }
-
- // Always add targetAbi in supportedAbis if it is empty.
- // targetAbi is the abi with which the toolchain was detected.
- // This is necessary for toolchains that don't have vcvars32.bat and the like in their
- // vcVarsBase path, like msvc2010.
- // Also, don't include that one in abiCache to avoid polluting it with values specific
- // to one toolchain as the cache is global for a vcVarsBase path. For this reason, the
- // targetAbi needs to be added manually.
- if (m_supportedAbis.empty())
- m_supportedAbis.append(targetAbi());
-}
-
Utils::Environment MsvcToolChain::readEnvironmentSetting(const Utils::Environment &env) const
{
Utils::Environment resultEnv = env;
@@ -858,11 +808,12 @@ static void addToAvailableMsvcToolchains(const MsvcToolChain *toolchain)
g_availableMsvcToolchains.push_back(toolchain);
}
-MsvcToolChain::MsvcToolChain(Core::Id typeId)
+MsvcToolChain::MsvcToolChain(Utils::Id typeId)
: ToolChain(typeId)
{
setDisplayName("Microsoft Visual C++ Compiler");
- setTypeDisplayName(MsvcToolChainFactory::tr("MSVC"));
+ setTypeDisplayName(tr("MSVC"));
+ addToAvailableMsvcToolchains(this);
}
void MsvcToolChain::inferWarningsForLevel(int warningLevel, WarningFlags &flags)
@@ -894,11 +845,6 @@ Abi MsvcToolChain::targetAbi() const
return m_abi;
}
-Abis MsvcToolChain::supportedAbis() const
-{
- return m_supportedAbis;
-}
-
void MsvcToolChain::setTargetAbi(const Abi &abi)
{
m_abi = abi;
@@ -978,7 +924,6 @@ QVariantMap MsvcToolChain::toMap() const
if (!m_varsBatArg.isEmpty())
data.insert(QLatin1String(varsBatArgKeyC), m_varsBatArg);
data.insert(QLatin1String(supportedAbiKeyC), m_abi.toString());
- data.insert(supportedAbisKeyC, Utils::transform<QStringList>(m_supportedAbis, &Abi::toString));
Utils::EnvironmentItem::sort(&m_environmentModifications);
data.insert(QLatin1String(environModsKeyC),
Utils::EnvironmentItem::toVariantList(m_environmentModifications));
@@ -987,21 +932,15 @@ QVariantMap MsvcToolChain::toMap() const
bool MsvcToolChain::fromMap(const QVariantMap &data)
{
- if (!ToolChain::fromMap(data))
+ if (!ToolChain::fromMap(data)) {
+ g_availableMsvcToolchains.removeOne(this);
return false;
+ }
m_vcvarsBat = QDir::fromNativeSeparators(data.value(QLatin1String(varsBatKeyC)).toString());
m_varsBatArg = data.value(QLatin1String(varsBatArgKeyC)).toString();
const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
m_abi = Abi::fromString(abiString);
- const QStringList abiList = data.value(supportedAbisKeyC).toStringList();
- m_supportedAbis.clear();
- for (const QString &a : abiList) {
- Abi abi = Abi::fromString(a);
- if (!abi.isValid())
- continue;
- m_supportedAbis.append(abi);
- }
m_environmentModifications = Utils::EnvironmentItem::itemsFromVariantList(
data.value(QLatin1String(environModsKeyC)).toList());
rescanForCompiler();
@@ -1011,13 +950,9 @@ bool MsvcToolChain::fromMap(const QVariantMap &data)
m_vcvarsBat,
m_varsBatArg));
- // supported Abis were not stored in the map in previous versions of the settings. Re-detect
- if (m_supportedAbis.isEmpty())
- detectInstalledAbis();
-
- const bool valid = !m_vcvarsBat.isEmpty() && m_abi.isValid() && !m_supportedAbis.isEmpty();
- if (valid)
- addToAvailableMsvcToolchains(this);
+ const bool valid = !m_vcvarsBat.isEmpty() && m_abi.isValid();
+ if (!valid)
+ g_availableMsvcToolchains.removeOne(this);
return valid;
}
@@ -1046,7 +981,7 @@ ToolChain::MacroInspectionRunner MsvcToolChain::createMacroInspectionRunner() co
Utils::Environment env(m_lastEnvironment);
addToEnvironment(env);
MacrosCache macroCache = predefinedMacrosCache();
- const Core::Id lang = language();
+ const Utils::Id lang = language();
// This runner must be thread-safe!
return [this, env, macroCache, lang](const QStringList &cxxflags) {
@@ -1237,9 +1172,9 @@ void MsvcToolChain::rescanForCompiler()
});
}
-IOutputParser *MsvcToolChain::outputParser() const
+QList<OutputLineParser *> MsvcToolChain::createOutputParsers() const
{
- return new MsvcParser;
+ return {new MsvcParser};
}
void MsvcToolChain::setupVarsBat(const Abi &abi, const QString &varsBat, const QString &varsBatArg)
@@ -1250,7 +1185,6 @@ void MsvcToolChain::setupVarsBat(const Abi &abi, const QString &varsBat, const Q
m_varsBatArg = varsBatArg;
if (!varsBat.isEmpty()) {
- detectInstalledAbis();
initEnvModWatcher(Utils::runAsync(envModThreadPool(),
&MsvcToolChain::environmentModifications,
varsBat,
@@ -1410,34 +1344,66 @@ void MsvcToolChainConfigWidget::setFromMsvcToolChain()
m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
}
-void MsvcToolChainConfigWidget::handleVcVarsChange(const QString &vcVars)
+void MsvcToolChainConfigWidget::updateAbis()
{
- const QString normalizedVcVars = QDir::fromNativeSeparators(vcVars);
+ const QString normalizedVcVars = QDir::fromNativeSeparators(m_varsBatPathCombo->currentText());
const auto *currentTc = static_cast<const MsvcToolChain *>(toolChain());
QTC_ASSERT(currentTc, return );
const MsvcToolChain::Platform platform = m_varsBatArchCombo->currentData().value<MsvcToolChain::Platform>();
const Abi::Architecture arch = archForPlatform(platform);
const unsigned char wordWidth = wordWidthForPlatform(platform);
+ // Search the selected vcVars bat file in already detected MSVC compilers.
+ // For each variant of MSVC found, add its supported ABIs to the ABI widget so the user can
+ // choose one appropriately.
+ Abis supportedAbis;
+ Abi targetAbi;
for (const MsvcToolChain *tc : g_availableMsvcToolchains) {
if (tc->varsBat() == normalizedVcVars && tc->targetAbi().wordWidth() == wordWidth
- && tc->targetAbi().architecture() == arch) {
- m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
- break;
+ && tc->targetAbi().architecture() == arch && tc->language() == currentTc->language()) {
+ // We need to filter out duplicates as there might be multiple toolchains with
+ // same abi (like x86, amd64_x86 for example).
+ for (const Abi &abi : tc->supportedAbis()) {
+ if (!supportedAbis.contains(abi))
+ supportedAbis.append(abi);
+ }
+ targetAbi = tc->targetAbi();
+ }
+ }
+
+ // If we didn't find an exact match, try to find a fallback according to varsBat only.
+ // This can happen when the toolchain does not support user-selected arch/wordWidth.
+ if (!targetAbi.isValid()) {
+ const MsvcToolChain *tc = Utils::findOrDefault(g_availableMsvcToolchains,
+ [normalizedVcVars](const MsvcToolChain *tc) {
+ return tc->varsBat() == normalizedVcVars;
+ });
+ if (tc) {
+ targetAbi = Abi(arch,
+ tc->targetAbi().os(),
+ tc->targetAbi().osFlavor(),
+ tc->targetAbi().binaryFormat(),
+ wordWidth);
}
}
+
+ // Always set ABIs, even if none was found, to prevent stale data in the ABI widget.
+ // In that case, a custom ABI will be selected according to targetAbi.
+ m_abiWidget->setAbis(supportedAbis, targetAbi);
+
emit dirty();
}
+void MsvcToolChainConfigWidget::handleVcVarsChange(const QString &)
+{
+ updateAbis();
+}
+
void MsvcToolChainConfigWidget::handleVcVarsArchChange(const QString &)
{
- Abi currentAbi = m_abiWidget->currentAbi();
- const MsvcToolChain::Platform platform = m_varsBatArchCombo->currentData().value<MsvcToolChain::Platform>();
- Abi newAbi(archForPlatform(platform), currentAbi.os(), currentAbi.osFlavor(),
- currentAbi.binaryFormat(), wordWidthForPlatform(platform));
- if (currentAbi != newAbi)
- m_abiWidget->setAbis(m_abiWidget->supportedAbis(), newAbi);
- emit dirty();
+ // supportedAbi list in the widget only contains matching ABIs to whatever arch was selected.
+ // We need to reupdate it from scratch with new arch parameters
+ updateAbis();
}
QString MsvcToolChainConfigWidget::vcVarsArguments() const
@@ -1503,7 +1469,7 @@ void ClangClToolChainConfigWidget::setFromClangClToolChain()
if (clangClToolChain->isAutoDetected())
m_llvmDirLabel->setText(QDir::toNativeSeparators(clangClToolChain->clangPath()));
else
- m_compilerCommand->setFileName(Utils::FilePath::fromString(clangClToolChain->clangPath()));
+ m_compilerCommand->setFilePath(Utils::FilePath::fromString(clangClToolChain->clangPath()));
}
static const MsvcToolChain *findMsvcToolChain(unsigned char wordWidth, Abi::OSFlavor flavor)
@@ -1551,8 +1517,11 @@ static const MsvcToolChain *selectMsvcToolChain(const QString &displayedVarsBat,
QTC_CHECK(displayedVarsBat.isEmpty());
const QVersionNumber version = clangClVersion(clangClPath);
- if (version.majorVersion() >= 6)
- toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2017Flavor);
+ if (version.majorVersion() >= 6) {
+ toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2019Flavor);
+ if (!toolChain)
+ toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2017Flavor);
+ }
if (!toolChain) {
toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2015Flavor);
if (!toolChain)
@@ -1616,7 +1585,7 @@ static QString compilerFromPath(const QString &path)
void ClangClToolChainConfigWidget::applyImpl()
{
- Utils::FilePath clangClPath = m_compilerCommand->fileName();
+ Utils::FilePath clangClPath = m_compilerCommand->filePath();
auto clangClToolChain = static_cast<ClangClToolChain *>(toolChain());
clangClToolChain->setClangPath(clangClPath.toString());
@@ -1693,9 +1662,9 @@ QStringList ClangClToolChain::suggestedMkspecList() const
return {mkspec, "win32-clang-msvc"};
}
-IOutputParser *ClangClToolChain::outputParser() const
+QList<OutputLineParser *> ClangClToolChain::createOutputParsers() const
{
- return new ClangClParser;
+ return {new ClangClParser};
}
static inline QString llvmDirKey()
@@ -1759,7 +1728,7 @@ Macros ClangClToolChain::msvcPredefinedMacros(const QStringList &cxxflags,
}
Utils::LanguageVersion ClangClToolChain::msvcLanguageVersion(const QStringList &cxxflags,
- const Core::Id &language,
+ const Utils::Id &language,
const Macros &macros) const
{
if (cxxflags.contains("--driver-mode=g++"))
@@ -1784,7 +1753,7 @@ ClangClToolChain::BuiltInHeaderPathsRunner ClangClToolChain::createBuiltInHeader
MsvcToolChainFactory::MsvcToolChainFactory()
{
- setDisplayName(tr("MSVC"));
+ setDisplayName(MsvcToolChain::tr("MSVC"));
setSupportedToolChainType(Constants::MSVC_TOOLCHAIN_TYPEID);
setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID});
setToolchainConstructor([] { return new MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID); });
@@ -1966,7 +1935,7 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
ClangClToolChainFactory::ClangClToolChainFactory()
{
- setDisplayName(tr("clang-cl"));
+ setDisplayName(ClangClToolChain::tr("clang-cl"));
setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID});
setSupportedToolChainType(Constants::CLANG_CL_TOOLCHAIN_TYPEID);
setToolchainConstructor([] { return new ClangClToolChain; });