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 "task.h"
|
||||
|
||||
#include <utils/async.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QUuid>
|
||||
@@ -656,6 +657,12 @@ Id ToolchainFactory::supportedToolchainType() const
|
||||
return m_supportedToolchainType;
|
||||
}
|
||||
|
||||
std::optional<AsyncToolchainDetector> ToolchainFactory::asyncAutoDetector(
|
||||
const ToolchainDetector &) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void ToolchainFactory::setSupportedToolchainType(const Id &supportedToolchainType)
|
||||
{
|
||||
m_supportedToolchainType = supportedToolchainType;
|
||||
@@ -752,4 +759,35 @@ BadToolchains BadToolchains::fromVariant(const QVariant &v)
|
||||
[](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
|
||||
|
@@ -241,6 +241,20 @@ public:
|
||||
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
|
||||
{
|
||||
ToolchainFactory(const ToolchainFactory &) = delete;
|
||||
@@ -255,6 +269,8 @@ public:
|
||||
QString displayName() const { return m_displayName; }
|
||||
Utils::Id supportedToolchainType() const;
|
||||
|
||||
virtual std::optional<AsyncToolchainDetector> asyncAutoDetector(
|
||||
const ToolchainDetector &detector) const;
|
||||
virtual Toolchains autoDetect(const ToolchainDetector &detector) const;
|
||||
virtual Toolchains detectForImport(const ToolchainDescription &tcd) const;
|
||||
|
||||
|
@@ -54,16 +54,27 @@ struct ToolChainOperations
|
||||
Toolchains toDelete;
|
||||
};
|
||||
|
||||
static Toolchains autoDetectToolChains(const ToolchainDetector &detector)
|
||||
static Toolchains autoDetectToolchains(const ToolchainDetector &detector)
|
||||
{
|
||||
Toolchains result;
|
||||
for (ToolchainFactory *f : ToolchainFactory::allToolchainFactories()) {
|
||||
NANOTRACE_SCOPE_ARGS("ProjectExplorer",
|
||||
"ToolChainSettingsAccessor::autoDetectToolChains",
|
||||
"ToolchainSettingsAccessor::autoDetectToolchains",
|
||||
{"factory", f->displayName().toStdString()});
|
||||
QElapsedTimer et;
|
||||
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";
|
||||
}
|
||||
|
||||
@@ -201,7 +212,7 @@ Toolchains ToolchainSettingsAccessor::restoreToolChains(QWidget *parent) const
|
||||
// Autodect from system paths on the desktop device.
|
||||
// The restriction is intentional to keep startup and automatic validation a limited effort
|
||||
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:
|
||||
const ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs);
|
||||
|
Reference in New Issue
Block a user