ProjectExplorer: Merge GccToolChainFactories further

This replaces the four classes from the GccToolChainFactories
hierarchy by a single (parametrized) GccToolChainFactory, but
makes the "RealGcc" one responsible for all autodetection.

This is a hack to move closer to a "scan only once" setup, and
temporarily necessary as there is currently one factory creates
one type of toolchain, so we need four factories for the current
four gcc-ish toolchain types.

Change-Id: Icbecb1be6e89cf5efad76baf92ef38ac63be074f
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2023-09-26 10:25:16 +02:00
parent 61048fa737
commit 4d2f3e8b01
4 changed files with 190 additions and 210 deletions

View File

@@ -1198,55 +1198,100 @@ static Utils::FilePaths renesasRl78SearchPathsFromRegistry()
return searchPaths; return searchPaths;
} }
GccToolChainFactory::GccToolChainFactory() static ToolChain *constructRealGccToolchain()
{ {
return new GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID, GccToolChain::RealGcc);
}
static ToolChain *constructClangToolchain()
{
return new GccToolChain(Constants::CLANG_TOOLCHAIN_TYPEID, GccToolChain::Clang);
}
static ToolChain *constructMinGWToolchain()
{
return new GccToolChain(Constants::MINGW_TOOLCHAIN_TYPEID, GccToolChain::MinGW);
}
static ToolChain *constructLinuxIccToolchain()
{
return new GccToolChain(Constants::LINUXICC_TOOLCHAIN_TYPEID, GccToolChain::LinuxIcc);
}
GccToolChainFactory::GccToolChainFactory(GccToolChain::SubType subType)
: m_autoDetecting(subType == GccToolChain::RealGcc)
{
switch (subType) {
case GccToolChain::RealGcc:
setDisplayName(Tr::tr("GCC")); setDisplayName(Tr::tr("GCC"));
setSupportedToolChainType(Constants::GCC_TOOLCHAIN_TYPEID); setSupportedToolChainType(Constants::GCC_TOOLCHAIN_TYPEID);
setToolchainConstructor(&constructRealGccToolchain);
break;
case GccToolChain::Clang:
setDisplayName(Tr::tr("Clang"));
setSupportedToolChainType(Constants::CLANG_TOOLCHAIN_TYPEID);
setToolchainConstructor(&constructClangToolchain);
break;
case GccToolChain::MinGW:
setDisplayName(Tr::tr("MinGW"));
setSupportedToolChainType(Constants::MINGW_TOOLCHAIN_TYPEID);
setToolchainConstructor(&constructMinGWToolchain);
break;
case GccToolChain::LinuxIcc:
setDisplayName(Tr::tr("ICC"));
setSupportedToolChainType(Constants::LINUXICC_TOOLCHAIN_TYPEID);
setToolchainConstructor(&constructLinuxIccToolchain);
break;
}
setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}); setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID});
setToolchainConstructor([] { return new GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID); });
setUserCreatable(true); setUserCreatable(true);
} }
Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) const Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) const
{ {
if (m_subType == GccToolChain::LinuxIcc) { Toolchains result;
Toolchains result = autoDetectToolchains("icpc",
// Do all autodetection in th 'RealGcc' case, and none in the others.
if (!m_autoDetecting)
return result;
// Linux ICC
result += autoDetectToolchains("icpc",
DetectVariants::No, DetectVariants::No,
Constants::CXX_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID,
Constants::LINUXICC_TOOLCHAIN_TYPEID, Constants::LINUXICC_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor()); &constructLinuxIccToolchain);
result += autoDetectToolchains("icc", result += autoDetectToolchains("icc",
DetectVariants::Yes, DetectVariants::Yes,
Constants::C_LANGUAGE_ID, Constants::C_LANGUAGE_ID,
Constants::LINUXICC_TOOLCHAIN_TYPEID, Constants::LINUXICC_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor()); &constructLinuxIccToolchain);
return result;
} // MinGW
if (m_subType == GccToolChain::MinGW) {
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;
}; };
Toolchains result = autoDetectToolchains("g++", result += autoDetectToolchains("g++",
DetectVariants::Yes, DetectVariants::Yes,
Constants::CXX_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID,
Constants::MINGW_TOOLCHAIN_TYPEID, Constants::MINGW_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor(), &constructMinGWToolchain,
tcChecker); tcChecker);
result += autoDetectToolchains("gcc", result += autoDetectToolchains("gcc",
DetectVariants::Yes, DetectVariants::Yes,
Constants::C_LANGUAGE_ID, Constants::C_LANGUAGE_ID,
Constants::MINGW_TOOLCHAIN_TYPEID, Constants::MINGW_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor(), &constructMinGWToolchain,
tcChecker); tcChecker);
return result;
}
if (m_subType == GccToolChain::Clang) { // Clang
Toolchains tcs; Toolchains tcs;
Toolchains known = detector.alreadyKnown; Toolchains known = detector.alreadyKnown;
@@ -1255,13 +1300,13 @@ Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) co
Constants::CXX_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID,
Constants::CLANG_TOOLCHAIN_TYPEID, Constants::CLANG_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor())); &constructClangToolchain));
tcs.append(autoDetectToolchains("clang", tcs.append(autoDetectToolchains("clang",
DetectVariants::Yes, DetectVariants::Yes,
Constants::C_LANGUAGE_ID, Constants::C_LANGUAGE_ID,
Constants::CLANG_TOOLCHAIN_TYPEID, Constants::CLANG_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor())); &constructClangToolchain));
known.append(tcs); known.append(tcs);
const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR); const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR);
@@ -1273,15 +1318,15 @@ Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) co
Constants::C_LANGUAGE_ID, Constants::C_LANGUAGE_ID,
Constants::CLANG_TOOLCHAIN_TYPEID, Constants::CLANG_TOOLCHAIN_TYPEID,
ToolchainDetector(known, detector.device, detector.searchPaths), ToolchainDetector(known, detector.device, detector.searchPaths),
toolchainConstructor())); &constructClangToolchain));
} }
return tcs; result += tcs;
}
// GCC is almost never what you want on macOS, but it is by default found in /usr/bin // GCC
if (HostOsInfo::isMacHost() && detector.device->type() == Constants::DESKTOP_DEVICE_TYPE)
return {}; // Gcc is almost never what you want on macOS, but it is by default found in /usr/bin
if (!HostOsInfo::isMacHost() || detector.device->type() != Constants::DESKTOP_DEVICE_TYPE) {
Toolchains tcs; Toolchains tcs;
static const auto tcChecker = [](const ToolChain *tc) { static const auto tcChecker = [](const ToolChain *tc) {
@@ -1294,31 +1339,40 @@ Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) co
Constants::CXX_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID,
Constants::GCC_TOOLCHAIN_TYPEID, Constants::GCC_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor(), &constructRealGccToolchain,
tcChecker)); tcChecker));
tcs.append(autoDetectToolchains("gcc", tcs.append(autoDetectToolchains("gcc",
DetectVariants::Yes, DetectVariants::Yes,
Constants::C_LANGUAGE_ID, Constants::C_LANGUAGE_ID,
Constants::GCC_TOOLCHAIN_TYPEID, Constants::GCC_TOOLCHAIN_TYPEID,
detector, detector,
toolchainConstructor(), &constructRealGccToolchain,
tcChecker)); tcChecker));
return tcs; result += tcs;
}
return result;
} }
Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
{ {
if (m_subType == GccToolChain::LinuxIcc) { Toolchains result;
// Do all autodetection in th 'RealGcc' case, and none in the others.
if (!m_autoDetecting)
return result;
const QString fileName = tcd.compilerPath.completeBaseName(); const QString fileName = tcd.compilerPath.completeBaseName();
const QString resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName();
// Linux ICC
if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) || if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) ||
(tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc"))) { (tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc"))) {
return autoDetectToolChain(tcd, toolchainConstructor()); result += autoDetectToolChain(tcd, &constructLinuxIccToolchain);
}
return {};
} }
if (m_subType == GccToolChain::MinGW) { // MingW
const QString fileName = tcd.compilerPath.completeBaseName();
const bool cCompiler = tcd.language == Constants::C_LANGUAGE_ID const bool cCompiler = tcd.language == Constants::C_LANGUAGE_ID
&& ((fileName.startsWith("gcc") || fileName.endsWith("gcc")) && ((fileName.startsWith("gcc") || fileName.endsWith("gcc"))
@@ -1329,51 +1383,43 @@ Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd)
|| (fileName.startsWith("c++") || fileName.endsWith("c++"))); || (fileName.startsWith("c++") || fileName.endsWith("c++")));
if (cCompiler || cxxCompiler) { if (cCompiler || cxxCompiler) {
return autoDetectToolChain(tcd, toolchainConstructor(), [](const ToolChain *tc) { result += autoDetectToolChain(tcd, &constructMinGWToolchain, [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor; return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor;
}); });
} }
return {}; // Clang
}
if (m_subType == GccToolChain::Clang) { bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
const QString fileName = tcd.compilerPath.completeBaseName();
const QString resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName();
const bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
&& ((fileName.startsWith("clang") && !fileName.startsWith("clang++")) && ((fileName.startsWith("clang") && !fileName.startsWith("clang++"))
|| (fileName == "cc" && resolvedSymlinksFileName.contains("clang"))); || (fileName == "cc" && resolvedSymlinksFileName.contains("clang")));
const bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID
&& (fileName.startsWith("clang++") && (fileName.startsWith("clang++")
|| (fileName == "c++" && resolvedSymlinksFileName.contains("clang"))); || (fileName == "c++" && resolvedSymlinksFileName.contains("clang")));
if (isCCompiler || isCxxCompiler) if (isCCompiler || isCxxCompiler)
return autoDetectToolChain(tcd, toolchainConstructor()); result += autoDetectToolChain(tcd, &constructClangToolchain);
return {}; // GCC
}
const QString fileName = tcd.compilerPath.completeBaseName(); isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
const QString resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName();
const bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
&& (fileName.startsWith("gcc") && (fileName.startsWith("gcc")
|| fileName.endsWith("gcc") || fileName.endsWith("gcc")
|| (fileName == "cc" && !resolvedSymlinksFileName.contains("clang"))); || (fileName == "cc" && !resolvedSymlinksFileName.contains("clang")));
const bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID
&& (fileName.startsWith("g++") && (fileName.startsWith("g++")
|| fileName.endsWith("g++") || fileName.endsWith("g++")
|| (fileName == "c++" && !resolvedSymlinksFileName.contains("clang"))); || (fileName == "c++" && !resolvedSymlinksFileName.contains("clang")));
if (isCCompiler || isCxxCompiler) { if (isCCompiler || isCxxCompiler) {
return autoDetectToolChain(tcd, toolchainConstructor(), [](const ToolChain *tc) { result += autoDetectToolChain(tcd, &constructRealGccToolchain, [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor; return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor;
}); });
} }
return {};
return result;
} }
static FilePaths findCompilerCandidates(const ToolchainDetector &detector, static FilePaths findCompilerCandidates(const ToolchainDetector &detector,
@@ -1910,22 +1956,6 @@ QString GccToolChain::sysRoot() const
return {}; return {};
} }
// --------------------------------------------------------------------------
// ClangToolChainFactory
// --------------------------------------------------------------------------
ClangToolChainFactory::ClangToolChainFactory()
{
m_subType = GccToolChain::Clang;
setDisplayName(Tr::tr("Clang"));
setSupportedToolChainType(Constants::CLANG_TOOLCHAIN_TYPEID);
setSupportedLanguages({Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID});
setToolchainConstructor([] {
return new GccToolChain(Constants::CLANG_TOOLCHAIN_TYPEID, GccToolChain::Clang);
});
}
void GccToolChainConfigWidget::updateParentToolChainComboBox() void GccToolChainConfigWidget::updateParentToolChainComboBox()
{ {
QTC_ASSERT(m_parentToolchainCombo, return); QTC_ASSERT(m_parentToolchainCombo, return);
@@ -1953,36 +1983,6 @@ void GccToolChainConfigWidget::updateParentToolChainComboBox()
} }
} }
// --------------------------------------------------------------------------
// MingwToolChainFactory
// --------------------------------------------------------------------------
MingwToolChainFactory::MingwToolChainFactory()
{
m_subType = GccToolChain::MinGW;
setDisplayName(Tr::tr("MinGW"));
setSupportedToolChainType(Constants::MINGW_TOOLCHAIN_TYPEID);
setSupportedLanguages({Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID});
setToolchainConstructor([] {
return new GccToolChain(Constants::MINGW_TOOLCHAIN_TYPEID, GccToolChain::MinGW);
});
}
// --------------------------------------------------------------------------
// LinuxIccToolChainFactory
// --------------------------------------------------------------------------
LinuxIccToolChainFactory::LinuxIccToolChainFactory()
{
m_subType = GccToolChain::LinuxIcc;
setDisplayName(Tr::tr("ICC"));
setSupportedToolChainType(Constants::LINUXICC_TOOLCHAIN_TYPEID);
setSupportedLanguages({Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID});
setToolchainConstructor([] {
return new GccToolChain(Constants::LINUXICC_TOOLCHAIN_TYPEID, GccToolChain::LinuxIcc);
});
}
GccToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag, WarningFlags &flags) : GccToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag, WarningFlags &flags) :
m_flags(flags) m_flags(flags)
{ {

View File

@@ -180,22 +180,18 @@ private:
QMetaObject::Connection m_thisToolchainRemovedConnection; QMetaObject::Connection m_thisToolchainRemovedConnection;
}; };
// --------------------------------------------------------------------------
// Factories
// --------------------------------------------------------------------------
namespace Internal { namespace Internal {
class GccToolChainFactory : public ToolChainFactory class GccToolChainFactory : public ToolChainFactory
{ {
public: public:
GccToolChainFactory(); explicit GccToolChainFactory(GccToolChain::SubType subType);
Toolchains autoDetect(const ToolchainDetector &detector) const final; Toolchains autoDetect(const ToolchainDetector &detector) const final;
Toolchains detectForImport(const ToolChainDescription &tcd) const final; Toolchains detectForImport(const ToolChainDescription &tcd) const final;
protected: private:
GccToolChain::SubType m_subType = GccToolChain::RealGcc;
enum class DetectVariants { Yes, No }; enum class DetectVariants { Yes, No };
using ToolchainChecker = std::function<bool(const ToolChain *)>; using ToolchainChecker = std::function<bool(const ToolChain *)>;
static Toolchains autoDetectToolchains(const QString &compilerName, static Toolchains autoDetectToolchains(const QString &compilerName,
@@ -208,24 +204,8 @@ protected:
static Toolchains autoDetectToolChain(const ToolChainDescription &tcd, static Toolchains autoDetectToolChain(const ToolChainDescription &tcd,
const ToolChainConstructor &constructor, const ToolChainConstructor &constructor,
const ToolchainChecker &checker = {}); const ToolchainChecker &checker = {});
};
class ClangToolChainFactory : public GccToolChainFactory const bool m_autoDetecting;
{
public:
ClangToolChainFactory();
};
class MingwToolChainFactory : public GccToolChainFactory
{
public:
MingwToolChainFactory();
};
class LinuxIccToolChainFactory : public GccToolChainFactory
{
public:
LinuxIccToolChainFactory();
}; };
} // namespace Internal } // namespace Internal

View File

@@ -626,15 +626,16 @@ public:
MsvcToolChainFactory m_mscvToolChainFactory; MsvcToolChainFactory m_mscvToolChainFactory;
ClangClToolChainFactory m_clangClToolChainFactory; ClangClToolChainFactory m_clangClToolChainFactory;
#else #else
LinuxIccToolChainFactory m_linuxToolChainFactory; GccToolChainFactory m_linuxToolChainFactory{GccToolChain::LinuxIcc};
#endif #endif
#ifndef Q_OS_MACOS #ifndef Q_OS_MACOS
MingwToolChainFactory m_mingwToolChainFactory; // Mingw offers cross-compiling to windows // Mingw offers cross-compiling to windows
GccToolChainFactory m_mingwToolChainFactory{GccToolChain::MinGW};
#endif #endif
GccToolChainFactory m_gccToolChainFactory; GccToolChainFactory m_gccToolChainFactory{GccToolChain::RealGcc};
ClangToolChainFactory m_clangToolChainFactory; GccToolChainFactory m_clangToolChainFactory{GccToolChain::Clang};
CustomToolChainFactory m_customToolChainFactory; CustomToolChainFactory m_customToolChainFactory;
DesktopDeviceFactory m_desktopDeviceFactory; DesktopDeviceFactory m_desktopDeviceFactory;

View File

@@ -671,8 +671,7 @@ void ToolChainFactory::setSupportsAllLanguages(bool supportsAllLanguages)
m_supportsAllLanguages = supportsAllLanguages; m_supportsAllLanguages = supportsAllLanguages;
} }
void ToolChainFactory::setToolchainConstructor void ToolChainFactory::setToolchainConstructor(const ToolChainConstructor &toolchainContructor)
(const ToolChainConstructor &toolchainContructor)
{ {
m_toolchainConstructor = toolchainContructor; m_toolchainConstructor = toolchainContructor;
} }