From 87504eac2d28991f6a6361d722d2a0d41a4e277c Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 7 Feb 2017 14:40:18 +0100 Subject: [PATCH] ProjectExplorer: Handle toolchains at the ProjectImporter level Change-Id: I941d2eaa6fdd6135b49b51e8f685fb1d0d8b652c Reviewed-by: Tim Jenssen --- .../projectexplorer/projectimporter.cpp | 79 ++++++++++++++++++- src/plugins/projectexplorer/projectimporter.h | 13 +++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index 563510da8b6..91126ba4b13 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -32,9 +32,13 @@ #include "project.h" #include "projectexplorerconstants.h" #include "target.h" +#include "toolchain.h" +#include "toolchainmanager.h" #include +#include + #include #include @@ -70,7 +74,11 @@ static bool hasOtherUsers(Core::Id id, const QVariant &v, Kit *k) } ProjectImporter::ProjectImporter(const Utils::FileName &path) : m_projectPath(path) -{ } +{ + useTemporaryKitInformation(ToolChainKitInformation::id(), + [this](Kit *k, const QVariantList &vl) { cleanupTemporaryToolChains(k, vl); }, + [this](Kit *k, const QVariantList &vl) { persistTemporaryToolChains(k, vl); }); +} ProjectImporter::~ProjectImporter() { @@ -302,6 +310,33 @@ bool ProjectImporter::findTemporaryHandler(Core::Id id) const return Utils::contains(m_temporaryHandlers, [id](const TemporaryInformationHandler &ch) { return ch.id == id; }); } +static ToolChain *toolChainFromVariant(const QVariant &v) +{ + const QByteArray tcId = v.toByteArray(); + return ToolChainManager::findToolChain(tcId); +} + +void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) +{ + for (const QVariant &v : vl) { + ToolChain *tc = toolChainFromVariant(v); + QTC_ASSERT(tc, continue); + ToolChainManager::deregisterToolChain(tc); + ToolChainKitInformation::setToolChain(k, nullptr); + } +} + +void ProjectImporter::persistTemporaryToolChains(Kit *k, const QVariantList &vl) +{ + for (const QVariant &v : vl) { + ToolChain *tmpTc = toolChainFromVariant(v); + QTC_ASSERT(tmpTc, continue); + ToolChain *actualTc = ToolChainKitInformation::toolChain(k, tmpTc->language()); + if (tmpTc && actualTc != tmpTc) + ToolChainManager::deregisterToolChain(tmpTc); + } +} + void ProjectImporter::useTemporaryKitInformation(Core::Id id, ProjectImporter::CleanupFunction cleanup, ProjectImporter::PersistFunction persist) @@ -330,4 +365,46 @@ bool ProjectImporter::hasKitWithTemporaryData(Core::Id id, const QVariant &data) }); } +static ProjectImporter::ToolChainData +createToolChains(const Utils::FileName &toolChainPath, const Core::Id &language) +{ + const QList factories + = ExtensionSystem::PluginManager::getObjects(); + ProjectImporter::ToolChainData data; + + for (ToolChainFactory *factory : factories) { + data.tcs = factory->autoDetect(toolChainPath, language); + if (data.tcs.isEmpty()) + continue; + + for (ToolChain *tc : data.tcs) + ToolChainManager::registerToolChain(tc); + + data.areTemporary = true; + break; + } + + return data; +} + +ProjectImporter::ToolChainData +ProjectImporter::findOrCreateToolChains(const Utils::FileName &toolChainPath, + const Core::Id &language) const +{ + ToolChainData result; + result.tcs = ToolChainManager::toolChains([toolChainPath, language](const ToolChain *tc) { + return tc->language() == language && tc->compilerCommand() == toolChainPath; + }); + for (const ToolChain *tc : result.tcs) { + const QByteArray tcId = tc->id(); + result.areTemporary = result.areTemporary ? true : hasKitWithTemporaryData(ToolChainKitInformation::id(), tcId); + } + if (!result.tcs.isEmpty()) + return result; + + // Create a new toolchain: + UpdateGuard guard(*this); + return createToolChains(toolChainPath, language); +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectimporter.h b/src/plugins/projectexplorer/projectimporter.h index 40ed32a8de7..e676430b6b9 100644 --- a/src/plugins/projectexplorer/projectimporter.h +++ b/src/plugins/projectexplorer/projectimporter.h @@ -31,17 +31,25 @@ #include +#include + namespace ProjectExplorer { class BuildInfo; class Kit; class Project; class Target; +class ToolChain; // Documentation inside. class PROJECTEXPLORER_EXPORT ProjectImporter : public QObject { public: + struct ToolChainData { + QList tcs; + bool areTemporary = false; + }; + ProjectImporter(const Utils::FileName &path); virtual ~ProjectImporter(); @@ -101,10 +109,15 @@ protected: // Does *any* kit feature the requested data yet? bool hasKitWithTemporaryData(Core::Id id, const QVariant &data) const; + ToolChainData findOrCreateToolChains(const Utils::FileName &toolChainPath, const Core::Id &language) const; + private: void markKitAsTemporary(Kit *k) const; bool findTemporaryHandler(Core::Id id) const; + void cleanupTemporaryToolChains(ProjectExplorer::Kit *k, const QVariantList &vl); + void persistTemporaryToolChains(ProjectExplorer::Kit *k, const QVariantList &vl); + const Utils::FileName m_projectPath; mutable bool m_isUpdating = false;