forked from qt-creator/qt-creator
ProjectExplorer: Give Xcode clang higher priority than "bare" clang
If Xcode is present, we want its toolchain in the default kit, rather than a generic compiler from /usr/bin. Change-Id: If5d1dc02b6abcfff580162a19f07706d58681b7e Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -587,6 +587,7 @@ Toolchains IosToolChainFactory::autoDetect(const ToolchainDetector &detector) co
|
|||||||
auto createOrAdd = [&](ClangToolChain *toolChain, Id l) {
|
auto createOrAdd = [&](ClangToolChain *toolChain, Id l) {
|
||||||
if (!toolChain) {
|
if (!toolChain) {
|
||||||
toolChain = new ClangToolChain;
|
toolChain = new ClangToolChain;
|
||||||
|
toolChain->setPriority(ToolChain::PriorityHigh);
|
||||||
toolChain->setDetection(ToolChain::AutoDetection);
|
toolChain->setDetection(ToolChain::AutoDetection);
|
||||||
toolChain->setLanguage(l);
|
toolChain->setLanguage(l);
|
||||||
toolChain->setDisplayName(target.name);
|
toolChain->setDisplayName(target.name);
|
||||||
|
@@ -111,6 +111,7 @@ const char targetAbiKeyC[] = "ProjectExplorer.GccToolChain.TargetAbi";
|
|||||||
const char originalTargetTripleKeyC[] = "ProjectExplorer.GccToolChain.OriginalTargetTriple";
|
const char originalTargetTripleKeyC[] = "ProjectExplorer.GccToolChain.OriginalTargetTriple";
|
||||||
const char supportedAbisKeyC[] = "ProjectExplorer.GccToolChain.SupportedAbis";
|
const char supportedAbisKeyC[] = "ProjectExplorer.GccToolChain.SupportedAbis";
|
||||||
const char parentToolChainIdKeyC[] = "ProjectExplorer.ClangToolChain.ParentToolChainId";
|
const char parentToolChainIdKeyC[] = "ProjectExplorer.ClangToolChain.ParentToolChainId";
|
||||||
|
const char priorityKeyC[] = "ProjectExplorer.ClangToolChain.Priority";
|
||||||
const char binaryRegexp[] = "(?:^|-|\\b)(?:gcc|g\\+\\+|clang(?:\\+\\+)?)(?:-([\\d.]+))?$";
|
const char binaryRegexp[] = "(?:^|-|\\b)(?:gcc|g\\+\\+|clang(?:\\+\\+)?)(?:-([\\d.]+))?$";
|
||||||
|
|
||||||
static QString runGcc(const FilePath &gcc, const QStringList &arguments, const Environment &env)
|
static QString runGcc(const FilePath &gcc, const QStringList &arguments, const Environment &env)
|
||||||
@@ -1715,6 +1716,7 @@ QVariantMap ClangToolChain::toMap() const
|
|||||||
{
|
{
|
||||||
QVariantMap data = GccToolChain::toMap();
|
QVariantMap data = GccToolChain::toMap();
|
||||||
data.insert(parentToolChainIdKeyC, m_parentToolChainId);
|
data.insert(parentToolChainIdKeyC, m_parentToolChainId);
|
||||||
|
data.insert(priorityKeyC, m_priority);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1724,6 +1726,7 @@ bool ClangToolChain::fromMap(const QVariantMap &data)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_parentToolChainId = data.value(parentToolChainIdKeyC).toByteArray();
|
m_parentToolChainId = data.value(parentToolChainIdKeyC).toByteArray();
|
||||||
|
m_priority = data.value(priorityKeyC, PriorityNormal).toInt();
|
||||||
syncAutodetectedWithParentToolchains();
|
syncAutodetectedWithParentToolchains();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -209,6 +209,9 @@ public:
|
|||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
|
|
||||||
|
void setPriority(int priority) { m_priority = priority; }
|
||||||
|
int priority() const override { return m_priority; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Utils::LanguageExtensions defaultLanguageExtensions() const override;
|
Utils::LanguageExtensions defaultLanguageExtensions() const override;
|
||||||
void syncAutodetectedWithParentToolchains();
|
void syncAutodetectedWithParentToolchains();
|
||||||
@@ -218,6 +221,7 @@ private:
|
|||||||
// which is used for comparison with matchesCompileCommand
|
// which is used for comparison with matchesCompileCommand
|
||||||
mutable std::optional<Utils::FilePath> m_resolvedCompilerCommand;
|
mutable std::optional<Utils::FilePath> m_resolvedCompilerCommand;
|
||||||
QByteArray m_parentToolChainId;
|
QByteArray m_parentToolChainId;
|
||||||
|
int m_priority = PriorityNormal;
|
||||||
QMetaObject::Connection m_mingwToolchainAddedConnection;
|
QMetaObject::Connection m_mingwToolchainAddedConnection;
|
||||||
QMetaObject::Connection m_thisToolchainRemovedConnection;
|
QMetaObject::Connection m_thisToolchainRemovedConnection;
|
||||||
|
|
||||||
|
@@ -268,6 +268,14 @@ void KitManager::restoreKits()
|
|||||||
bestTc = tc;
|
bestTc = tc;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bestTc->priority() > tc->priority())
|
||||||
|
continue;
|
||||||
|
if (bestTc->priority() < tc->priority()) {
|
||||||
|
bestTc = tc;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const QString bestFilePath = bestTc->compilerCommand().toString();
|
const QString bestFilePath = bestTc->compilerCommand().toString();
|
||||||
const QString currentFilePath = tc->compilerCommand().toString();
|
const QString currentFilePath = tc->compilerCommand().toString();
|
||||||
if (bestFilePath.contains("icecc"))
|
if (bestFilePath.contains("icecc"))
|
||||||
@@ -283,6 +291,7 @@ void KitManager::restoreKits()
|
|||||||
bestTc = tc;
|
bestTc = tc;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestFilePath.length() > currentFilePath.length())
|
if (bestFilePath.length() > currentFilePath.length())
|
||||||
bestTc = tc;
|
bestTc = tc;
|
||||||
}
|
}
|
||||||
|
@@ -208,7 +208,8 @@ void QtKitAspect::fix(Kit *k)
|
|||||||
// Prefer exact matches.
|
// Prefer exact matches.
|
||||||
// TODO: We should probably prefer the compiler with the highest version number instead,
|
// TODO: We should probably prefer the compiler with the highest version number instead,
|
||||||
// but this information is currently not exposed by the ToolChain class.
|
// but this information is currently not exposed by the ToolChain class.
|
||||||
sort(possibleTcs, [version](const ToolChain *tc1, const ToolChain *tc2) {
|
const FilePaths envPathVar = Environment::systemEnvironment().path();
|
||||||
|
sort(possibleTcs, [version, &envPathVar](const ToolChain *tc1, const ToolChain *tc2) {
|
||||||
const QVector<Abi> &qtAbis = version->qtAbis();
|
const QVector<Abi> &qtAbis = version->qtAbis();
|
||||||
const bool tc1ExactMatch = qtAbis.contains(tc1->targetAbi());
|
const bool tc1ExactMatch = qtAbis.contains(tc1->targetAbi());
|
||||||
const bool tc2ExactMatch = qtAbis.contains(tc2->targetAbi());
|
const bool tc2ExactMatch = qtAbis.contains(tc2->targetAbi());
|
||||||
@@ -216,24 +217,37 @@ void QtKitAspect::fix(Kit *k)
|
|||||||
return true;
|
return true;
|
||||||
if (!tc1ExactMatch && tc2ExactMatch)
|
if (!tc1ExactMatch && tc2ExactMatch)
|
||||||
return false;
|
return false;
|
||||||
return tc1->priority() > tc2->priority();
|
|
||||||
});
|
|
||||||
|
|
||||||
const Toolchains goodTcs = Utils::filtered(possibleTcs, [&spec](const ToolChain *t) {
|
// For a multi-arch Qt that support the host ABI, prefer toolchains that match
|
||||||
return t->suggestedMkspecList().contains(spec);
|
// the host ABI.
|
||||||
});
|
if (qtAbis.size() > 1 && qtAbis.contains(Abi::hostAbi())) {
|
||||||
|
const bool tc1HasHostAbi = tc1->targetAbi() == Abi::hostAbi();
|
||||||
|
const bool tc2HasHostAbi = tc2->targetAbi() == Abi::hostAbi();
|
||||||
|
if (tc1HasHostAbi && !tc2HasHostAbi)
|
||||||
|
return true;
|
||||||
|
if (!tc1HasHostAbi && tc2HasHostAbi)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tc1->priority() > tc2->priority())
|
||||||
|
return true;
|
||||||
|
if (tc1->priority() < tc2->priority())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Hack to prefer a tool chain from PATH (e.g. autodetected) over other matches.
|
// Hack to prefer a tool chain from PATH (e.g. autodetected) over other matches.
|
||||||
// This improves the situation a bit if a cross-compilation tool chain has the
|
// This improves the situation a bit if a cross-compilation tool chain has the
|
||||||
// same ABI as the host.
|
// same ABI as the host.
|
||||||
const Environment systemEnvironment = Environment::systemEnvironment();
|
const bool tc1IsInPath = envPathVar.contains(tc1->compilerCommand().parentDir());
|
||||||
ToolChain *bestTc = Utils::findOrDefault(goodTcs,
|
const bool tc2IsInPath = envPathVar.contains(tc2->compilerCommand().parentDir());
|
||||||
[&systemEnvironment](const ToolChain *t) {
|
return tc1IsInPath && !tc2IsInPath;
|
||||||
return systemEnvironment.path().contains(t->compilerCommand().parentDir());
|
|
||||||
});
|
});
|
||||||
if (!bestTc) {
|
|
||||||
bestTc = goodTcs.isEmpty() ? possibleTcs.first() : goodTcs.first();
|
// TODO: Why is this not done during sorting?
|
||||||
}
|
const Toolchains goodTcs = Utils::filtered(possibleTcs, [&spec](const ToolChain *t) {
|
||||||
if (bestTc)
|
return t->suggestedMkspecList().contains(spec);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ToolChain * const bestTc = goodTcs.isEmpty() ? possibleTcs.first() : goodTcs.first())
|
||||||
ToolChainKitAspect::setAllToolChainsToMatch(k, bestTc);
|
ToolChainKitAspect::setAllToolChainsToMatch(k, bestTc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user