Commit ac1d9abd authored by Tobias Hunger's avatar Tobias Hunger
Browse files

ToolChainManager: Refactor toolchain restoration



This should be simpler to follow now.

Fix autodetection to return not only the newly detected toolchains,
but also those that are re-detected (taking their definition from
the alreadyKnown list passed to the autodetect method where possible).

This avoids running lots of toolchains during start-up, but still
enables us to fix QTCREATORBUG-12751

Task-number: QTCREATORBUG-12751
Change-Id: Ie74e7cffb2b014a6132cc8559db232397344f2f1
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
parent e5d62f3e
...@@ -1233,21 +1233,15 @@ static bool equalKits(Kit *a, Kit *b) ...@@ -1233,21 +1233,15 @@ static bool equalKits(Kit *a, Kit *b)
void AndroidConfigurations::registerNewToolChains() void AndroidConfigurations::registerNewToolChains()
{ {
QList<ToolChain *> existingToolChains = ToolChainManager::toolChains(); const QList<ToolChain *> existingAndroidToolChains
QList<ToolChain *> toolchains = AndroidToolChainFactory::createToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation()); = Utils::filtered(ToolChainManager::toolChains(),
foreach (ToolChain *tc, toolchains) { Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_ID)));
bool found = false;
for (int i = 0; i < existingToolChains.count(); ++i) { const QList<ToolChain *> newToolchains
if (*(existingToolChains.at(i)) == *tc) { = AndroidToolChainFactory::autodetectToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation(),
found = true; existingAndroidToolChains);
break; foreach (ToolChain *tc, newToolchains)
}
}
if (found)
delete tc;
else
ToolChainManager::registerToolChain(tc); ToolChainManager::registerToolChain(tc);
}
} }
void AndroidConfigurations::removeOldToolChains() void AndroidConfigurations::removeOldToolChains()
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <projectexplorer/toolchainmanager.h> #include <projectexplorer/toolchainmanager.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <utils/algorithm.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
...@@ -260,8 +261,7 @@ AndroidToolChainFactory::AndroidToolChainFactory() ...@@ -260,8 +261,7 @@ AndroidToolChainFactory::AndroidToolChainFactory()
QList<ToolChain *> AndroidToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown) QList<ToolChain *> AndroidToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
{ {
Q_UNUSED(alreadyKnown); return autodetectToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation(), alreadyKnown);
return createToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation());
} }
bool AndroidToolChainFactory::canRestore(const QVariantMap &data) bool AndroidToolChainFactory::canRestore(const QVariantMap &data)
...@@ -352,11 +352,23 @@ bool AndroidToolChainFactory::versionCompareLess(AndroidToolChain *atc, AndroidT ...@@ -352,11 +352,23 @@ bool AndroidToolChainFactory::versionCompareLess(AndroidToolChain *atc, AndroidT
return versionCompareLess(a, b); return versionCompareLess(a, b);
} }
QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileName &ndkPath) static AndroidToolChain *findToolChain(Utils::FileName &compilerPath, const QList<ToolChain *> &alreadyKnown)
{
return static_cast<AndroidToolChain *>(
Utils::findOrDefault(alreadyKnown, [compilerPath](ToolChain *tc) {
return tc->compilerCommand() == compilerPath
&& tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID;
}));
}
QList<ToolChain *>
AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath,
const QList<ToolChain *> &alreadyKnown)
{ {
QList<ToolChain *> result; QList<ToolChain *> result;
if (ndkPath.isEmpty()) if (ndkPath.isEmpty())
return result; return result;
QRegExp versionRegExp(NDKGccVersionRegExp); QRegExp versionRegExp(NDKGccVersionRegExp);
FileName path = ndkPath; FileName path = ndkPath;
QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(), QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(),
...@@ -373,13 +385,16 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam ...@@ -373,13 +385,16 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam
Abi abi = AndroidConfig::abiForToolChainPrefix(platform); Abi abi = AndroidConfig::abiForToolChainPrefix(platform);
if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
continue; continue;
AndroidToolChain *tc = new AndroidToolChain(abi, version, ToolChain::AutoDetection);
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, version); FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, version);
tc->resetToolChain(compilerPath);
AndroidToolChain *tc = findToolChain(compilerPath, alreadyKnown);
if (!tc) {
tc = new AndroidToolChain(abi, version, ToolChain::AutoDetection);
tc->resetToolChain(compilerPath);
}
result.append(tc); result.append(tc);
QHash<Abi, AndroidToolChain *>::const_iterator it auto it = newestToolChainForArch.constFind(abi);
= newestToolChainForArch.constFind(abi);
if (it == newestToolChainForArch.constEnd()) if (it == newestToolChainForArch.constEnd())
newestToolChainForArch.insert(abi, tc); newestToolChainForArch.insert(abi, tc);
else if (versionCompareLess(it.value(), tc)) else if (versionCompareLess(it.value(), tc))
...@@ -388,8 +403,7 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam ...@@ -388,8 +403,7 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam
foreach (ToolChain *tc, result) { foreach (ToolChain *tc, result) {
AndroidToolChain *atc = static_cast<AndroidToolChain *>(tc); AndroidToolChain *atc = static_cast<AndroidToolChain *>(tc);
if (newestToolChainForArch.value(atc->targetAbi()) != atc) atc->setSecondaryToolChain(newestToolChainForArch.value(atc->targetAbi()) != atc);
atc->setSecondaryToolChain(true);
} }
return result; return result;
......
...@@ -113,7 +113,9 @@ public: ...@@ -113,7 +113,9 @@ public:
QString version; QString version;
}; };
static QList<ProjectExplorer::ToolChain *> createToolChainsForNdk(const Utils::FileName &ndkPath); static QList<ProjectExplorer::ToolChain *>
autodetectToolChainsForNdk(const Utils::FileName &ndkPath,
const QList<ProjectExplorer::ToolChain *> &alreadyKnown);
static QList<AndroidToolChainInformation> toolchainPathsForNdk(const Utils::FileName &ndkPath); static QList<AndroidToolChainInformation> toolchainPathsForNdk(const Utils::FileName &ndkPath);
static QList<int> versionNumberFromString(const QString &version); static QList<int> versionNumberFromString(const QString &version);
......
...@@ -375,10 +375,10 @@ QList<ToolChain *> IosToolChainFactory::autoDetect(const QList<ToolChain *> &exi ...@@ -375,10 +375,10 @@ QList<ToolChain *> IosToolChainFactory::autoDetect(const QList<ToolChain *> &exi
foreach (const Platform &platform, platforms) { foreach (const Platform &platform, platforms) {
ClangToolChain *toolChain = findToolChainForPlatform(platform, existingClangToolChains); ClangToolChain *toolChain = findToolChainForPlatform(platform, existingClangToolChains);
if (!toolChain) { if (!toolChain) {
ClangToolChain *newToolChain = createToolChain(platform); toolChain = createToolChain(platform);
toolChains.append(newToolChain); existingClangToolChains.append(toolChain);
existingClangToolChains.append(newToolChain);
} }
toolChains.append(toolChain);
} }
return Utils::transform(toolChains, [](ClangToolChain *tc) -> ToolChain * { return tc; }); return Utils::transform(toolChains, [](ClangToolChain *tc) -> ToolChain * { return tc; });
} }
......
...@@ -819,7 +819,8 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp ...@@ -819,7 +819,8 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp
if (compilerPath.isEmpty()) if (compilerPath.isEmpty())
return result; return result;
if (Utils::findOrDefault(alreadyKnown, Utils::equal(&ToolChain::compilerCommand, compilerPath))) result = Utils::filtered(alreadyKnown, Utils::equal(&ToolChain::compilerCommand, compilerPath));
if (!result.isEmpty())
return result; return result;
GccToolChain::addCommandPathToEnvironment(compilerPath, systemEnvironment); GccToolChain::addCommandPathToEnvironment(compilerPath, systemEnvironment);
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "msvcparser.h" #include "msvcparser.h"
#include "projectexplorerconstants.h" #include "projectexplorerconstants.h"
#include <utils/algorithm.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <utils/winutils.h> #include <utils/winutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
...@@ -526,9 +527,26 @@ QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath, MsvcToolChai ...@@ -526,9 +527,26 @@ QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath, MsvcToolChai
return vcVarsBatFor(basePath, platformName(platform)); return vcVarsBatFor(basePath, platformName(platform));
} }
static ToolChain *findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown,
const QString &name, const Abi &abi,
const QString &varsBat, const QString &varsBatArg,
ToolChain::Detection d = ToolChain::ManualDetection)
{
ToolChain *tc = Utils::findOrDefault(alreadyKnown,
[&varsBat, &varsBatArg](ToolChain *tc) -> bool {
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
return false;
auto mtc = static_cast<MsvcToolChain *>(tc);
return mtc->varsBat() == varsBat
&& mtc->varsBatArg() == varsBatArg;
});
if (!tc)
tc = new MsvcToolChain(name, abi, varsBat, varsBatArg, d);
return tc;
}
QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown) QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
{ {
Q_UNUSED(alreadyKnown);
QList<ToolChain *> results; QList<ToolChain *> results;
// 1) Installed SDKs preferred over standalone Visual studio // 1) Installed SDKs preferred over standalone Visual studio
...@@ -550,16 +568,19 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al ...@@ -550,16 +568,19 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
continue; continue;
QList<ToolChain *> tmp; QList<ToolChain *> tmp;
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86), tmp.append(findOrCreateToolChain(alreadyKnown,
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, sdkKey), generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
fi.absoluteFilePath(), QLatin1String("/x86"), ToolChain::AutoDetection)); findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, sdkKey),
fi.absoluteFilePath(), QLatin1String("/x86"), ToolChain::AutoDetection));
// Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed // Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64), tmp.append(findOrCreateToolChain(alreadyKnown,
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, sdkKey), generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
fi.absoluteFilePath(), QLatin1String("/x64"), ToolChain::AutoDetection)); findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, sdkKey),
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64), fi.absoluteFilePath(), QLatin1String("/x64"), ToolChain::AutoDetection));
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, sdkKey), tmp.append(findOrCreateToolChain(alreadyKnown,
fi.absoluteFilePath(), QLatin1String("/ia64"), ToolChain::AutoDetection)); generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, sdkKey),
fi.absoluteFilePath(), QLatin1String("/ia64"), ToolChain::AutoDetection));
// Make sure the default is front. // Make sure the default is front.
if (folder == defaultSdkPath) if (folder == defaultSdkPath)
results = tmp + results; results = tmp + results;
...@@ -601,11 +622,11 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al ...@@ -601,11 +622,11 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
foreach (const MsvcToolChain::Platform &platform, platforms) { foreach (const MsvcToolChain::Platform &platform, platforms) {
if (hostSupportsPlatform(platform) if (hostSupportsPlatform(platform)
&& QFileInfo(vcVarsBatFor(path, platform)).isFile()) { && QFileInfo(vcVarsBatFor(path, platform)).isFile()) {
results.append(new MsvcToolChain( results.append(findOrCreateToolChain(
alreadyKnown,
generateDisplayName(vsName, MsvcToolChain::VS, platform), generateDisplayName(vsName, MsvcToolChain::VS, platform),
findAbiOfMsvc(MsvcToolChain::VS, platform, vsName), findAbiOfMsvc(MsvcToolChain::VS, platform, vsName),
vcvarsAllbat, vcvarsAllbat, platformName(platform),
platformName(platform),
ToolChain::AutoDetection)); ToolChain::AutoDetection));
} }
} }
......
...@@ -50,7 +50,6 @@ static const char TOOLCHAIN_DATA_KEY[] = "ToolChain."; ...@@ -50,7 +50,6 @@ static const char TOOLCHAIN_DATA_KEY[] = "ToolChain.";
static const char TOOLCHAIN_COUNT_KEY[] = "ToolChain.Count"; static const char TOOLCHAIN_COUNT_KEY[] = "ToolChain.Count";
static const char TOOLCHAIN_FILE_VERSION_KEY[] = "Version"; static const char TOOLCHAIN_FILE_VERSION_KEY[] = "Version";
static const char TOOLCHAIN_FILENAME[] = "/qtcreator/toolchains.xml"; static const char TOOLCHAIN_FILENAME[] = "/qtcreator/toolchains.xml";
static const char LEGACY_TOOLCHAIN_FILENAME[] = "/toolChains.xml";
using namespace Utils; using namespace Utils;
...@@ -167,98 +166,146 @@ static QList<ToolChain *> restoreFromFile(const FileName &fileName) ...@@ -167,98 +166,146 @@ static QList<ToolChain *> restoreFromFile(const FileName &fileName)
return result; return result;
} }
static QList<ToolChain *> autoDetectToolChains(const QList<ToolChain *> alreadyKnownTcs)
{
QList<ToolChain *> result;
const QList<ToolChainFactory *> factories
= ExtensionSystem::PluginManager::getObjects<ToolChainFactory>();
foreach (ToolChainFactory *f, factories)
result.append(f->autoDetect(alreadyKnownTcs));
return result;
}
static QList<ToolChain *> subtractByEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
{
return Utils::filtered(a, [&b](ToolChain *atc) {
return !Utils::anyOf(b, [atc](ToolChain *btc) { return *atc == *btc; });
});
}
static QList<ToolChain *> subtractByPointerEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
{
return Utils::filtered(a, [&b](ToolChain *atc) { return !b.contains(atc); });
}
static QList<ToolChain *> subtractById(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
{
return Utils::filtered(a, [&b](ToolChain *atc) {
return !Utils::anyOf(b, Utils::equal(&ToolChain::id, atc->id()));
});
}
static QList<ToolChain *> intersectByEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
{
return Utils::filtered(a, [&b](ToolChain *atc) {
return Utils::anyOf(b, [atc](ToolChain *btc) { return *atc == *btc; });
});
}
static QList<ToolChain *> makeUnique(const QList<ToolChain *> &a)
{
return QSet<ToolChain *>::fromList(a).toList();
}
namespace {
struct ToolChainOperations
{
QList<ToolChain *> toDemote;
QList<ToolChain *> toRegister;
QList<ToolChain *> toDelete;
};
} // namespace
static ToolChainOperations mergeToolChainLists(const QList<ToolChain *> &systemFileTcs,
const QList<ToolChain *> &userFileTcs,
const QList<ToolChain *> &autodetectedTcs)
{
const QList<ToolChain *> manualUserTcs
= Utils::filtered(userFileTcs, [](ToolChain *t) { return !t->isAutoDetected(); });
// Remove systemFileTcs from autodetectedUserTcs based on id-matches:
const QList<ToolChain *> autodetectedUserFileTcs
= Utils::filtered(userFileTcs, &ToolChain::isAutoDetected);
const QList<ToolChain *> autodetectedUserTcs = subtractById(autodetectedUserFileTcs, systemFileTcs);
// 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.
const QList<ToolChain *> redetectedUserTcs
= intersectByEqual(autodetectedUserTcs, autodetectedTcs);
// Remove redetected tcs from autodetectedUserTcs:
const QList<ToolChain *> notRedetectedUserTcs
= subtractByPointerEqual(autodetectedUserTcs, redetectedUserTcs);
// Remove redetected tcs from autodetectedTcs:
const QList<ToolChain *> newlyAutodetectedTcs
= subtractByEqual(autodetectedTcs, redetectedUserTcs);
const QList<ToolChain *> notRedetectedButValidUserTcs
= Utils::filtered(notRedetectedUserTcs, &ToolChain::isValid);
const QList<ToolChain *> validManualUserTcs
= Utils::filtered(manualUserTcs, &ToolChain::isValid);
ToolChainOperations result;
result.toDemote = notRedetectedButValidUserTcs;
result.toRegister = result.toDemote + systemFileTcs + redetectedUserTcs + newlyAutodetectedTcs
+ validManualUserTcs;
result.toDelete = makeUnique(subtractByPointerEqual(systemFileTcs + userFileTcs + autodetectedTcs,
result.toRegister));
return result;
}
void ToolChainManager::restoreToolChains() void ToolChainManager::restoreToolChains()
{ {
QTC_ASSERT(!d->m_writer, return); QTC_ASSERT(!d->m_writer, return);
d->m_writer = d->m_writer =
new PersistentSettingsWriter(settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)), QLatin1String("QtCreatorToolChains")); new PersistentSettingsWriter(settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)),
QLatin1String("QtCreatorToolChains"));
QList<ToolChain *> tcsToRegister;
QList<ToolChain *> tcsToCheck;
// read all tool chains from SDK // read all tool chains from SDK
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName()); const QList<ToolChain *> systemFileTcs = readSystemFileToolChains();
QList<ToolChain *> readTcs =
restoreFromFile(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(TOOLCHAIN_FILENAME)));
// make sure we mark these as autodetected!
foreach (ToolChain *tc, readTcs)
tc->setDetection(ToolChain::AutoDetection);
tcsToRegister = readTcs; // SDK TCs are always considered to be up-to-date, so no need to
// recheck them.
// read all tool chains from user file. // read all tool chains from user file.
// Read legacy settings once and keep them around... const QList<ToolChain *> userFileTcs
FileName fileName = settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)); = restoreFromFile(settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)));
if (!fileName.exists())
fileName = settingsFileName(QLatin1String(LEGACY_TOOLCHAIN_FILENAME));
readTcs = restoreFromFile(fileName);
foreach (ToolChain *tc, readTcs) {
if (tc->isAutoDetected())
tcsToCheck.append(tc);
else
tcsToRegister.append(tc);
}
readTcs.clear();
// Remove TCs configured by the SDK:
foreach (ToolChain *tc, tcsToRegister) {
for (int i = tcsToCheck.count() - 1; i >= 0; --i) {
if (tcsToCheck.at(i)->id() == tc->id()) {
delete tcsToCheck.at(i);
tcsToCheck.removeAt(i);
}
}
}
// Then auto detect // Autodetect: Pass autodetected toolchains from user file so the information can be reused:
QList<ToolChain *> detectedTcs = tcsToCheck; const QList<ToolChain *> autodetectedUserFileTcs
QList<ToolChainFactory *> factories = ExtensionSystem::PluginManager::getObjects<ToolChainFactory>(); = Utils::filtered(userFileTcs, &ToolChain::isAutoDetected);
foreach (ToolChainFactory *f, factories) const QList<ToolChain *> autodetectedTcs = autoDetectToolChains(autodetectedUserFileTcs);
detectedTcs.append(f->autoDetect(tcsToCheck));
// Find/update autodetected tool chains:
ToolChain *toStore = 0;
foreach (ToolChain *currentDetected, detectedTcs) {
toStore = currentDetected;
// Check whether we had this TC stored and prefer the old one with the old id, marked
// as auto-detection.
for (int i = 0; i < tcsToCheck.count(); ++i) {
if (tcsToCheck.at(i) == currentDetected) {
tcsToCheck.removeAt(i);
break;
} else if (*(tcsToCheck.at(i)) == *currentDetected) {
toStore = tcsToCheck.at(i);
toStore->setDetection(ToolChain::AutoDetection);
tcsToCheck.removeAt(i);
delete currentDetected;
break;
}
}
tcsToRegister += toStore;
}
// Keep toolchains that were not rediscovered but are still executable and delete the rest // merge tool chains and register those that we need to keep:
foreach (ToolChain *tc, tcsToCheck) { ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs);
if (!tc->isValid()) {
qWarning() << QString::fromLatin1("ToolChain \"%1\" (%2) dropped since it is not valid")
.arg(tc->displayName()).arg(QString::fromUtf8(tc->id()));
delete tc;
} else {
tc->setDetection(ToolChain::ManualDetection); // "demote" to manual toolchain
tcsToRegister += tc;
}
}
// Store manual tool chains // Process ops:
foreach (ToolChain *tc, tcsToRegister) foreach (ToolChain *tc, ops.toDemote)
tc->setDetection(ToolChain::ManualDetection);
foreach (ToolChain *tc, ops.toRegister)
registerToolChain(tc); registerToolChain(tc);
qDeleteAll(ops.toDelete);
emit m_instance->toolChainsLoaded(); emit m_instance->toolChainsLoaded();
} }
QList<ToolChain *> ToolChainManager::readSystemFileToolChains()
{
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
QList<ToolChain *> systemTcs
= restoreFromFile(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(TOOLCHAIN_FILENAME)));
foreach (ToolChain *tc, systemTcs)
tc->setDetection(ToolChain::AutoDetection);
return systemTcs;
}
void ToolChainManager::saveToolChains() void ToolChainManager::saveToolChains()
{ {
QVariantMap data; QVariantMap data;
......
...@@ -87,6 +87,9 @@ private: ...@@ -87,6 +87,9 @@ private:
// Make sure the this is only called after all // Make sure the this is only called after all
// Tool chain Factories are registered! // Tool chain Factories are registered!
static void restoreToolChains(); static void restoreToolChains();
static QList<ToolChain *> readSystemFileToolChains();
static void notifyAboutUpdate(ToolChain *); static void notifyAboutUpdate(ToolChain *);
friend class ProjectExplorerPlugin; // for constructor friend class ProjectExplorerPlugin; // for constructor
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "msvcparser.h" #include "msvcparser.h"
#include "projectexplorerconstants.h" #include "projectexplorerconstants.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QDir> #include <QDir>
...@@ -352,10 +353,33 @@ WinCEToolChainFactory::WinCEToolChainFactory() ...@@ -352,10 +353,33 @@ WinCEToolChainFactory::WinCEToolChainFactory()
setDisplayName(tr("WinCE")); setDisplayName(tr("WinCE"));
} }
static ToolChain *findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown,
const QString &name, const Abi &abi,
const QString &vcvarsBat, const QString &msvcVer,
const QString &ceVer, const QString &binPath,
const QString &includePath, const QString &libPath,
ToolChain::Detection d = ToolChain::ManualDetection)
{