From e05c7867805167e927e36e03a92a6e99ac911dae Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 10 Aug 2021 13:09:21 +0200 Subject: [PATCH] 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 --- .../projectexplorer/kitinformation.cpp | 14 +++-- src/plugins/projectexplorer/msvctoolchain.cpp | 53 +++++++++++++++---- src/plugins/projectexplorer/msvctoolchain.h | 2 + src/plugins/projectexplorer/toolchain.h | 1 + src/plugins/qtsupport/qtkitinformation.cpp | 6 ++- 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 60e9dcbfa8c..eb02496a326 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -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) { - return t->targetAbi().toString() == abi && t->language() == l; - }); - if (tc) - setToolChain(k, tc); + QList possibleTcs = ToolChainManager::toolChains( + [abi, l](const ToolChain *t) { + return t->targetAbi().toString() == abi && t->language() == l; + }); + 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); } diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index cc637f17fe1..23677a2c4ce 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -109,6 +109,15 @@ const MsvcPlatform platforms[] static QList 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 MsvcToolChain::createConfigurationWidget( return std::make_unique(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 diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index b74d278d593..a13afe753d2 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -74,6 +74,7 @@ public: bool fromMap(const QVariantMap &data) override; std::unique_ptr 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; diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index b3ad1484c58..72c1b388bb9 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -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; diff --git a/src/plugins/qtsupport/qtkitinformation.cpp b/src/plugins/qtsupport/qtkitinformation.cpp index 54f61ec5912..002c49f7fc0 100644 --- a/src/plugins/qtsupport/qtkitinformation.cpp +++ b/src/plugins/qtsupport/qtkitinformation.cpp @@ -236,7 +236,11 @@ void QtKitAspect::fix(Kit *k) const QVector &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 goodTcs = Utils::filtered(possibleTcs,