From b6299edf1fd99ba048e466418f580d30d8dc3322 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 8 Aug 2024 15:24:49 +0200 Subject: [PATCH] ProjectExplorer: Factor out function to compare toolchain suitability ... and use in ToolchainKitAspect in addition to KitManager. Change-Id: I4c9221735a660697baab667877cc335ee0ee3e78 Reviewed-by: hjk --- src/plugins/projectexplorer/kitaspects.cpp | 16 ++++----- src/plugins/projectexplorer/kitmanager.cpp | 30 +--------------- .../projectexplorer/toolchainmanager.cpp | 34 +++++++++++++++++++ .../projectexplorer/toolchainmanager.h | 2 ++ 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/plugins/projectexplorer/kitaspects.cpp b/src/plugins/projectexplorer/kitaspects.cpp index c5478de4edf..60ca66ee17b 100644 --- a/src/plugins/projectexplorer/kitaspects.cpp +++ b/src/plugins/projectexplorer/kitaspects.cpp @@ -460,22 +460,20 @@ static void setToolchainsFromAbis(Kit *k, const LanguagesAndAbis &abisByLanguage // Set a matching bundle for each LanguageCategory/Abi pair, if possible. for (auto it = abisByCategory.cbegin(); it != abisByCategory.cend(); ++it) { - QList matchingBundles + const QList matchingBundles = Utils::filtered(bundles, [&it](const ToolchainBundle &b) { return b.factory()->languageCategory() == it.key() && b.targetAbi() == it.value(); }); - // FIXME: Re-use the algorithm from KitManager - Utils::sort(matchingBundles, [](const ToolchainBundle &b1, const ToolchainBundle &b2) { - return b1.get(&Toolchain::priority) > b2.get(&Toolchain::priority); - }); - - if (!matchingBundles.isEmpty()) { - ToolchainKitAspect::setBundle(k, matchingBundles.first()); - } else { + if (matchingBundles.isEmpty()) { for (const Id language : it.key()) ToolchainKitAspect::clearToolchain(k, language); + continue; } + + const auto bestBundle + = std::min_element(bundles.begin(), bundles.end(), &ToolchainManager::isBetterToolchain); + ToolchainKitAspect::setBundle(k, *bestBundle); } } diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index 04425377efa..e78ba9c3a52 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -300,9 +300,6 @@ void KitManager::restoreKits() // No kits exist yet, so let's try to autoconfigure some from the toolchains we know. QHash>> uniqueToolchains; - // On Linux systems, we usually detect a plethora of same-ish toolchains. The following - // algorithm gives precedence to icecc and ccache and otherwise simply chooses the one with - // the shortest path. const QList bundles = ToolchainBundle::collectBundles( ToolchainBundle::AutoRegister::On); for (const ToolchainBundle &bundle : bundles) { @@ -313,32 +310,7 @@ void KitManager::restoreKits() continue; } - const int bestPriority = bestBundle->get(&Toolchain::priority); - const int currentPriority = bundle.get(&Toolchain::priority); - if (bestPriority > currentPriority) - continue; - if (bestPriority < currentPriority) { - bestBundle = bundle; - continue; - } - - const QString bestFilePath = bestBundle->get(&Toolchain::compilerCommand).toString(); - const QString currentFilePath = bundle.get(&Toolchain::compilerCommand).toString(); - if (bestFilePath.contains("icecc")) - continue; - if (currentFilePath.contains("icecc")) { - bestBundle = bundle; - continue; - } - - if (bestFilePath.contains("ccache")) - continue; - if (currentFilePath.contains("ccache")) { - bestBundle = bundle; - continue; - } - - if (bestFilePath.length() > currentFilePath.length()) + if (ToolchainManager::isBetterToolchain(bundle, *bestBundle)) bestBundle = bundle; } diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp index 9311aaf6872..d93817b9f0b 100644 --- a/src/plugins/projectexplorer/toolchainmanager.cpp +++ b/src/plugins/projectexplorer/toolchainmanager.cpp @@ -331,4 +331,38 @@ void ToolchainManager::addBadToolchain(const Utils::FilePath &toolchain) d->m_badToolchains.toolchains << toolchain; } +// Use as a tie-breaker for toolchains that match the strong requirements like toolchain type +// and ABI. +// For toolchains with the same priority, gives precedence to icecc and ccache +// and otherwise simply chooses the one with the shortest path. +bool ToolchainManager::isBetterToolchain( + const ToolchainBundle &bundle1, const ToolchainBundle &bundle2) +{ + const int priority1 = bundle1.get(&Toolchain::priority); + const int priority2 = bundle2.get(&Toolchain::priority); + if (priority1 > priority2) + return true; + if (priority1 < priority2) + return false; + + const QString path1 = bundle1.get(&Toolchain::compilerCommand).path(); + const QString path2 = bundle2.get(&Toolchain::compilerCommand).path(); + + const bool b1IsIcecc = path1.contains("icecc"); + const bool b2IsIcecc = path2.contains("icecc"); + if (b1IsIcecc) + return !b2IsIcecc; + if (b2IsIcecc) + return false; + + const bool b1IsCCache = path1.contains("ccache"); + const bool b2IsCcache = path2.contains("ccache"); + if (b1IsCCache) + return !b2IsCcache; + if (b2IsCcache) + return false; + + return path1.size() < path2.size(); +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/toolchainmanager.h b/src/plugins/projectexplorer/toolchainmanager.h index 5eff268c288..9065d8ab2e2 100644 --- a/src/plugins/projectexplorer/toolchainmanager.h +++ b/src/plugins/projectexplorer/toolchainmanager.h @@ -67,6 +67,8 @@ public: static bool isBadToolchain(const Utils::FilePath &toolchain); static void addBadToolchain(const Utils::FilePath &toolchain); + static bool isBetterToolchain(const ToolchainBundle &bundle1, const ToolchainBundle &bundle2); + void saveToolchains(); signals: