forked from qt-creator/qt-creator
ProjectExplorer: add async toolchain autodetection
Change-Id: I82c6d0b22a9d36674c58561ef654d7ffde8574da Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include "toolchainmanager.h"
|
#include "toolchainmanager.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
#include <utils/async.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
@@ -656,6 +657,12 @@ Id ToolchainFactory::supportedToolchainType() const
|
|||||||
return m_supportedToolchainType;
|
return m_supportedToolchainType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<AsyncToolchainDetector> ToolchainFactory::asyncAutoDetector(
|
||||||
|
const ToolchainDetector &) const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void ToolchainFactory::setSupportedToolchainType(const Id &supportedToolchainType)
|
void ToolchainFactory::setSupportedToolchainType(const Id &supportedToolchainType)
|
||||||
{
|
{
|
||||||
m_supportedToolchainType = supportedToolchainType;
|
m_supportedToolchainType = supportedToolchainType;
|
||||||
@@ -752,4 +759,35 @@ BadToolchains BadToolchains::fromVariant(const QVariant &v)
|
|||||||
[](const QVariant &e) { return BadToolchain::fromMap(storeFromVariant(e)); });
|
[](const QVariant &e) { return BadToolchain::fromMap(storeFromVariant(e)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsyncToolchainDetector::AsyncToolchainDetector(
|
||||||
|
const ToolchainDetector &detector,
|
||||||
|
const std::function<Toolchains(const ToolchainDetector &)> &func,
|
||||||
|
const std::function<bool(const Toolchain *, const Toolchains &)> &alreadyRegistered)
|
||||||
|
: m_detector(detector)
|
||||||
|
, m_func(func)
|
||||||
|
, m_alreadyRegistered(alreadyRegistered)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncToolchainDetector::run()
|
||||||
|
{
|
||||||
|
auto watcher = new QFutureWatcher<Toolchains>();
|
||||||
|
QObject::connect(watcher,
|
||||||
|
&QFutureWatcher<Toolchains>::finished,
|
||||||
|
[watcher,
|
||||||
|
alreadyRegistered = m_alreadyRegistered]() {
|
||||||
|
Toolchains existingTcs = ToolchainManager::toolchains();
|
||||||
|
for (Toolchain *tc : watcher->result()) {
|
||||||
|
if (tc->isValid() && !alreadyRegistered(tc, existingTcs)) {
|
||||||
|
ToolchainManager::registerToolchain(tc);
|
||||||
|
existingTcs << tc;
|
||||||
|
} else {
|
||||||
|
delete tc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
watcher->deleteLater();
|
||||||
|
});
|
||||||
|
watcher->setFuture(Utils::asyncRun(m_func, m_detector));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -241,6 +241,20 @@ public:
|
|||||||
const Utils::FilePaths searchPaths; // If empty use device path and/or magic.
|
const Utils::FilePaths searchPaths; // If empty use device path and/or magic.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PROJECTEXPLORER_EXPORT AsyncToolchainDetector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AsyncToolchainDetector(
|
||||||
|
const ToolchainDetector &detector,
|
||||||
|
const std::function<Toolchains(const ToolchainDetector &)> &func,
|
||||||
|
const std::function<bool(const Toolchain *, const Toolchains &)> &alreadyRegistered);
|
||||||
|
void run();
|
||||||
|
private:
|
||||||
|
ToolchainDetector m_detector;
|
||||||
|
std::function<Toolchains(const ToolchainDetector &)> m_func;
|
||||||
|
std::function<bool(Toolchain *, const Toolchains &)> m_alreadyRegistered;
|
||||||
|
};
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT ToolchainFactory
|
class PROJECTEXPLORER_EXPORT ToolchainFactory
|
||||||
{
|
{
|
||||||
ToolchainFactory(const ToolchainFactory &) = delete;
|
ToolchainFactory(const ToolchainFactory &) = delete;
|
||||||
@@ -255,6 +269,8 @@ public:
|
|||||||
QString displayName() const { return m_displayName; }
|
QString displayName() const { return m_displayName; }
|
||||||
Utils::Id supportedToolchainType() const;
|
Utils::Id supportedToolchainType() const;
|
||||||
|
|
||||||
|
virtual std::optional<AsyncToolchainDetector> asyncAutoDetector(
|
||||||
|
const ToolchainDetector &detector) const;
|
||||||
virtual Toolchains autoDetect(const ToolchainDetector &detector) const;
|
virtual Toolchains autoDetect(const ToolchainDetector &detector) const;
|
||||||
virtual Toolchains detectForImport(const ToolchainDescription &tcd) const;
|
virtual Toolchains detectForImport(const ToolchainDescription &tcd) const;
|
||||||
|
|
||||||
|
@@ -54,16 +54,27 @@ struct ToolChainOperations
|
|||||||
Toolchains toDelete;
|
Toolchains toDelete;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Toolchains autoDetectToolChains(const ToolchainDetector &detector)
|
static Toolchains autoDetectToolchains(const ToolchainDetector &detector)
|
||||||
{
|
{
|
||||||
Toolchains result;
|
Toolchains result;
|
||||||
for (ToolchainFactory *f : ToolchainFactory::allToolchainFactories()) {
|
for (ToolchainFactory *f : ToolchainFactory::allToolchainFactories()) {
|
||||||
NANOTRACE_SCOPE_ARGS("ProjectExplorer",
|
NANOTRACE_SCOPE_ARGS("ProjectExplorer",
|
||||||
"ToolChainSettingsAccessor::autoDetectToolChains",
|
"ToolchainSettingsAccessor::autoDetectToolchains",
|
||||||
{"factory", f->displayName().toStdString()});
|
{"factory", f->displayName().toStdString()});
|
||||||
QElapsedTimer et;
|
QElapsedTimer et;
|
||||||
et.start();
|
et.start();
|
||||||
result.append(f->autoDetect(detector));
|
if (std::optional<AsyncToolchainDetector> asyncDetector = f->asyncAutoDetector(detector)) {
|
||||||
|
Toolchains known = Utils::filtered(detector.alreadyKnown,
|
||||||
|
[supportedType = f->supportedToolchainType()](
|
||||||
|
const Toolchain *tc) {
|
||||||
|
return tc->typeId() == supportedType
|
||||||
|
&& tc->isValid();
|
||||||
|
});
|
||||||
|
result.append(known);
|
||||||
|
asyncDetector->run();
|
||||||
|
} else {
|
||||||
|
result.append(f->autoDetect(detector));
|
||||||
|
}
|
||||||
qCDebug(Log) << f->displayName() << "auto detection took: " << et.elapsed() << "ms";
|
qCDebug(Log) << f->displayName() << "auto detection took: " << et.elapsed() << "ms";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +212,7 @@ Toolchains ToolchainSettingsAccessor::restoreToolChains(QWidget *parent) const
|
|||||||
// Autodect from system paths on the desktop device.
|
// Autodect from system paths on the desktop device.
|
||||||
// The restriction is intentional to keep startup and automatic validation a limited effort
|
// The restriction is intentional to keep startup and automatic validation a limited effort
|
||||||
ToolchainDetector detector(autodetectedUserFileTcs, DeviceManager::defaultDesktopDevice(), {});
|
ToolchainDetector detector(autodetectedUserFileTcs, DeviceManager::defaultDesktopDevice(), {});
|
||||||
const Toolchains autodetectedTcs = autoDetectToolChains(detector);
|
const Toolchains autodetectedTcs = autoDetectToolchains(detector);
|
||||||
|
|
||||||
// merge tool chains and register those that we need to keep:
|
// merge tool chains and register those that we need to keep:
|
||||||
const ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs);
|
const ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs);
|
||||||
|
Reference in New Issue
Block a user