QtSupport: check for preferred toolchain by host

Instead of just prefering perfect matches also take the host platform
into account when looking for matching toolchains. This allows us to
prefer the amd64 compiler over the x86_amd64 msvc compiler.

Change-Id: I59c8b7f95765a76ded7771cb8c26e03581ca2350
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2021-08-10 13:09:21 +02:00
parent f1b2be3e1d
commit e05c786780
5 changed files with 60 additions and 16 deletions

View File

@@ -502,11 +502,15 @@ void ToolChainKitAspect::setup(Kit *k)
// ID is not found: Might be an ABI string...
lockToolchains = false;
const QString abi = QString::fromUtf8(id);
tc = ToolChainManager::toolChain([abi, l](const ToolChain *t) {
QList<ToolChain *> possibleTcs = ToolChainManager::toolChains(
[abi, l](const ToolChain *t) {
return t->targetAbi().toString() == abi && t->language() == l;
});
if (tc)
setToolChain(k, tc);
Utils::sort(possibleTcs, [](const ToolChain *tc1, const ToolChain *tc2) {
return tc1->hostPrefersToolchain() && !tc2->hostPrefersToolchain();
});
if (!possibleTcs.isEmpty())
setToolChain(k, possibleTcs.first());
else
clearToolChain(k, l);
}

View File

@@ -109,6 +109,15 @@ const MsvcPlatform platforms[]
static QList<const MsvcToolChain *> g_availableMsvcToolchains;
static const MsvcPlatform *platformEntryFromName(const QString &name)
{
for (const MsvcPlatform &p : platforms) {
if (name == QLatin1String(p.name))
return &p;
}
return nullptr;
}
static const MsvcPlatform *platformEntry(MsvcToolChain::Platform t)
{
for (const MsvcPlatform &p : platforms) {
@@ -125,27 +134,37 @@ static QString platformName(MsvcToolChain::Platform t)
return QString();
}
static bool hostSupportsPlatform(MsvcToolChain::Platform platform)
static bool hostPrefersPlatform(MsvcToolChain::Platform platform)
{
switch (Utils::HostOsInfo::hostArchitecture()) {
case Utils::HostOsInfo::HostArchitectureAMD64:
if (platform == MsvcToolChain::amd64 || platform == MsvcToolChain::amd64_arm
|| platform == MsvcToolChain::amd64_x86 || platform == MsvcToolChain::amd64_arm64)
return true;
Q_FALLTHROUGH(); // all x86 toolchains are also working on an amd64 host
case Utils::HostOsInfo::HostArchitectureX86:
switch (HostOsInfo::hostArchitecture()) {
case HostOsInfo::HostArchitectureAMD64:
return platform == MsvcToolChain::amd64 || platform == MsvcToolChain::amd64_arm
|| platform == MsvcToolChain::amd64_x86 || platform == MsvcToolChain::amd64_arm64;
case HostOsInfo::HostArchitectureX86:
return platform == MsvcToolChain::x86 || platform == MsvcToolChain::x86_amd64
|| platform == MsvcToolChain::x86_ia64 || platform == MsvcToolChain::x86_arm
|| platform == MsvcToolChain::x86_arm64;
case Utils::HostOsInfo::HostArchitectureArm:
case HostOsInfo::HostArchitectureArm:
return platform == MsvcToolChain::arm;
case Utils::HostOsInfo::HostArchitectureItanium:
case HostOsInfo::HostArchitectureItanium:
return platform == MsvcToolChain::ia64;
default:
return false;
}
}
static bool hostSupportsPlatform(MsvcToolChain::Platform platform)
{
if (hostPrefersPlatform(platform))
return true;
// The x86 host toolchains are not the preferred toolchains on amd64 but they are still
// supported by that host
return HostOsInfo::hostArchitecture() == HostOsInfo::HostArchitectureAMD64
&& (platform == MsvcToolChain::x86 || platform == MsvcToolChain::x86_amd64
|| platform == MsvcToolChain::x86_ia64 || platform == MsvcToolChain::x86_arm
|| platform == MsvcToolChain::x86_arm64);
}
static QString fixRegistryPath(const QString &path)
{
QString result = QDir::fromNativeSeparators(path);
@@ -985,6 +1004,11 @@ std::unique_ptr<ToolChainConfigWidget> MsvcToolChain::createConfigurationWidget(
return std::make_unique<MsvcToolChainConfigWidget>(this);
}
bool MsvcToolChain::hostPrefersToolchain() const
{
return hostPrefersPlatform(platform());
}
bool static hasFlagEffectOnMacros(const QString &flag)
{
if (flag.startsWith("-") || flag.startsWith("/")) {
@@ -1212,6 +1236,15 @@ void MsvcToolChain::resetVarsBat()
m_varsBatArg.clear();
}
MsvcToolChain::Platform MsvcToolChain::platform() const
{
QStringList args = m_varsBatArg.split(' ');
if (const MsvcPlatform *entry = platformEntryFromName(args.value(0)))
return entry->platform;
return Utils::HostOsInfo::hostArchitecture() == Utils::HostOsInfo::HostArchitectureAMD64 ? amd64
: x86;
}
// --------------------------------------------------------------------------
// MsvcBasedToolChainConfigWidget: Creates a simple GUI without error label
// to display name and varsBat. Derived classes should add the error label and

View File

@@ -74,6 +74,7 @@ public:
bool fromMap(const QVariantMap &data) override;
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
bool hostPrefersToolchain() const override;
MacroInspectionRunner createMacroInspectionRunner() const override;
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
@@ -91,6 +92,7 @@ public:
QString varsBat() const { return m_vcvarsBat; }
void setupVarsBat(const Abi &abi, const QString &varsBat, const QString &varsBatArg);
void resetVarsBat();
Platform platform() const;
bool operator==(const ToolChain &) const override;

View File

@@ -116,6 +116,7 @@ public:
virtual QString originalTargetTriple() const { return QString(); }
virtual QStringList extraCodeModelFlags() const { return QStringList(); }
virtual Utils::FilePath installDir() const { return Utils::FilePath(); }
virtual bool hostPrefersToolchain() const { return true; }
virtual bool isValid() const;

View File

@@ -236,7 +236,11 @@ void QtKitAspect::fix(Kit *k)
const QVector<Abi> &qtAbis = version->qtAbis();
const bool tc1ExactMatch = qtAbis.contains(tc1->targetAbi());
const bool tc2ExactMatch = qtAbis.contains(tc2->targetAbi());
return tc1ExactMatch && !tc2ExactMatch;
if (tc1ExactMatch && !tc2ExactMatch)
return true;
if (!tc1ExactMatch && tc2ExactMatch)
return false;
return tc1->hostPrefersToolchain() && !tc2->hostPrefersToolchain();
});
const QList<ToolChain *> goodTcs = Utils::filtered(possibleTcs,