forked from qt-creator/qt-creator
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: Eike Ziller <eike.ziller@theqtcompany.com>
This commit is contained in:
@@ -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 @@
|
|||||||
#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()
|
|||||||
|
|
||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
|
|
||||||
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:
|
|||||||
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
|
|||||||
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
|
|||||||
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 @@
|
|||||||
#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
|
|||||||
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
|
|||||||
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
|
|||||||
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.";
|
|||||||
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)
|
|||||||
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) {
|
// Autodetect: Pass autodetected toolchains from user file so the information can be reused:
|
||||||
if (tc->isAutoDetected())
|
const QList<ToolChain *> autodetectedUserFileTcs
|
||||||
tcsToCheck.append(tc);
|
= Utils::filtered(userFileTcs, &ToolChain::isAutoDetected);
|
||||||
else
|
const QList<ToolChain *> autodetectedTcs = autoDetectToolChains(autodetectedUserFileTcs);
|
||||||
tcsToRegister.append(tc);
|
|
||||||
}
|
|
||||||
readTcs.clear();
|
|
||||||
|
|
||||||
// Remove TCs configured by the SDK:
|
// merge tool chains and register those that we need to keep:
|
||||||
foreach (ToolChain *tc, tcsToRegister) {
|
ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs);
|
||||||
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
|
// Process ops:
|
||||||
QList<ToolChain *> detectedTcs = tcsToCheck;
|
foreach (ToolChain *tc, ops.toDemote)
|
||||||
QList<ToolChainFactory *> factories = ExtensionSystem::PluginManager::getObjects<ToolChainFactory>();
|
tc->setDetection(ToolChain::ManualDetection);
|
||||||
foreach (ToolChainFactory *f, factories)
|
|
||||||
detectedTcs.append(f->autoDetect(tcsToCheck));
|
|
||||||
|
|
||||||
// Find/update autodetected tool chains:
|
foreach (ToolChain *tc, ops.toRegister)
|
||||||
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
|
|
||||||
foreach (ToolChain *tc, tcsToCheck) {
|
|
||||||
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
|
|
||||||
foreach (ToolChain *tc, tcsToRegister)
|
|
||||||
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:
|
|||||||
// 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 @@
|
|||||||
#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()
|
|||||||
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)
|
||||||
|
{
|
||||||
|
ToolChain *tc
|
||||||
|
= Utils::findOrDefault(alreadyKnown, [&](ToolChain *tc) -> bool {
|
||||||
|
if (tc->typeId() != Constants::WINCE_TOOLCHAIN_TYPEID)
|
||||||
|
return false;
|
||||||
|
auto cetc = static_cast<WinCEToolChain *>(tc);
|
||||||
|
return cetc->targetAbi() == abi
|
||||||
|
&& cetc->varsBat() == vcvarsBat
|
||||||
|
&& cetc->msvcVer() == msvcVer
|
||||||
|
&& cetc->ceVer() == ceVer
|
||||||
|
&& cetc->binPath() == binPath
|
||||||
|
&& cetc->includePath() == includePath
|
||||||
|
&& cetc->libPath() == libPath;
|
||||||
|
});
|
||||||
|
if (!tc)
|
||||||
|
tc = new WinCEToolChain(name, abi, vcvarsBat, msvcVer, ceVer, binPath, includePath, libPath, d);
|
||||||
|
return tc;
|
||||||
|
}
|
||||||
|
|
||||||
QList<ToolChain *> WinCEToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
QList<ToolChain *> WinCEToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
Q_UNUSED(alreadyKnown);
|
|
||||||
QList<ToolChain *> results;
|
QList<ToolChain *> results;
|
||||||
|
|
||||||
// 1) Installed WinCEs
|
// 1) Installed WinCEs
|
||||||
@@ -398,16 +422,16 @@ QList<ToolChain *> WinCEToolChainFactory::autoDetect(const QList<ToolChain *> &a
|
|||||||
QString ceVer;
|
QString ceVer;
|
||||||
|
|
||||||
if (parseSDK(platformReader, theArch, thePlat, ceVer, binPath, includePath, libPath)) {
|
if (parseSDK(platformReader, theArch, thePlat, ceVer, binPath, includePath, libPath)) {
|
||||||
WinCEToolChain *pChain = new WinCEToolChain(thePlat,
|
results.append(findOrCreateToolChain(alreadyKnown,
|
||||||
Abi(theArch, Abi::WindowsOS, Abi::WindowsCEFlavor, Abi::PEFormat, 32),
|
thePlat,
|
||||||
vcvars32bat,
|
Abi(theArch, Abi::WindowsOS, Abi::WindowsCEFlavor, Abi::PEFormat, 32),
|
||||||
msvcVer,
|
vcvars32bat,
|
||||||
ceVer,
|
msvcVer,
|
||||||
binPath,
|
ceVer,
|
||||||
includePath,
|
binPath,
|
||||||
libPath,
|
includePath,
|
||||||
ToolChain::AutoDetection);
|
libPath,
|
||||||
results.append(pChain);
|
ToolChain::AutoDetection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,8 +57,13 @@ public:
|
|||||||
|
|
||||||
QString typeDisplayName() const override;
|
QString typeDisplayName() const override;
|
||||||
|
|
||||||
|
QString msvcVer() const { return m_msvcVer; }
|
||||||
QString ceVer() const;
|
QString ceVer() const;
|
||||||
|
|
||||||
|
QString binPath() const { return m_binPath; }
|
||||||
|
QString includePath() const { return m_includePath; }
|
||||||
|
QString libPath() const { return m_libPath; }
|
||||||
|
|
||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user