ProjectExplorer: Use toolchain bundles when auto-detecting kits

Fixes: QTCREATORBUG-30630
Change-Id: I0929a809204ccd6f8e547987bc7bec42249efa32
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2024-08-06 15:29:48 +02:00
parent 35493fddf1
commit 6e2db380d0

View File

@@ -35,6 +35,8 @@
#include <QPushButton> #include <QPushButton>
#include <QStyle> #include <QStyle>
#include <optional>
using namespace Core; using namespace Core;
using namespace Utils; using namespace Utils;
using namespace ProjectExplorer::Internal; using namespace ProjectExplorer::Internal;
@@ -298,46 +300,49 @@ void KitManager::restoreKits()
if (resultList.empty() || !haveKitForBinary) { if (resultList.empty() || !haveKitForBinary) {
// No kits exist yet, so let's try to autoconfigure some from the toolchains we know. // No kits exist yet, so let's try to autoconfigure some from the toolchains we know.
QHash<Abi, QHash<Utils::Id, Toolchain *>> uniqueToolchains; QHash<Abi, QHash<LanguageCategory, std::optional<ToolchainBundle>>> uniqueToolchains;
// On Linux systems, we usually detect a plethora of same-ish toolchains. The following // 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 // algorithm gives precedence to icecc and ccache and otherwise simply chooses the one with
// the shortest path. This should also take care of ensuring matching C/C++ pairs. // the shortest path.
// TODO: This should not need to be done here. Instead, it should be a convenience const QList<ToolchainBundle> bundles = ToolchainBundle::collectBundles();
// operation on some lower level, e.g. in the toolchain class(es). for (const ToolchainBundle &bundle : bundles) {
// Also, we shouldn't detect so many doublets in the first place. ToolchainManager::registerToolchains(bundle.createdToolchains());
for (Toolchain * const tc : ToolchainManager::toolchains()) {
Toolchain *&bestTc = uniqueToolchains[tc->targetAbi()][tc->language()]; auto &bestBundle
if (!bestTc) { = uniqueToolchains[bundle.targetAbi()][bundle.factory()->languageCategory()];
bestTc = tc; if (!bestBundle) {
bestBundle = bundle;
continue; continue;
} }
if (bestTc->priority() > tc->priority()) const int bestPriority = bestBundle->get(&Toolchain::priority);
const int currentPriority = bundle.get(&Toolchain::priority);
if (bestPriority > currentPriority)
continue; continue;
if (bestTc->priority() < tc->priority()) { if (bestPriority < currentPriority) {
bestTc = tc; bestBundle = bundle;
continue; continue;
} }
const QString bestFilePath = bestTc->compilerCommand().toString(); const QString bestFilePath = bestBundle->get(&Toolchain::compilerCommand).toString();
const QString currentFilePath = tc->compilerCommand().toString(); const QString currentFilePath = bundle.get(&Toolchain::compilerCommand).toString();
if (bestFilePath.contains("icecc")) if (bestFilePath.contains("icecc"))
continue; continue;
if (currentFilePath.contains("icecc")) { if (currentFilePath.contains("icecc")) {
bestTc = tc; bestBundle = bundle;
continue; continue;
} }
if (bestFilePath.contains("ccache")) if (bestFilePath.contains("ccache"))
continue; continue;
if (currentFilePath.contains("ccache")) { if (currentFilePath.contains("ccache")) {
bestTc = tc; bestBundle = bundle;
continue; continue;
} }
if (bestFilePath.length() > currentFilePath.length()) if (bestFilePath.length() > currentFilePath.length())
bestTc = tc; bestBundle = bundle;
} }
// Create temporary kits for all toolchains found. // Create temporary kits for all toolchains found.
@@ -346,8 +351,8 @@ void KitManager::restoreKits()
auto kit = std::make_unique<Kit>(); auto kit = std::make_unique<Kit>();
kit->setSdkProvided(false); kit->setSdkProvided(false);
kit->setAutoDetected(false); // TODO: Why false? What does autodetected mean here? kit->setAutoDetected(false); // TODO: Why false? What does autodetected mean here?
for (Toolchain * const tc : it.value()) for (const auto &bundle : it.value())
ToolchainKitAspect::setToolchain(kit.get(), tc); ToolchainKitAspect::setBundle(kit.get(), *bundle);
if (contains(resultList, [&kit](const std::unique_ptr<Kit> &existingKit) { if (contains(resultList, [&kit](const std::unique_ptr<Kit> &existingKit) {
return ToolchainKitAspect::toolChains(kit.get()) return ToolchainKitAspect::toolChains(kit.get())
== ToolchainKitAspect::toolChains(existingKit.get()); == ToolchainKitAspect::toolChains(existingKit.get());