forked from qt-creator/qt-creator
ProjectExplorer: Fix msvc toolschain abi compatibility
According to MSDN: "You can mix binaries built by different versions of the v140, v141, and v142 toolsets. However, you must link by using a toolset at least as recent as the most recent binary in your app. Here's an example: you can link an app compiled using any 2017 toolset (v141, versions 15.0 through 15.9) to a static library compiled using, say, Visual Studio 2019 version 16.2 (v142), if they're linked using a version 16.2 or later toolset. You can link a version 16.2 library to a version 16.4 app as long as you use a 16.4 or later toolset." https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017? view=msvc-160 So don't try to assign an older msvc toolchain to a kit that contains a Qt build with a newer version of msvc. Fixes: QTCREATORBUG-25618 Change-Id: If58676da5f61add1eed7e786862ee475e180b7dc Reviewed-by: Robert Löhning <robert.loehning@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -726,14 +726,6 @@ bool Abi::isCompatibleWith(const Abi &other) const
|
||||
return isCompat;
|
||||
}
|
||||
|
||||
bool Abi::isFullyCompatibleWith(const Abi &other) const
|
||||
{
|
||||
return *this == other
|
||||
|| (wordWidth() == other.wordWidth()
|
||||
&& architecture() == other.architecture()
|
||||
&& compatibleMSVCFlavors(osFlavor(), other.osFlavor()));
|
||||
}
|
||||
|
||||
bool Abi::isValid() const
|
||||
{
|
||||
return m_architecture != UnknownArchitecture
|
||||
|
||||
@@ -148,7 +148,6 @@ public:
|
||||
bool operator != (const Abi &other) const;
|
||||
bool operator == (const Abi &other) const;
|
||||
bool isCompatibleWith(const Abi &other) const;
|
||||
bool isFullyCompatibleWith(const Abi &other) const;
|
||||
|
||||
bool isValid() const;
|
||||
bool isNull() const;
|
||||
|
||||
@@ -908,6 +908,33 @@ QStringList MsvcToolChain::suggestedMkspecList() const
|
||||
return {};
|
||||
}
|
||||
|
||||
Abis MsvcToolChain::supportedAbis() const
|
||||
{
|
||||
Abi abi = targetAbi();
|
||||
Abis abis = {abi};
|
||||
switch (abi.osFlavor()) {
|
||||
case Abi::WindowsMsvc2019Flavor:
|
||||
abis << Abi(abi.architecture(),
|
||||
abi.os(),
|
||||
Abi::WindowsMsvc2017Flavor,
|
||||
abi.binaryFormat(),
|
||||
abi.wordWidth(),
|
||||
abi.param());
|
||||
Q_FALLTHROUGH();
|
||||
case Abi::WindowsMsvc2017Flavor:
|
||||
abis << Abi(abi.architecture(),
|
||||
abi.os(),
|
||||
Abi::WindowsMsvc2015Flavor,
|
||||
abi.binaryFormat(),
|
||||
abi.wordWidth(),
|
||||
abi.param());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return abis;
|
||||
}
|
||||
|
||||
QVariantMap MsvcToolChain::toMap() const
|
||||
{
|
||||
QVariantMap data = ToolChain::toMap();
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
QString originalTargetTriple() const override;
|
||||
|
||||
QStringList suggestedMkspecList() const override;
|
||||
Abis supportedAbis() const override;
|
||||
|
||||
QVariantMap toMap() const override;
|
||||
bool fromMap(const QVariantMap &data) override;
|
||||
|
||||
@@ -516,6 +516,7 @@ Tasks BaseQtVersion::validateKit(const Kit *k)
|
||||
|
||||
if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) {
|
||||
Abi targetAbi = tc->targetAbi();
|
||||
Abis supportedAbis = tc->supportedAbis();
|
||||
bool fuzzyMatch = false;
|
||||
bool fullMatch = false;
|
||||
|
||||
@@ -526,9 +527,12 @@ Tasks BaseQtVersion::validateKit(const Kit *k)
|
||||
qtAbiString.append(qtAbi.toString());
|
||||
|
||||
if (!fullMatch)
|
||||
fullMatch = targetAbi.isFullyCompatibleWith(qtAbi);
|
||||
if (!fuzzyMatch)
|
||||
fuzzyMatch = targetAbi.isCompatibleWith(qtAbi);
|
||||
fullMatch = supportedAbis.contains(qtAbi);
|
||||
if (!fuzzyMatch && !fullMatch) {
|
||||
fuzzyMatch = Utils::anyOf(supportedAbis, [&](const Abi &abi) {
|
||||
return qtAbi.isCompatibleWith(abi);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
QString message;
|
||||
|
||||
@@ -222,11 +222,10 @@ void QtKitAspect::fix(Kit *k)
|
||||
|
||||
const QString spec = version->mkspec();
|
||||
QList<ToolChain *> possibleTcs = ToolChainManager::toolChains([version](const ToolChain *t) {
|
||||
return t->isValid()
|
||||
&& t->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID
|
||||
&& contains(version->qtAbis(), [t](const Abi &qtAbi) {
|
||||
return qtAbi.isFullyCompatibleWith(t->targetAbi());
|
||||
});
|
||||
if (!t->isValid() || t->language() != ProjectExplorer::Constants::CXX_LANGUAGE_ID)
|
||||
return false;
|
||||
return Utils::anyOf(version->qtAbis(),
|
||||
[t](const Abi &qtAbi) { return t->supportedAbis().contains(qtAbi); });
|
||||
});
|
||||
if (!possibleTcs.isEmpty()) {
|
||||
// Prefer exact matches.
|
||||
|
||||
Reference in New Issue
Block a user