ProjectExplorer: Handle toolchains at the ProjectImporter level

Change-Id: I941d2eaa6fdd6135b49b51e8f685fb1d0d8b652c
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2017-02-07 14:40:18 +01:00
parent 587b2cbe0f
commit 87504eac2d
2 changed files with 91 additions and 1 deletions

View File

@@ -32,9 +32,13 @@
#include "project.h" #include "project.h"
#include "projectexplorerconstants.h" #include "projectexplorerconstants.h"
#include "target.h" #include "target.h"
#include "toolchain.h"
#include "toolchainmanager.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -70,7 +74,11 @@ static bool hasOtherUsers(Core::Id id, const QVariant &v, Kit *k)
} }
ProjectImporter::ProjectImporter(const Utils::FileName &path) : m_projectPath(path) 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() 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; }); 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, void ProjectImporter::useTemporaryKitInformation(Core::Id id,
ProjectImporter::CleanupFunction cleanup, ProjectImporter::CleanupFunction cleanup,
ProjectImporter::PersistFunction persist) 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<ToolChainFactory *> factories
= ExtensionSystem::PluginManager::getObjects<ToolChainFactory>();
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 } // namespace ProjectExplorer

View File

@@ -31,17 +31,25 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <QVariant>
namespace ProjectExplorer { namespace ProjectExplorer {
class BuildInfo; class BuildInfo;
class Kit; class Kit;
class Project; class Project;
class Target; class Target;
class ToolChain;
// Documentation inside. // Documentation inside.
class PROJECTEXPLORER_EXPORT ProjectImporter : public QObject class PROJECTEXPLORER_EXPORT ProjectImporter : public QObject
{ {
public: public:
struct ToolChainData {
QList<ToolChain *> tcs;
bool areTemporary = false;
};
ProjectImporter(const Utils::FileName &path); ProjectImporter(const Utils::FileName &path);
virtual ~ProjectImporter(); virtual ~ProjectImporter();
@@ -101,10 +109,15 @@ protected:
// Does *any* kit feature the requested data yet? // Does *any* kit feature the requested data yet?
bool hasKitWithTemporaryData(Core::Id id, const QVariant &data) const; bool hasKitWithTemporaryData(Core::Id id, const QVariant &data) const;
ToolChainData findOrCreateToolChains(const Utils::FileName &toolChainPath, const Core::Id &language) const;
private: private:
void markKitAsTemporary(Kit *k) const; void markKitAsTemporary(Kit *k) const;
bool findTemporaryHandler(Core::Id id) 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; const Utils::FileName m_projectPath;
mutable bool m_isUpdating = false; mutable bool m_isUpdating = false;