ProjectExplorer: Use a struct for toolchain autodetection parameters

Also, make some functions const and use an alias for QList<ToolChain *>.

Change-Id: I6a1cbcb79bfaa9d252c4b69e00aa93e5d0dabe2f
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2022-01-14 17:29:02 +01:00
parent 3749cfc896
commit 5cfe69b049
24 changed files with 262 additions and 296 deletions

View File

@@ -431,10 +431,8 @@ IarToolChainFactory::IarToolChainFactory()
setUserCreatable(true); setUserCreatable(true);
} }
QList<ToolChain *> IarToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains IarToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
Q_UNUSED(device);
Candidates candidates; Candidates candidates;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@@ -501,23 +499,21 @@ QList<ToolChain *> IarToolChainFactory::autoDetect(const QList<ToolChain *> &alr
#endif // Q_OS_WIN #endif // Q_OS_WIN
return autoDetectToolchains(candidates, alreadyKnown); return autoDetectToolchains(candidates, detector.alreadyKnown);
} }
QList<ProjectExplorer::ToolChain *> IarToolChainFactory::detectForImport( Toolchains IarToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
const ProjectExplorer::ToolChainDescription &tcd)
{ {
return { autoDetectToolchain({tcd.compilerPath, {}}, tcd.language) }; return { autoDetectToolchain({tcd.compilerPath, {}}, tcd.language) };
} }
QList<ToolChain *> IarToolChainFactory::autoDetectToolchains( Toolchains IarToolChainFactory::autoDetectToolchains(
const Candidates &candidates, const QList<ToolChain *> &alreadyKnown) const const Candidates &candidates, const Toolchains &alreadyKnown) const
{ {
QList<ToolChain *> result; Toolchains result;
for (const Candidate &candidate : qAsConst(candidates)) { for (const Candidate &candidate : qAsConst(candidates)) {
const QList<ToolChain *> filtered = Utils::filtered( const Toolchains filtered = Utils::filtered(alreadyKnown, [candidate](ToolChain *tc) {
alreadyKnown, [candidate](ToolChain *tc) {
return tc->typeId() == Constants::IAREW_TOOLCHAIN_TYPEID return tc->typeId() == Constants::IAREW_TOOLCHAIN_TYPEID
&& tc->compilerCommand() == candidate.compilerPath && tc->compilerCommand() == candidate.compilerPath
&& (tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID && (tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID
@@ -537,8 +533,7 @@ QList<ToolChain *> IarToolChainFactory::autoDetectToolchains(
return result; return result;
} }
QList<ToolChain *> IarToolChainFactory::autoDetectToolchain( Toolchains IarToolChainFactory::autoDetectToolchain(const Candidate &candidate, Id languageId) const
const Candidate &candidate, Utils::Id languageId) const
{ {
const auto env = Environment::systemEnvironment(); const auto env = Environment::systemEnvironment();
const Macros macros = dumpPredefinedMacros(candidate.compilerPath, {}, languageId, env); const Macros macros = dumpPredefinedMacros(candidate.compilerPath, {}, languageId, env);

View File

@@ -90,16 +90,15 @@ class IarToolChainFactory final : public ProjectExplorer::ToolChainFactory
public: public:
IarToolChainFactory(); IarToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect( ProjectExplorer::Toolchains autoDetect(
const QList<ProjectExplorer::ToolChain *> &alreadyKnown, const ProjectExplorer::ToolchainDetector &detector) const final;
const ProjectExplorer::IDevice::Ptr &device) final; ProjectExplorer::Toolchains detectForImport(
QList<ProjectExplorer::ToolChain *> detectForImport( const ProjectExplorer::ToolChainDescription &tcd) const final;
const ProjectExplorer::ToolChainDescription &tcd) final;
private: private:
QList<ProjectExplorer::ToolChain *> autoDetectToolchains(const Candidates &candidates, ProjectExplorer::Toolchains autoDetectToolchains(const Candidates &candidates,
const QList<ProjectExplorer::ToolChain *> &alreadyKnown) const; const ProjectExplorer::Toolchains &alreadyKnown) const;
QList<ProjectExplorer::ToolChain *> autoDetectToolchain( ProjectExplorer::Toolchains autoDetectToolchain(
const Candidate &candidate, Utils::Id languageId) const; const Candidate &candidate, Utils::Id languageId) const;
}; };

View File

@@ -601,10 +601,8 @@ static QString extractVersion(const QString &toolsFile, const QString &section)
return {}; return {};
} }
QList<ToolChain *> KeilToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains KeilToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
Q_UNUSED(device)
#ifdef Q_OS_WIN64 #ifdef Q_OS_WIN64
static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\" \ static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\" \
"Windows\\CurrentVersion\\Uninstall\\Keil µVision4"; "Windows\\CurrentVersion\\Uninstall\\Keil µVision4";
@@ -651,16 +649,16 @@ QList<ToolChain *> KeilToolChainFactory::autoDetect(const QList<ToolChain *> &al
registry.endGroup(); registry.endGroup();
} }
return autoDetectToolchains(candidates, alreadyKnown); return autoDetectToolchains(candidates, detector.alreadyKnown);
} }
QList<ToolChain *> KeilToolChainFactory::autoDetectToolchains( Toolchains KeilToolChainFactory::autoDetectToolchains(
const Candidates &candidates, const QList<ToolChain *> &alreadyKnown) const const Candidates &candidates, const Toolchains &alreadyKnown) const
{ {
QList<ToolChain *> result; Toolchains result;
for (const Candidate &candidate : qAsConst(candidates)) { for (const Candidate &candidate : qAsConst(candidates)) {
const QList<ToolChain *> filtered = Utils::filtered( const Toolchains filtered = Utils::filtered(
alreadyKnown, [candidate](ToolChain *tc) { alreadyKnown, [candidate](ToolChain *tc) {
return tc->typeId() == Constants::IAREW_TOOLCHAIN_TYPEID return tc->typeId() == Constants::IAREW_TOOLCHAIN_TYPEID
&& tc->compilerCommand() == candidate.compilerPath && tc->compilerCommand() == candidate.compilerPath
@@ -681,8 +679,7 @@ QList<ToolChain *> KeilToolChainFactory::autoDetectToolchains(
return result; return result;
} }
QList<ToolChain *> KeilToolChainFactory::autoDetectToolchain( Toolchains KeilToolChainFactory::autoDetectToolchain(const Candidate &candidate, Id language) const
const Candidate &candidate, Utils::Id language) const
{ {
const auto env = Environment::systemEnvironment(); const auto env = Environment::systemEnvironment();

View File

@@ -91,14 +91,13 @@ class KeilToolChainFactory final : public ProjectExplorer::ToolChainFactory
public: public:
KeilToolChainFactory(); KeilToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect( ProjectExplorer::Toolchains autoDetect(
const QList<ProjectExplorer::ToolChain *> &alreadyKnown, const ProjectExplorer::ToolchainDetector &detector) const final;
const ProjectExplorer::IDevice::Ptr &device) final;
private: private:
QList<ProjectExplorer::ToolChain *> autoDetectToolchains(const Candidates &candidates, ProjectExplorer::Toolchains autoDetectToolchains(const Candidates &candidates,
const QList<ProjectExplorer::ToolChain *> &alreadyKnown) const; const ProjectExplorer::Toolchains &alreadyKnown) const;
QList<ProjectExplorer::ToolChain *> autoDetectToolchain( ProjectExplorer::Toolchains autoDetectToolchain(
const Candidate &candidate, Utils::Id language) const; const Candidate &candidate, Utils::Id language) const;
}; };

View File

@@ -306,10 +306,8 @@ SdccToolChainFactory::SdccToolChainFactory()
setUserCreatable(true); setUserCreatable(true);
} }
QList<ToolChain *> SdccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains SdccToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
Q_UNUSED(device)
Candidates candidates; Candidates candidates;
if (Utils::HostOsInfo::isWindowsHost()) { if (Utils::HostOsInfo::isWindowsHost()) {
@@ -362,17 +360,16 @@ QList<ToolChain *> SdccToolChainFactory::autoDetect(const QList<ToolChain *> &al
candidates.push_back(candidate); candidates.push_back(candidate);
} }
return autoDetectToolchains(candidates, alreadyKnown); return autoDetectToolchains(candidates, detector.alreadyKnown);
} }
QList<ToolChain *> SdccToolChainFactory::autoDetectToolchains( Toolchains SdccToolChainFactory::autoDetectToolchains(
const Candidates &candidates, const QList<ToolChain *> &alreadyKnown) const const Candidates &candidates, const Toolchains &alreadyKnown) const
{ {
QList<ToolChain *> result; Toolchains result;
for (const Candidate &candidate : qAsConst(candidates)) { for (const Candidate &candidate : qAsConst(candidates)) {
const QList<ToolChain *> filtered = Utils::filtered( const Toolchains filtered = Utils::filtered(alreadyKnown, [candidate](ToolChain *tc) {
alreadyKnown, [candidate](ToolChain *tc) {
return tc->typeId() == Constants::SDCC_TOOLCHAIN_TYPEID return tc->typeId() == Constants::SDCC_TOOLCHAIN_TYPEID
&& tc->compilerCommand() == candidate.compilerPath && tc->compilerCommand() == candidate.compilerPath
&& (tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID); && (tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID);
@@ -390,8 +387,7 @@ QList<ToolChain *> SdccToolChainFactory::autoDetectToolchains(
return result; return result;
} }
QList<ToolChain *> SdccToolChainFactory::autoDetectToolchain( Toolchains SdccToolChainFactory::autoDetectToolchain(const Candidate &candidate, Id language) const
const Candidate &candidate, Utils::Id language) const
{ {
const auto env = Environment::systemEnvironment(); const auto env = Environment::systemEnvironment();
@@ -401,7 +397,7 @@ QList<ToolChain *> SdccToolChainFactory::autoDetectToolchain(
{Abi::Stm8Architecture} {Abi::Stm8Architecture}
}; };
QList<ToolChain *> tcs; Toolchains tcs;
// Probe each ABI from the table, because the SDCC compiler // Probe each ABI from the table, because the SDCC compiler
// can be compiled with or without the specified architecture. // can be compiled with or without the specified architecture.

View File

@@ -82,14 +82,13 @@ class SdccToolChainFactory final : public ProjectExplorer::ToolChainFactory
public: public:
SdccToolChainFactory(); SdccToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect( ProjectExplorer::Toolchains autoDetect(
const QList<ProjectExplorer::ToolChain *> &alreadyKnown, const ProjectExplorer::ToolchainDetector &detector) const final;
const ProjectExplorer::IDevice::Ptr &device) final;
private: private:
QList<ProjectExplorer::ToolChain *> autoDetectToolchains(const Candidates &candidates, ProjectExplorer::Toolchains autoDetectToolchains(const Candidates &candidates,
const QList<ProjectExplorer::ToolChain *> &alreadyKnown) const; const ProjectExplorer::Toolchains &alreadyKnown) const;
QList<ProjectExplorer::ToolChain *> autoDetectToolchain( ProjectExplorer::Toolchains autoDetectToolchain(
const Candidate &candidate, Utils::Id language) const; const Candidate &candidate, Utils::Id language) const;
}; };

View File

@@ -729,17 +729,18 @@ QList<BaseQtVersion *> KitDetectorPrivate::autoDetectQtVersions() const
return qtVersions; return qtVersions;
} }
QList<ToolChain *> KitDetectorPrivate::autoDetectToolChains() Toolchains KitDetectorPrivate::autoDetectToolChains()
{ {
const QList<ToolChainFactory *> factories = ToolChainFactory::allToolChainFactories(); const QList<ToolChainFactory *> factories = ToolChainFactory::allToolChainFactories();
QList<ToolChain *> alreadyKnown = ToolChainManager::toolChains(); Toolchains alreadyKnown = ToolChainManager::toolChains();
QList<ToolChain *> allNewToolChains; Toolchains allNewToolChains;
QApplication::processEvents(); QApplication::processEvents();
emit q->logOutput('\n' + tr("Searching toolchains...")); emit q->logOutput('\n' + tr("Searching toolchains..."));
for (ToolChainFactory *factory : factories) { for (ToolChainFactory *factory : factories) {
emit q->logOutput(tr("Searching toolchains of type %1").arg(factory->displayName())); emit q->logOutput(tr("Searching toolchains of type %1").arg(factory->displayName()));
const QList<ToolChain *> newToolChains = factory->autoDetect(alreadyKnown, m_device.constCast<IDevice>()); const ToolchainDetector detector(alreadyKnown, m_device);
const Toolchains newToolChains = factory->autoDetect(detector);
for (ToolChain *toolChain : newToolChains) { for (ToolChain *toolChain : newToolChains) {
emit q->logOutput(tr("Found \"%1\"").arg(toolChain->compilerCommand().toUserOutput())); emit q->logOutput(tr("Found \"%1\"").arg(toolChain->compilerCommand().toUserOutput()));
toolChain->setDetectionSource(m_sharedId); toolChain->setDetectionSource(m_sharedId);

View File

@@ -588,13 +588,11 @@ IosToolChainFactory::IosToolChainFactory()
ProjectExplorer::Constants::CXX_LANGUAGE_ID}); ProjectExplorer::Constants::CXX_LANGUAGE_ID});
} }
QList<ToolChain *> IosToolChainFactory::autoDetect(const QList<ToolChain *> &existingToolChains, Toolchains IosToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
Q_UNUSED(device); QList<ClangToolChain *> existingClangToolChains = clangToolChains(detector.alreadyKnown);
QList<ClangToolChain *> existingClangToolChains = clangToolChains(existingToolChains);
const QList<XcodePlatform> platforms = XcodeProbe::detectPlatforms().values(); const QList<XcodePlatform> platforms = XcodeProbe::detectPlatforms().values();
QList<ToolChain *> toolChains; Toolchains toolChains;
toolChains.reserve(platforms.size()); toolChains.reserve(platforms.size());
for (const XcodePlatform &platform : platforms) { for (const XcodePlatform &platform : platforms) {
for (const XcodePlatform::ToolchainTarget &target : platform.targets) { for (const XcodePlatform::ToolchainTarget &target : platform.targets) {

View File

@@ -98,9 +98,8 @@ class IosToolChainFactory : public ProjectExplorer::ToolChainFactory
public: public:
IosToolChainFactory(); IosToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect( ProjectExplorer::Toolchains autoDetect(
const QList<ProjectExplorer::ToolChain *> &existingToolChains, const ProjectExplorer::ToolchainDetector &detector) const final;
const ProjectExplorer::IDevice::Ptr &device) override;
}; };
class IosConfigurations : public QObject class IosConfigurations : public QObject

View File

@@ -439,7 +439,7 @@ static ToolChain *iarToolChain(const FilePath &path, Id language)
return f->supportedToolChainType() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID; return f->supportedToolChainType() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
}); });
if (iarFactory) { if (iarFactory) {
QList<ToolChain*> detected = iarFactory->autoDetect({}, {}); Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
if (detected.isEmpty()) if (detected.isEmpty())
detected = iarFactory->detectForImport({path, language}); detected = iarFactory->detectForImport({path, language});
for (auto tc: detected) { for (auto tc: detected) {

View File

@@ -51,17 +51,18 @@ NimToolChainFactory::NimToolChainFactory()
setUserCreatable(true); setUserCreatable(true);
} }
QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains NimToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
QList<ToolChain *> result; Toolchains result;
IDevice::ConstPtr dev =
detector.device ? detector.device : DeviceManager::defaultDesktopDevice();
IDevice::ConstPtr dev = device ? device : DeviceManager::defaultDesktopDevice();
const FilePath compilerPath = dev->searchExecutableInPath("nim"); const FilePath compilerPath = dev->searchExecutableInPath("nim");
if (compilerPath.isEmpty()) if (compilerPath.isEmpty())
return result; return result;
result = Utils::filtered(alreadyKnown, [compilerPath](ToolChain *tc) { result = Utils::filtered(detector.alreadyKnown, [compilerPath](ToolChain *tc) {
return tc->typeId() == Constants::C_NIMTOOLCHAIN_TYPEID return tc->typeId() == Constants::C_NIMTOOLCHAIN_TYPEID
&& tc->compilerCommand() == compilerPath; && tc->compilerCommand() == compilerPath;
}); });
@@ -76,9 +77,9 @@ QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alr
return result; return result;
} }
QList<ToolChain *> NimToolChainFactory::detectForImport(const ToolChainDescription &tcd) Toolchains NimToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
{ {
QList<ToolChain *> result; Toolchains result;
if (tcd.language == Constants::C_NIMLANGUAGE_ID) { if (tcd.language == Constants::C_NIMLANGUAGE_ID) {
auto tc = new NimToolChain; auto tc = new NimToolChain;
tc->setDetection(ToolChain::ManualDetection); // FIXME: sure? tc->setDetection(ToolChain::ManualDetection); // FIXME: sure?

View File

@@ -39,9 +39,8 @@ class NimToolChainFactory : public ProjectExplorer::ToolChainFactory
public: public:
NimToolChainFactory(); NimToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect(const QList<ProjectExplorer::ToolChain *> &alreadyKnown, ProjectExplorer::Toolchains autoDetect(const ProjectExplorer::ToolchainDetector &detector) const final;
const ProjectExplorer::IDevice::Ptr &device) final; ProjectExplorer::Toolchains detectForImport(const ProjectExplorer::ToolChainDescription &tcd) const final;
QList<ProjectExplorer::ToolChain *> detectForImport(const ProjectExplorer::ToolChainDescription &tcd) final;
}; };
class NimToolChainConfigWidget : public ProjectExplorer::ToolChainConfigWidget class NimToolChainConfigWidget : public ProjectExplorer::ToolChainConfigWidget

View File

@@ -997,28 +997,25 @@ GccToolChainFactory::GccToolChainFactory()
setUserCreatable(true); setUserCreatable(true);
} }
QList<ToolChain *> GccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
// GCC is almost never what you want on macOS, but it is by default found in /usr/bin // GCC is almost never what you want on macOS, but it is by default found in /usr/bin
if (HostOsInfo::isMacHost()) if (HostOsInfo::isMacHost())
return {}; return {};
QList<ToolChain *> tcs; Toolchains tcs;
static const auto tcChecker = [](const ToolChain *tc) { static const auto tcChecker = [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor
&& tc->compilerCommand().fileName() != "c89-gcc" && tc->compilerCommand().fileName() != "c89-gcc"
&& tc->compilerCommand().fileName() != "c99-gcc"; && tc->compilerCommand().fileName() != "c99-gcc";
}; };
tcs.append(autoDetectToolchains("g++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID, tcs.append(autoDetectToolchains("g++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID,
Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown, Constants::GCC_TOOLCHAIN_TYPEID, detector, tcChecker));
device, tcChecker));
tcs.append(autoDetectToolchains("gcc", DetectVariants::Yes, Constants::C_LANGUAGE_ID, tcs.append(autoDetectToolchains("gcc", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown, Constants::GCC_TOOLCHAIN_TYPEID, detector, tcChecker));
device, tcChecker));
return tcs; return tcs;
} }
QList<ToolChain *> GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
{ {
const QString fileName = tcd.compilerPath.completeBaseName(); const QString fileName = tcd.compilerPath.completeBaseName();
if ((tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc") if ((tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc")
@@ -1030,11 +1027,10 @@ QList<ToolChain *> GccToolChainFactory::detectForImport(const ToolChainDescripti
return autoDetectToolChain(tcd, [](const ToolChain *tc) { return autoDetectToolChain(tcd, [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor; return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor;
}); });
return QList<ToolChain *>(); return {};
} }
static FilePaths findCompilerCandidates(const IDevice::ConstPtr &device,
static FilePaths findCompilerCandidates(const IDevice::Ptr &device,
const QString &compilerName, const QString &compilerName,
bool detectVariants) bool detectVariants)
{ {
@@ -1106,20 +1102,19 @@ static FilePaths findCompilerCandidates(const IDevice::Ptr &device,
return compilerPaths; return compilerPaths;
} }
QList<ToolChain *> GccToolChainFactory::autoDetectToolchains( Toolchains GccToolChainFactory::autoDetectToolchains(
const QString &compilerName, const QString &compilerName,
DetectVariants detectVariants, DetectVariants detectVariants,
const Id language, const Id language,
const Id requiredTypeId, const Id requiredTypeId,
const QList<ToolChain *> &alreadyKnown, const ToolchainDetector &detector,
const IDevice::Ptr &device, const ToolchainChecker &checker) const
const ToolchainChecker &checker)
{ {
const FilePaths compilerPaths = const FilePaths compilerPaths =
findCompilerCandidates(device, compilerName, detectVariants == DetectVariants::Yes); findCompilerCandidates(detector.device, compilerName, detectVariants == DetectVariants::Yes);
QList<ToolChain *> existingCandidates Toolchains existingCandidates
= filtered(alreadyKnown, [requiredTypeId, language, &checker](const ToolChain *tc) { = filtered(detector.alreadyKnown, [requiredTypeId, language, &checker](const ToolChain *tc) {
if (tc->typeId() != requiredTypeId) if (tc->typeId() != requiredTypeId)
return false; return false;
if (tc->language() != language) if (tc->language() != language)
@@ -1128,7 +1123,8 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(
return false; return false;
return true; return true;
}); });
QList<ToolChain *> result;
Toolchains result;
for (const FilePath &compilerPath : qAsConst(compilerPaths)) { for (const FilePath &compilerPath : qAsConst(compilerPaths)) {
bool alreadyExists = false; bool alreadyExists = false;
for (ToolChain * const existingTc : existingCandidates) { for (ToolChain * const existingTc : existingCandidates) {
@@ -1168,10 +1164,10 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(
return result; return result;
} }
QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const ToolChainDescription &tcd, Toolchains GccToolChainFactory::autoDetectToolChain(const ToolChainDescription &tcd,
const ToolchainChecker &checker) const ToolchainChecker &checker) const
{ {
QList<ToolChain *> result; Toolchains result;
Environment systemEnvironment = Environment::systemEnvironment(); Environment systemEnvironment = Environment::systemEnvironment();
GccToolChain::addCommandPathToEnvironment(tcd.compilerPath, systemEnvironment); GccToolChain::addCommandPathToEnvironment(tcd.compilerPath, systemEnvironment);
@@ -1626,16 +1622,15 @@ ClangToolChainFactory::ClangToolChainFactory()
setToolchainConstructor([] { return new ClangToolChain; }); setToolchainConstructor([] { return new ClangToolChain; });
} }
QList<ToolChain *> ClangToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains ClangToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
QList<ToolChain *> tcs; Toolchains tcs;
QList<ToolChain *> known = alreadyKnown; Toolchains known = detector.alreadyKnown;
tcs.append(autoDetectToolchains("clang++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID, tcs.append(autoDetectToolchains("clang++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID,
Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown, device)); Constants::CLANG_TOOLCHAIN_TYPEID, detector));
tcs.append(autoDetectToolchains("clang", DetectVariants::Yes, Constants::C_LANGUAGE_ID, tcs.append(autoDetectToolchains("clang", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown, device)); Constants::CLANG_TOOLCHAIN_TYPEID, detector));
known.append(tcs); known.append(tcs);
const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR); const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR);
@@ -1643,13 +1638,13 @@ QList<ToolChain *> ClangToolChainFactory::autoDetect(const QList<ToolChain *> &a
const FilePath clang = compilerPath.parentDir().pathAppended("clang").withExecutableSuffix(); const FilePath clang = compilerPath.parentDir().pathAppended("clang").withExecutableSuffix();
tcs.append(autoDetectToolchains(clang.toString(), DetectVariants::No, tcs.append(autoDetectToolchains(clang.toString(), DetectVariants::No,
Constants::C_LANGUAGE_ID, Constants::CLANG_TOOLCHAIN_TYPEID, Constants::C_LANGUAGE_ID, Constants::CLANG_TOOLCHAIN_TYPEID,
tcs, device)); ToolchainDetector(tcs, detector.device)));
} }
return tcs; return tcs;
} }
QList<ToolChain *> ClangToolChainFactory::detectForImport(const ToolChainDescription &tcd) Toolchains ClangToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
{ {
const QString fileName = tcd.compilerPath.toString(); const QString fileName = tcd.compilerPath.toString();
if ((tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("clang") && !fileName.startsWith("clang++")) if ((tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("clang") && !fileName.startsWith("clang++"))
@@ -1814,21 +1809,20 @@ MingwToolChainFactory::MingwToolChainFactory()
setToolchainConstructor([] { return new MingwToolChain; }); setToolchainConstructor([] { return new MingwToolChain; });
} }
QList<ToolChain *> MingwToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains MingwToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
static const auto tcChecker = [](const ToolChain *tc) { static const auto tcChecker = [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor; return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor;
}; };
QList<ToolChain *> result = autoDetectToolchains( Toolchains result = autoDetectToolchains(
"g++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID, "g++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID,
Constants::MINGW_TOOLCHAIN_TYPEID, alreadyKnown, device, tcChecker); Constants::MINGW_TOOLCHAIN_TYPEID, detector, tcChecker);
result += autoDetectToolchains("gcc", DetectVariants::Yes, Constants::C_LANGUAGE_ID, result += autoDetectToolchains("gcc", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
Constants::MINGW_TOOLCHAIN_TYPEID, alreadyKnown, device, tcChecker); Constants::MINGW_TOOLCHAIN_TYPEID, detector, tcChecker);
return result; return result;
} }
QList<ToolChain *> MingwToolChainFactory::detectForImport(const ToolChainDescription &tcd) Toolchains MingwToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
{ {
const QString fileName = tcd.compilerPath.completeBaseName(); const QString fileName = tcd.compilerPath.completeBaseName();
if ((tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc") if ((tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc")
@@ -1896,18 +1890,17 @@ LinuxIccToolChainFactory::LinuxIccToolChainFactory()
setToolchainConstructor([] { return new LinuxIccToolChain; }); setToolchainConstructor([] { return new LinuxIccToolChain; });
} }
QList<ToolChain *> LinuxIccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains LinuxIccToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
QList<ToolChain *> result Toolchains result
= autoDetectToolchains("icpc", DetectVariants::No, Constants::CXX_LANGUAGE_ID, = autoDetectToolchains("icpc", DetectVariants::No, Constants::CXX_LANGUAGE_ID,
Constants::LINUXICC_TOOLCHAIN_TYPEID, alreadyKnown, device); Constants::LINUXICC_TOOLCHAIN_TYPEID, detector);
result += autoDetectToolchains("icc", DetectVariants::Yes, Constants::C_LANGUAGE_ID, result += autoDetectToolchains("icc", DetectVariants::Yes, Constants::C_LANGUAGE_ID,
Constants::LINUXICC_TOOLCHAIN_TYPEID, alreadyKnown, device); Constants::LINUXICC_TOOLCHAIN_TYPEID, detector);
return result; return result;
} }
QList<ToolChain *> LinuxIccToolChainFactory::detectForImport(const ToolChainDescription &tcd) Toolchains LinuxIccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
{ {
const QString fileName = tcd.compilerPath.toString(); const QString fileName = tcd.compilerPath.toString();
if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) || if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) ||

View File

@@ -52,21 +52,19 @@ class GccToolChainFactory : public ToolChainFactory
public: public:
GccToolChainFactory(); GccToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains autoDetect(const ToolchainDetector &detector) const override;
const IDevice::Ptr &device) override; Toolchains detectForImport(const ToolChainDescription &tcd) const override;
QList<ToolChain *> detectForImport(const ToolChainDescription &tcd) override;
protected: protected:
enum class DetectVariants { Yes, No }; enum class DetectVariants { Yes, No };
using ToolchainChecker = std::function<bool(const ToolChain *)>; using ToolchainChecker = std::function<bool(const ToolChain *)>;
QList<ToolChain *> autoDetectToolchains( Toolchains autoDetectToolchains(
const QString &compilerName, DetectVariants detectVariants, const Utils::Id language, const QString &compilerName, DetectVariants detectVariants, const Utils::Id language,
const Utils::Id requiredTypeId, const QList<ToolChain *> &alreadyKnown, const Utils::Id requiredTypeId, const ToolchainDetector &detector,
const ProjectExplorer::IDevice::Ptr &device, const ToolchainChecker &checker = {}) const;
const ToolchainChecker &checker = {}); Toolchains autoDetectToolChain(
QList<ToolChain *> autoDetectToolChain(
const ToolChainDescription &tcd, const ToolChainDescription &tcd,
const ToolchainChecker &checker = {}); const ToolchainChecker &checker = {}) const;
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -134,9 +132,8 @@ class ClangToolChainFactory : public GccToolChainFactory
public: public:
ClangToolChainFactory(); ClangToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains autoDetect(const ToolchainDetector &detector) const final;
const IDevice::Ptr &device) override; Toolchains detectForImport(const ToolChainDescription &tcd) const final;
QList<ToolChain *> detectForImport(const ToolChainDescription &tcd) final;
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -148,9 +145,8 @@ class MingwToolChainFactory : public GccToolChainFactory
public: public:
MingwToolChainFactory(); MingwToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains autoDetect(const ToolchainDetector &detector) const final;
const IDevice::Ptr &device) override; Toolchains detectForImport(const ToolChainDescription &tcd) const final;
QList<ToolChain *> detectForImport(const ToolChainDescription &tcd) final;
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -162,8 +158,8 @@ class LinuxIccToolChainFactory : public GccToolChainFactory
public: public:
LinuxIccToolChainFactory(); LinuxIccToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown, const IDevice::Ptr &) override; Toolchains autoDetect(const ToolchainDetector &detector) const final;
QList<ToolChain *> detectForImport(const ToolChainDescription &tcd) final; Toolchains detectForImport(const ToolChainDescription &tcd) const final;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -1586,12 +1586,12 @@ static const MsvcToolChain *selectMsvcToolChain(const QString &displayedVarsBat,
return toolChain; return toolChain;
} }
static QList<ToolChain *> detectClangClToolChainInPath(const FilePath &clangClPath, static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath,
const QList<ToolChain *> &alreadyKnown, const Toolchains &alreadyKnown,
const QString &displayedVarsBat, const QString &displayedVarsBat,
bool isDefault = false) bool isDefault = false)
{ {
QList<ToolChain *> res; Toolchains res;
const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32; const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32;
const MsvcToolChain *toolChain = selectMsvcToolChain(displayedVarsBat, clangClPath, wordWidth); const MsvcToolChain *toolChain = selectMsvcToolChain(displayedVarsBat, clangClPath, wordWidth);
@@ -1647,9 +1647,7 @@ void ClangClToolChainConfigWidget::applyImpl()
} }
const QString displayedVarsBat = m_varsBatDisplayCombo->currentText(); const QString displayedVarsBat = m_varsBatDisplayCombo->currentText();
QList<ToolChain *> results = detectClangClToolChainInPath(clangClPath, Toolchains results = detectClangClToolChainInPath(clangClPath, {}, displayedVarsBat);
{},
displayedVarsBat);
if (results.isEmpty()) { if (results.isEmpty()) {
clangClToolChain->resetVarsBat(); clangClToolChain->resetVarsBat();
@@ -1831,14 +1829,15 @@ QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath,
return result; return result;
} }
static QList<ToolChain *> findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown, const QString &name, static Toolchains findOrCreateToolchains(const ToolchainDetector &detector,
const QString &name,
const Abi &abi, const Abi &abi,
const QString &varsBat, const QString &varsBat,
const QString &varsBatArg) const QString &varsBatArg)
{ {
QList<ToolChain *> res; Toolchains res;
for (auto language : {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) { for (auto language : {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) {
ToolChain *tc = Utils::findOrDefault(alreadyKnown, [&](ToolChain *tc) -> bool { ToolChain *tc = Utils::findOrDefault(detector.alreadyKnown, [&](ToolChain *tc) -> bool {
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID) if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
return false; return false;
if (tc->targetAbi() != abi) if (tc->targetAbi() != abi)
@@ -1862,7 +1861,7 @@ static QList<ToolChain *> findOrCreateToolChain(const QList<ToolChain *> &alread
} }
// Detect build tools introduced with MSVC2015 // Detect build tools introduced with MSVC2015
static void detectCppBuildTools2015(QList<ToolChain *> *list) static void detectCppBuildTools2015(Toolchains *list)
{ {
struct Entry struct Entry
{ {
@@ -1901,15 +1900,14 @@ static void detectCppBuildTools2015(QList<ToolChain *> *list)
} }
} }
QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains MsvcToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
if (!device.isNull()) { if (!detector.device.isNull()) {
// FIXME currently no support for msvc toolchains on a device // FIXME currently no support for msvc toolchains on a device
return {}; return {};
} }
QList<ToolChain *> results; Toolchains results;
// 1) Installed SDKs preferred over standalone Visual studio // 1) Installed SDKs preferred over standalone Visual studio
const QSettings const QSettings
@@ -1940,7 +1938,7 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
{MsvcToolChain::ia64, "ia64"}, {MsvcToolChain::ia64, "ia64"},
}; };
for (const auto &platform : platforms) { for (const auto &platform : platforms) {
tmp.append(findOrCreateToolChain(alreadyKnown, tmp.append(findOrCreateToolchains(detector.alreadyKnown,
generateDisplayName(name, generateDisplayName(name,
MsvcToolChain::WindowsSDK, MsvcToolChain::WindowsSDK,
platform.first), platform.first),
@@ -1981,7 +1979,7 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
= QFileInfo(vcVarsBatFor(i.vcVarsPath, platform, i.version)).isFile(); = QFileInfo(vcVarsBatFor(i.vcVarsPath, platform, i.version)).isFile();
if (hostSupportsPlatform(platform) && toolchainInstalled) { if (hostSupportsPlatform(platform) && toolchainInstalled) {
results.append( results.append(
findOrCreateToolChain(alreadyKnown, findOrCreateToolchains(detector.alreadyKnown,
generateDisplayName(i.vsName, MsvcToolChain::VS, platform), generateDisplayName(i.vsName, MsvcToolChain::VS, platform),
findAbiOfMsvc(MsvcToolChain::VS, platform, i.vsName), findAbiOfMsvc(MsvcToolChain::VS, platform, i.vsName),
i.vcVarsAll, i.vcVarsAll,
@@ -2011,11 +2009,9 @@ bool ClangClToolChainFactory::canCreate() const
return !g_availableMsvcToolchains.isEmpty(); return !g_availableMsvcToolchains.isEmpty();
} }
QList<ToolChain *> ClangClToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains ClangClToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
Q_UNUSED(alreadyKnown) if (!detector.device.isNull()) {
if (!device.isNull()) {
// FIXME currently no support for msvc toolchains on a device // FIXME currently no support for msvc toolchains on a device
return {}; return {};
} }
@@ -2025,14 +2021,14 @@ QList<ToolChain *> ClangClToolChainFactory::autoDetect(const QList<ToolChain *>
const char registryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\LLVM\\LLVM"; const char registryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\LLVM\\LLVM";
#endif #endif
QList<ToolChain *> results; Toolchains results;
QList<ToolChain *> known = alreadyKnown; Toolchains known = detector.alreadyKnown;
FilePath qtCreatorsClang = Core::ICore::clangExecutable(CLANG_BINDIR); FilePath qtCreatorsClang = Core::ICore::clangExecutable(CLANG_BINDIR);
if (!qtCreatorsClang.isEmpty()) { if (!qtCreatorsClang.isEmpty()) {
qtCreatorsClang = qtCreatorsClang.parentDir().pathAppended("clang-cl.exe"); qtCreatorsClang = qtCreatorsClang.parentDir().pathAppended("clang-cl.exe");
results.append(detectClangClToolChainInPath(qtCreatorsClang, results.append(detectClangClToolChainInPath(qtCreatorsClang,
alreadyKnown, "", true)); detector.alreadyKnown, "", true));
known.append(results); known.append(results);
} }

View File

@@ -204,10 +204,9 @@ class MsvcToolChainFactory : public ToolChainFactory
public: public:
MsvcToolChainFactory(); MsvcToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains autoDetect(const ToolchainDetector &detector) const final;
const IDevice::Ptr &device) override;
bool canCreate() const override; bool canCreate() const final;
static QString vcVarsBatFor(const QString &basePath, static QString vcVarsBatFor(const QString &basePath,
MsvcToolChain::Platform platform, MsvcToolChain::Platform platform,
@@ -219,10 +218,9 @@ class ClangClToolChainFactory : public ToolChainFactory
public: public:
ClangClToolChainFactory(); ClangClToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains autoDetect(const ToolchainDetector &detector) const final;
const IDevice::Ptr &device) override;
bool canCreate() const override; bool canCreate() const final;
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View File

@@ -539,15 +539,13 @@ const QList<ToolChainFactory *> ToolChainFactory::allToolChainFactories()
return Internal::g_toolChainFactories; return Internal::g_toolChainFactories;
} }
QList<ToolChain *> ToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, Toolchains ToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const IDevice::Ptr &device)
{ {
Q_UNUSED(alreadyKnown) Q_UNUSED(detector)
Q_UNUSED(device)
return {}; return {};
} }
QList<ToolChain *> ToolChainFactory::detectForImport(const ToolChainDescription &tcd) Toolchains ToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
{ {
Q_UNUSED(tcd) Q_UNUSED(tcd)
return {}; return {};
@@ -558,7 +556,7 @@ bool ToolChainFactory::canCreate() const
return m_userCreatable; return m_userCreatable;
} }
ToolChain *ToolChainFactory::create() ToolChain *ToolChainFactory::create() const
{ {
return m_toolchainConstructor ? m_toolchainConstructor() : nullptr; return m_toolchainConstructor ? m_toolchainConstructor() : nullptr;
} }
@@ -650,4 +648,8 @@ void ToolChainFactory::setUserCreatable(bool userCreatable)
m_userCreatable = userCreatable; m_userCreatable = userCreatable;
} }
ToolchainDetector::ToolchainDetector(const Toolchains &alreadyKnown, const IDevice::ConstPtr &device)
: alreadyKnown(alreadyKnown), device(device)
{}
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -212,6 +212,17 @@ private:
friend class ToolChainFactory; friend class ToolChainFactory;
}; };
using Toolchains = QList<ToolChain *>;
class PROJECTEXPLORER_EXPORT ToolchainDetector
{
public:
ToolchainDetector(const Toolchains &alreadyKnown = {}, const IDevice::ConstPtr &device = {});
const Toolchains alreadyKnown;
const IDevice::ConstPtr device;
};
class PROJECTEXPLORER_EXPORT ToolChainFactory class PROJECTEXPLORER_EXPORT ToolChainFactory
{ {
ToolChainFactory(const ToolChainFactory &) = delete; ToolChainFactory(const ToolChainFactory &) = delete;
@@ -226,12 +237,11 @@ public:
QString displayName() const { return m_displayName; } QString displayName() const { return m_displayName; }
Utils::Id supportedToolChainType() const; Utils::Id supportedToolChainType() const;
virtual QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown, virtual Toolchains autoDetect(const ToolchainDetector &detector) const;
const IDevice::Ptr &device); virtual Toolchains detectForImport(const ToolChainDescription &tcd) const;
virtual QList<ToolChain *> detectForImport(const ToolChainDescription &tcd);
virtual bool canCreate() const; virtual bool canCreate() const;
virtual ToolChain *create(); virtual ToolChain *create() const;
ToolChain *restore(const QVariantMap &data); ToolChain *restore(const QVariantMap &data);

View File

@@ -398,7 +398,7 @@ StaticTreeItem *ToolChainOptionsWidget::parentForToolChain(ToolChain *tc)
void ToolChainOptionsWidget::redetectToolchains() void ToolChainOptionsWidget::redetectToolchains()
{ {
QList<ToolChainTreeItem *> itemsToRemove; QList<ToolChainTreeItem *> itemsToRemove;
QList<ToolChain *> knownTcs; Toolchains knownTcs;
m_model.forAllItems([&itemsToRemove, &knownTcs](TreeItem *item) { m_model.forAllItems([&itemsToRemove, &knownTcs](TreeItem *item) {
if (item->level() != 3) if (item->level() != 3)
return; return;
@@ -410,10 +410,11 @@ void ToolChainOptionsWidget::redetectToolchains()
knownTcs << tcItem->toolChain; knownTcs << tcItem->toolChain;
} }
}); });
QList<ToolChain *> toAdd; Toolchains toAdd;
QSet<ToolChain *> toDelete; QSet<ToolChain *> toDelete;
for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) { for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) {
for (ToolChain * const tc : f->autoDetect(knownTcs, {})) { // FIXME: Pass device. const ToolchainDetector detector(knownTcs, {}); // FIXME: Pass device.
for (ToolChain * const tc : f->autoDetect(detector)) {
if (knownTcs.contains(tc) || toDelete.contains(tc)) if (knownTcs.contains(tc) || toDelete.contains(tc))
continue; continue;
const auto matchItem = [tc](const ToolChainTreeItem *item) { const auto matchItem = [tc](const ToolChainTreeItem *item) {

View File

@@ -62,25 +62,24 @@ static const char TOOLCHAIN_FILENAME[] = "toolchains.xml";
struct ToolChainOperations struct ToolChainOperations
{ {
QList<ToolChain *> toDemote; Toolchains toDemote;
QList<ToolChain *> toRegister; Toolchains toRegister;
QList<ToolChain *> toDelete; Toolchains toDelete;
}; };
static QList<ToolChain *> autoDetectToolChains(const QList<ToolChain *> alreadyKnownTcs, static Toolchains autoDetectToolChains(const ToolchainDetector &detector)
const IDevice::Ptr &device)
{ {
QList<ToolChain *> result; Toolchains result;
for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories())
result.append(f->autoDetect(alreadyKnownTcs, device)); result.append(f->autoDetect(detector));
// Remove invalid toolchains that might have sneaked in. // Remove invalid toolchains that might have sneaked in.
return Utils::filtered(result, [](const ToolChain *tc) { return tc->isValid(); }); return Utils::filtered(result, [](const ToolChain *tc) { return tc->isValid(); });
} }
static QList<ToolChain *> makeUniqueByEqual(const QList<ToolChain *> &a) static Toolchains makeUniqueByEqual(const Toolchains &a)
{ {
QList<ToolChain *> result; Toolchains result;
foreach (ToolChain *tc, a) { foreach (ToolChain *tc, a) {
if (!Utils::contains(result, [tc](ToolChain *rtc) { return *tc == *rtc; })) if (!Utils::contains(result, [tc](ToolChain *rtc) { return *tc == *rtc; }))
result.append(tc); result.append(tc);
@@ -88,42 +87,42 @@ static QList<ToolChain *> makeUniqueByEqual(const QList<ToolChain *> &a)
return result; return result;
} }
static QList<ToolChain *> makeUniqueByPointerEqual(const QList<ToolChain *> &a) static Toolchains makeUniqueByPointerEqual(const Toolchains &a)
{ {
return Utils::toList(Utils::toSet(a)); return Utils::toList(Utils::toSet(a));
} }
static QList<ToolChain *> subtractById(const QList<ToolChain *> &a, const QList<ToolChain *> &b) static Toolchains subtractById(const Toolchains &a, const Toolchains &b)
{ {
return Utils::filtered(a, [&b](ToolChain *atc) { return Utils::filtered(a, [&b](ToolChain *atc) {
return !Utils::anyOf(b, Utils::equal(&ToolChain::id, atc->id())); return !Utils::anyOf(b, Utils::equal(&ToolChain::id, atc->id()));
}); });
} }
static bool containsByEqual(const QList<ToolChain *> &a, const ToolChain *atc) static bool containsByEqual(const Toolchains &a, const ToolChain *atc)
{ {
return Utils::anyOf(a, [atc](ToolChain *btc) { return *atc == *btc; }); return Utils::anyOf(a, [atc](ToolChain *btc) { return *atc == *btc; });
} }
static QList<ToolChain *> subtractByEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b) static Toolchains subtractByEqual(const Toolchains &a, const Toolchains &b)
{ {
return Utils::filtered(a, [&b](ToolChain *atc) { return Utils::filtered(a, [&b](ToolChain *atc) {
return !Utils::anyOf(b, [atc](ToolChain *btc) { return *atc == *btc; }); return !Utils::anyOf(b, [atc](ToolChain *btc) { return *atc == *btc; });
}); });
} }
static QList<ToolChain *> subtractByPointerEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b) static Toolchains subtractByPointerEqual(const Toolchains &a, const Toolchains &b)
{ {
return Utils::filtered(a, [&b](ToolChain *atc) { return !b.contains(atc); }); return Utils::filtered(a, [&b](ToolChain *atc) { return !b.contains(atc); });
} }
static QList<ToolChain *> stabilizeOrder(const QList<ToolChain *> &toRegister, static Toolchains stabilizeOrder(const Toolchains &toRegister,
const QList<ToolChain *> &userFileTcs) const Toolchains &userFileTcs)
{ {
// Keep the toolchains in their position in the user toolchain file to minimize diff! // Keep the toolchains in their position in the user toolchain file to minimize diff!
QList<ToolChain *> result; Toolchains result;
result.reserve(toRegister.size()); result.reserve(toRegister.size());
QList<ToolChain *> toHandle = toRegister; Toolchains toHandle = toRegister;
for (int i = 0; i < userFileTcs.count(); ++i) { for (int i = 0; i < userFileTcs.count(); ++i) {
const QByteArray userId = userFileTcs.at(i)->id(); const QByteArray userId = userFileTcs.at(i)->id();
@@ -139,30 +138,30 @@ static QList<ToolChain *> stabilizeOrder(const QList<ToolChain *> &toRegister,
return result; return result;
} }
static ToolChainOperations mergeToolChainLists(const QList<ToolChain *> &systemFileTcs, static ToolChainOperations mergeToolChainLists(const Toolchains &systemFileTcs,
const QList<ToolChain *> &userFileTcs, const Toolchains &userFileTcs,
const QList<ToolChain *> &autodetectedTcs) const Toolchains &autodetectedTcs)
{ {
const QList<ToolChain *> uniqueUserFileTcs = makeUniqueByEqual(userFileTcs); const Toolchains uniqueUserFileTcs = makeUniqueByEqual(userFileTcs);
QList<ToolChain *> manualUserFileTcs; Toolchains manualUserFileTcs;
QList<ToolChain *> autodetectedUserFileTcs; Toolchains autodetectedUserFileTcs;
std::tie(autodetectedUserFileTcs, manualUserFileTcs) std::tie(autodetectedUserFileTcs, manualUserFileTcs)
= Utils::partition(uniqueUserFileTcs, &ToolChain::isAutoDetected); = Utils::partition(uniqueUserFileTcs, &ToolChain::isAutoDetected);
const QList<ToolChain *> autodetectedUserTcs = subtractById(autodetectedUserFileTcs, systemFileTcs); const Toolchains autodetectedUserTcs = subtractById(autodetectedUserFileTcs, systemFileTcs);
// Calculate a set of Tcs that were detected before (and saved to userFile) and that // Calculate a set of Tcs that were detected before (and saved to userFile) and that
// got re-detected again. Take the userTcs (to keep Ids) over the same in autodetectedTcs. // got re-detected again. Take the userTcs (to keep Ids) over the same in autodetectedTcs.
QList<ToolChain *> redetectedUserTcs; Toolchains redetectedUserTcs;
QList<ToolChain *> notRedetectedUserTcs; Toolchains notRedetectedUserTcs;
std::tie(redetectedUserTcs, notRedetectedUserTcs) std::tie(redetectedUserTcs, notRedetectedUserTcs)
= Utils::partition(autodetectedUserTcs, = Utils::partition(autodetectedUserTcs,
[&autodetectedTcs](ToolChain *tc) { return containsByEqual(autodetectedTcs, tc); }); [&autodetectedTcs](ToolChain *tc) { return containsByEqual(autodetectedTcs, tc); });
// Remove redetected tcs from autodetectedTcs: // Remove redetected tcs from autodetectedTcs:
const QList<ToolChain *> newlyAutodetectedTcs const Toolchains newlyAutodetectedTcs
= subtractByEqual(autodetectedTcs, redetectedUserTcs); = subtractByEqual(autodetectedTcs, redetectedUserTcs);
const QList<ToolChain *> notRedetectedButValidUserTcs const Toolchains notRedetectedButValidUserTcs
= Utils::filtered(notRedetectedUserTcs, &ToolChain::isValid); = Utils::filtered(notRedetectedUserTcs, &ToolChain::isValid);
ToolChainOperations result; ToolChainOperations result;
@@ -190,22 +189,23 @@ ToolChainSettingsAccessor::ToolChainSettingsAccessor() :
addVersionUpgrader(std::make_unique<ToolChainSettingsUpgraderV0>()); addVersionUpgrader(std::make_unique<ToolChainSettingsUpgraderV0>());
} }
QList<ToolChain *> ToolChainSettingsAccessor::restoreToolChains(QWidget *parent) const Toolchains ToolChainSettingsAccessor::restoreToolChains(QWidget *parent) const
{ {
// read all tool chains from SDK // read all tool chains from SDK
const QList<ToolChain *> systemFileTcs = toolChains( const Toolchains systemFileTcs = toolChains(
restoreSettings(Core::ICore::installerResourcePath(TOOLCHAIN_FILENAME), parent)); restoreSettings(Core::ICore::installerResourcePath(TOOLCHAIN_FILENAME), parent));
for (ToolChain * const systemTc : systemFileTcs) for (ToolChain * const systemTc : systemFileTcs)
systemTc->setDetection(ToolChain::AutoDetectionFromSdk); systemTc->setDetection(ToolChain::AutoDetectionFromSdk);
// read all tool chains from user file. // read all tool chains from user file.
const QList<ToolChain *> userFileTcs = toolChains(restoreSettings(parent)); const Toolchains userFileTcs = toolChains(restoreSettings(parent));
// Autodetect: Pass autodetected toolchains from user file so the information can be reused: // Autodetect: Pass autodetected toolchains from user file so the information can be reused:
const QList<ToolChain *> autodetectedUserFileTcs const Toolchains autodetectedUserFileTcs
= Utils::filtered(userFileTcs, &ToolChain::isAutoDetected); = Utils::filtered(userFileTcs, &ToolChain::isAutoDetected);
// FIXME: Use real device? // FIXME: Use real device?
const QList<ToolChain *> autodetectedTcs = autoDetectToolChains(autodetectedUserFileTcs, {}); const Toolchains autodetectedTcs =
autoDetectToolChains(ToolchainDetector(autodetectedUserFileTcs, {}));
// 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);
@@ -219,7 +219,7 @@ QList<ToolChain *> ToolChainSettingsAccessor::restoreToolChains(QWidget *parent)
return ops.toRegister; return ops.toRegister;
} }
void ToolChainSettingsAccessor::saveToolChains(const QList<ToolChain *> &toolchains, QWidget *parent) void ToolChainSettingsAccessor::saveToolChains(const Toolchains &toolchains, QWidget *parent)
{ {
QVariantMap data; QVariantMap data;
@@ -240,9 +240,9 @@ void ToolChainSettingsAccessor::saveToolChains(const QList<ToolChain *> &toolcha
saveSettings(data, parent); saveSettings(data, parent);
} }
QList<ToolChain *> ToolChainSettingsAccessor::toolChains(const QVariantMap &data) const Toolchains ToolChainSettingsAccessor::toolChains(const QVariantMap &data) const
{ {
QList<ToolChain *> result; Toolchains result;
const QList<ToolChainFactory *> factories = ToolChainFactory::allToolChainFactories(); const QList<ToolChainFactory *> factories = ToolChainFactory::allToolChainFactories();
const int count = data.value(TOOLCHAIN_COUNT_KEY, 0).toInt(); const int count = data.value(TOOLCHAIN_COUNT_KEY, 0).toInt();
@@ -291,8 +291,6 @@ QList<ToolChain *> ToolChainSettingsAccessor::toolChains(const QVariantMap &data
namespace ProjectExplorer { namespace ProjectExplorer {
using TCList = QList<ToolChain *>;
const char TestTokenKey[] = "TestTokenKey"; const char TestTokenKey[] = "TestTokenKey";
const char TestToolChainType[] = "TestToolChainType"; const char TestToolChainType[] = "TestToolChainType";
@@ -375,11 +373,11 @@ void ProjectExplorerPlugin::testToolChainMerging_data()
TestToolChainFactory factory; TestToolChainFactory factory;
QTest::addColumn<TCList>("system"); QTest::addColumn<Toolchains>("system");
QTest::addColumn<TCList>("user"); QTest::addColumn<Toolchains>("user");
QTest::addColumn<TCList>("autodetect"); QTest::addColumn<Toolchains>("autodetect");
QTest::addColumn<TCList>("toDemote"); QTest::addColumn<Toolchains>("toDemote");
QTest::addColumn<TCList>("toRegister"); QTest::addColumn<Toolchains>("toRegister");
TTC *system1 = nullptr; TTC *system1 = nullptr;
ToolChain *system1c = nullptr; ToolChain *system1c = nullptr;
@@ -422,57 +420,57 @@ void ProjectExplorerPlugin::testToolChainMerging_data()
} }
QTest::newRow("no toolchains") QTest::newRow("no toolchains")
<< (TCList()) << (TCList()) << (TCList()) << (Toolchains()) << (Toolchains()) << (Toolchains())
<< (TCList()) << (TCList()); << (Toolchains()) << (Toolchains());
QTest::newRow("System: system, no user") QTest::newRow("System: system, no user")
<< (TCList() << system1) << (TCList()) << (TCList()) << (Toolchains() << system1) << (Toolchains()) << (Toolchains())
<< (TCList()) << (TCList() << system1); << (Toolchains()) << (Toolchains() << system1);
QTest::newRow("System: system, user") QTest::newRow("System: system, user")
<< (TCList() << system1) << (TCList() << system1) << (TCList()) << (Toolchains() << system1) << (Toolchains() << system1) << (Toolchains())
<< (TCList()) << (TCList() << system1); << (Toolchains()) << (Toolchains() << system1);
QTest::newRow("System: no system, user") // keep, the user tool chain as it is still found QTest::newRow("System: no system, user") // keep, the user tool chain as it is still found
<< (TCList()) << (TCList() << system1) << (TCList()) << (Toolchains()) << (Toolchains() << system1) << (Toolchains())
<< (TCList() << system1) << (TCList() << system1); << (Toolchains() << system1) << (Toolchains() << system1);
QTest::newRow("System: no system, invalid user") QTest::newRow("System: no system, invalid user")
<< (TCList()) << (TCList() << system3i) << (TCList()) << (Toolchains()) << (Toolchains() << system3i) << (Toolchains())
<< (TCList()) << (TCList()); << (Toolchains()) << (Toolchains());
QTest::newRow("Auto: no auto, user") QTest::newRow("Auto: no auto, user")
<< (TCList()) << (TCList() << auto1) << (TCList()) << (Toolchains()) << (Toolchains() << auto1) << (Toolchains())
<< (TCList() << auto1) << (TCList() << auto1); << (Toolchains() << auto1) << (Toolchains() << auto1);
QTest::newRow("Auto: auto, no user") QTest::newRow("Auto: auto, no user")
<< (TCList()) << (TCList()) << (TCList() << auto1) << (Toolchains()) << (Toolchains()) << (Toolchains() << auto1)
<< (TCList()) << (TCList() << auto1); << (Toolchains()) << (Toolchains() << auto1);
QTest::newRow("Auto: auto, user") QTest::newRow("Auto: auto, user")
<< (TCList()) << (TCList() << auto1) << (TCList() << auto1) << (Toolchains()) << (Toolchains() << auto1) << (Toolchains() << auto1)
<< (TCList()) << (TCList() << auto1); << (Toolchains()) << (Toolchains() << auto1);
QTest::newRow("Auto: auto-redetect, user") QTest::newRow("Auto: auto-redetect, user")
<< (TCList()) << (TCList() << auto1) << (TCList() << auto1_2) << (Toolchains()) << (Toolchains() << auto1) << (Toolchains() << auto1_2)
<< (TCList()) << (TCList() << auto1); << (Toolchains()) << (Toolchains() << auto1);
QTest::newRow("Auto: auto-redetect, duplicate users") QTest::newRow("Auto: auto-redetect, duplicate users")
<< (TCList()) << (TCList() << auto1 << auto1c) << (TCList() << auto1_2) << (Toolchains()) << (Toolchains() << auto1 << auto1c) << (Toolchains() << auto1_2)
<< (TCList()) << (TCList() << auto1); << (Toolchains()) << (Toolchains() << auto1);
QTest::newRow("Auto: (no) auto, invalid user") QTest::newRow("Auto: (no) auto, invalid user")
<< (TCList()) << (TCList() << auto3i) << (TCList()) << (Toolchains()) << (Toolchains() << auto3i) << (Toolchains())
<< (TCList()) << (TCList()); << (Toolchains()) << (Toolchains());
QTest::newRow("invalid user") QTest::newRow("invalid user")
<< (TCList()) << (TCList() << user3i) << (TCList()) << (Toolchains()) << (Toolchains() << user3i) << (Toolchains())
<< (TCList()) << (TCList{user3i}); << (Toolchains()) << (Toolchains{user3i});
QTest::newRow("one of everything") QTest::newRow("one of everything")
<< (TCList() << system1) << (TCList() << user1) << (TCList() << auto1) << (Toolchains() << system1) << (Toolchains() << user1) << (Toolchains() << auto1)
<< (TCList()) << (TCList() << system1 << user1 << auto1); << (Toolchains()) << (Toolchains() << system1 << user1 << auto1);
} }
void ProjectExplorerPlugin::testToolChainMerging() void ProjectExplorerPlugin::testToolChainMerging()
{ {
QFETCH(TCList, system); QFETCH(Toolchains, system);
QFETCH(TCList, user); QFETCH(Toolchains, user);
QFETCH(TCList, autodetect); QFETCH(Toolchains, autodetect);
QFETCH(TCList, toRegister); QFETCH(Toolchains, toRegister);
QFETCH(TCList, toDemote); QFETCH(Toolchains, toDemote);
Internal::ToolChainOperations ops = Internal::mergeToolChainLists(system, user, autodetect); Internal::ToolChainOperations ops = Internal::mergeToolChainLists(system, user, autodetect);

View File

@@ -218,17 +218,12 @@ QnxToolChainFactory::QnxToolChainFactory()
setUserCreatable(true); setUserCreatable(true);
} }
QList<ProjectExplorer::ToolChain *> QnxToolChainFactory::autoDetect( Toolchains QnxToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const QList<ProjectExplorer::ToolChain *> &alreadyKnown,
const IDevice::Ptr &device)
{ {
Q_UNUSED(device); Toolchains tcs;
const auto configurations = QnxConfigurationManager::instance()->configurations();
QList<ToolChain *> tcs; for (QnxConfiguration *configuration : configurations)
QList<QnxConfiguration *> configurations = tcs += configuration->autoDetect(detector.alreadyKnown);
QnxConfigurationManager::instance()->configurations();
foreach (QnxConfiguration *configuration, configurations)
tcs += configuration->autoDetect(alreadyKnown);
return tcs; return tcs;
} }

View File

@@ -70,9 +70,8 @@ class QnxToolChainFactory : public ProjectExplorer::ToolChainFactory
public: public:
QnxToolChainFactory(); QnxToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect( ProjectExplorer::Toolchains autoDetect(
const QList<ProjectExplorer::ToolChain *> &alreadyKnown, const ProjectExplorer::ToolchainDetector &detector) const final;
const ProjectExplorer::IDevice::Ptr &device) final;
}; };
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@@ -126,7 +126,7 @@ void WebAssemblyToolChain::registerToolChains()
return f->supportedToolChainType() == Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID; return f->supportedToolChainType() == Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID;
}); });
QTC_ASSERT(factory, return); QTC_ASSERT(factory, return);
for (auto toolChain : factory->autoDetect({}, {})) for (auto toolChain : factory->autoDetect(ToolchainDetector({}, {})))
ToolChainManager::registerToolChain(toolChain); ToolChainManager::registerToolChain(toolChain);
// Let kits pick up the new toolchains // Let kits pick up the new toolchains
@@ -155,19 +155,15 @@ WebAssemblyToolChainFactory::WebAssemblyToolChainFactory()
setUserCreatable(true); setUserCreatable(true);
} }
QList<ToolChain *> WebAssemblyToolChainFactory::autoDetect( Toolchains WebAssemblyToolChainFactory::autoDetect(const ToolchainDetector &detector) const
const QList<ToolChain *> &alreadyKnown,
const IDevice::Ptr &device)
{ {
Q_UNUSED(alreadyKnown)
const FilePath sdk = WebAssemblyEmSdk::registeredEmSdk(); const FilePath sdk = WebAssemblyEmSdk::registeredEmSdk();
if (!WebAssemblyEmSdk::isValid(sdk)) if (!WebAssemblyEmSdk::isValid(sdk))
return {}; return {};
if (device) { if (detector.device) {
// Only detect toolchains from the emsdk installation device // Only detect toolchains from the emsdk installation device
const FilePath deviceRoot = device->mapToGlobalPath({}); const FilePath deviceRoot = detector.device->mapToGlobalPath({});
if (deviceRoot.host() != sdk.host()) if (deviceRoot.host() != sdk.host())
return {}; return {};
} }
@@ -175,7 +171,7 @@ QList<ToolChain *> WebAssemblyToolChainFactory::autoDetect(
Environment env = sdk.deviceEnvironment(); Environment env = sdk.deviceEnvironment();
WebAssemblyEmSdk::addToEnvironment(sdk, env); WebAssemblyEmSdk::addToEnvironment(sdk, env);
QList<ToolChain *> result; Toolchains result;
for (auto languageId : {ProjectExplorer::Constants::C_LANGUAGE_ID, for (auto languageId : {ProjectExplorer::Constants::C_LANGUAGE_ID,
ProjectExplorer::Constants::CXX_LANGUAGE_ID}) { ProjectExplorer::Constants::CXX_LANGUAGE_ID}) {
auto toolChain = new WebAssemblyToolChain; auto toolChain = new WebAssemblyToolChain;

View File

@@ -57,9 +57,8 @@ class WebAssemblyToolChainFactory : public ProjectExplorer::ToolChainFactory
public: public:
WebAssemblyToolChainFactory(); WebAssemblyToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect( ProjectExplorer::Toolchains autoDetect(
const QList<ProjectExplorer::ToolChain *> &alreadyKnown, const ProjectExplorer::ToolchainDetector &detector) const final;
const ProjectExplorer::IDevice::Ptr &device) override;
}; };
} // namespace Internal } // namespace Internal