MsvcToolchain: Fix "detection" of supported ABIs for msvc2010

Always ensure that supportedAbis includes targetAbi so toolchains that
don't have any vcvars32.bat or the like (like msvc2010) are restored
correctly at startup.

The cache-miss case is just shifted inside a else clause so the added
code is executed both in case of cache hit or miss.

The targetAbi is added to m_supportedAbis but is not cached in abiCache
as the abiCache has only vcVarsBat as the key, which is the same for
all toolchains of the same compiler but different architecture.

This way, even if the common supportedAbis is retrieved from the cache,
the presence of targetAbi is always checked and added if needed.

With this modification to detectInstalledAbis(), setSupportedAbi is not
needed anymore as it is redundant. Now msvc2015 build tools case is
handled the same way as msvc2010 in detectInstalledAbis().
This effectively reverts 2896e5f5e2.

Also, the existing QTC_ASSERT(m_supportedAbis.isEmpty(), return); in
detectInstalledAbis() is removed as when vcVars is changed, it can
have a new uncached vcVarsBase while having supportedAbis set already
(via a call to changeVcVarsCall).
This happens for clang-cl toolchains that inherit MsvcToolchain but
change vcVarsBat in ClangClToolChain::resetMsvcToolChain later (in
ClangClToolChain::detectClangClToolChainInPath).

Task-number: QTCREATORBUG-22960
Change-Id: Iaad5ea1dc649393037a3d32faa9075153974b5cb
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Alexis Murzeau
2019-10-14 23:52:16 +02:00
parent 8c7dd57645
commit 708179285d
2 changed files with 38 additions and 36 deletions

View File

@@ -776,39 +776,51 @@ void MsvcToolChain::updateEnvironmentModifications(QList<Utils::EnvironmentItem>
void MsvcToolChain::detectInstalledAbis()
{
if (!m_supportedAbis.isEmpty()) // Build Tools 2015
return;
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);
return;
} 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);
}
QTC_ASSERT(m_supportedAbis.isEmpty(), return);
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
@@ -1284,13 +1296,6 @@ void MsvcToolChain::changeVcVarsCall(const QString &varsBat, const QString &vars
}
}
void MsvcToolChain::setSupportedAbi(const Abi &abi)
{
// Hack for Build Tools 2015 only.
QTC_CHECK(m_supportedAbis.isEmpty());
m_supportedAbis = { abi };
}
// --------------------------------------------------------------------------
// MsvcBasedToolChainConfigWidget: Creates a simple GUI without error label
// to display name and varsBat. Derived classes should add the error label and
@@ -1909,7 +1914,6 @@ static void detectCppBuildTools2015(QList<ToolChain *> *list)
QLatin1String(e.varsBatArg));
tc->setDetection(ToolChain::AutoDetection);
tc->setLanguage(language);
tc->setSupportedAbi(abi);
list->append(tc);
}
}

View File

@@ -98,8 +98,6 @@ public:
void setVarsBatArg(const QString &varsBA) { m_varsBatArg = varsBA; }
void changeVcVarsCall(const QString &varsBat, const QString &varsBatArgs = QString());
void setSupportedAbi(const Abi &abi);
bool operator==(const ToolChain &) const override;
bool isJobCountSupported() const override { return false; }