diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 084fd9c8f33..ff5387d63a3 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -1198,182 +1198,228 @@ static Utils::FilePaths renesasRl78SearchPathsFromRegistry() return searchPaths; } -GccToolChainFactory::GccToolChainFactory() +static ToolChain *constructRealGccToolchain() { - setDisplayName(Tr::tr("GCC")); - setSupportedToolChainType(Constants::GCC_TOOLCHAIN_TYPEID); + 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")); + 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}); - setToolchainConstructor([] { return new GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID); }); setUserCreatable(true); } Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) const { - if (m_subType == GccToolChain::LinuxIcc) { - Toolchains result = autoDetectToolchains("icpc", - DetectVariants::No, - Constants::CXX_LANGUAGE_ID, - Constants::LINUXICC_TOOLCHAIN_TYPEID, - detector, - toolchainConstructor()); - result += autoDetectToolchains("icc", - DetectVariants::Yes, - Constants::C_LANGUAGE_ID, - Constants::LINUXICC_TOOLCHAIN_TYPEID, - detector, - toolchainConstructor()); + Toolchains result; + + // Do all autodetection in th 'RealGcc' case, and none in the others. + if (!m_autoDetecting) return result; - } - if (m_subType == GccToolChain::MinGW) { - static const auto tcChecker = [](const ToolChain *tc) { - return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor; - }; - Toolchains result = autoDetectToolchains("g++", - DetectVariants::Yes, - Constants::CXX_LANGUAGE_ID, - Constants::MINGW_TOOLCHAIN_TYPEID, - detector, - toolchainConstructor(), - tcChecker); - result += autoDetectToolchains("gcc", - DetectVariants::Yes, - Constants::C_LANGUAGE_ID, - Constants::MINGW_TOOLCHAIN_TYPEID, - detector, - toolchainConstructor(), - tcChecker); - return result; - } + // Linux ICC - if (m_subType == GccToolChain::Clang) { - Toolchains tcs; - Toolchains known = detector.alreadyKnown; + result += autoDetectToolchains("icpc", + DetectVariants::No, + Constants::CXX_LANGUAGE_ID, + Constants::LINUXICC_TOOLCHAIN_TYPEID, + detector, + &constructLinuxIccToolchain); + result += autoDetectToolchains("icc", + DetectVariants::Yes, + Constants::C_LANGUAGE_ID, + Constants::LINUXICC_TOOLCHAIN_TYPEID, + detector, + &constructLinuxIccToolchain); - tcs.append(autoDetectToolchains("clang++", - DetectVariants::Yes, - Constants::CXX_LANGUAGE_ID, - Constants::CLANG_TOOLCHAIN_TYPEID, - detector, - toolchainConstructor())); - tcs.append(autoDetectToolchains("clang", - DetectVariants::Yes, - Constants::C_LANGUAGE_ID, - Constants::CLANG_TOOLCHAIN_TYPEID, - detector, - toolchainConstructor())); - known.append(tcs); + // MinGW - const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR); - if (!compilerPath.isEmpty()) { - const FilePath clang = compilerPath.parentDir().pathAppended("clang").withExecutableSuffix(); - tcs.append( - autoDetectToolchains(clang.toString(), - DetectVariants::No, - Constants::C_LANGUAGE_ID, - Constants::CLANG_TOOLCHAIN_TYPEID, - ToolchainDetector(known, detector.device, detector.searchPaths), - toolchainConstructor())); - } + static const auto tcChecker = [](const ToolChain *tc) { + return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor; + }; + result += autoDetectToolchains("g++", + DetectVariants::Yes, + Constants::CXX_LANGUAGE_ID, + Constants::MINGW_TOOLCHAIN_TYPEID, + detector, + &constructMinGWToolchain, + tcChecker); + result += autoDetectToolchains("gcc", + DetectVariants::Yes, + Constants::C_LANGUAGE_ID, + Constants::MINGW_TOOLCHAIN_TYPEID, + detector, + &constructMinGWToolchain, + tcChecker); - return tcs; - } - - // 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) - return {}; + // Clang Toolchains tcs; - static const auto tcChecker = [](const ToolChain *tc) { - return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor - && tc->compilerCommand().fileName() != "c89-gcc" - && tc->compilerCommand().fileName() != "c99-gcc"; - }; - tcs.append(autoDetectToolchains("g++", + Toolchains known = detector.alreadyKnown; + + tcs.append(autoDetectToolchains("clang++", DetectVariants::Yes, Constants::CXX_LANGUAGE_ID, - Constants::GCC_TOOLCHAIN_TYPEID, + Constants::CLANG_TOOLCHAIN_TYPEID, detector, - toolchainConstructor(), - tcChecker)); - tcs.append(autoDetectToolchains("gcc", + &constructClangToolchain)); + tcs.append(autoDetectToolchains("clang", DetectVariants::Yes, Constants::C_LANGUAGE_ID, - Constants::GCC_TOOLCHAIN_TYPEID, + Constants::CLANG_TOOLCHAIN_TYPEID, detector, - toolchainConstructor(), - tcChecker)); - return tcs; + &constructClangToolchain)); + known.append(tcs); + + const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR); + if (!compilerPath.isEmpty()) { + const FilePath clang = compilerPath.parentDir().pathAppended("clang").withExecutableSuffix(); + tcs.append( + autoDetectToolchains(clang.toString(), + DetectVariants::No, + Constants::C_LANGUAGE_ID, + Constants::CLANG_TOOLCHAIN_TYPEID, + ToolchainDetector(known, detector.device, detector.searchPaths), + &constructClangToolchain)); + } + + result += tcs; + + // GCC + + // 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; + static const auto tcChecker = [](const ToolChain *tc) { + return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor + && tc->compilerCommand().fileName() != "c89-gcc" + && tc->compilerCommand().fileName() != "c99-gcc"; + }; + tcs.append(autoDetectToolchains("g++", + DetectVariants::Yes, + Constants::CXX_LANGUAGE_ID, + Constants::GCC_TOOLCHAIN_TYPEID, + detector, + &constructRealGccToolchain, + tcChecker)); + tcs.append(autoDetectToolchains("gcc", + DetectVariants::Yes, + Constants::C_LANGUAGE_ID, + Constants::GCC_TOOLCHAIN_TYPEID, + detector, + &constructRealGccToolchain, + tcChecker)); + result += tcs; + } + + return result; } Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const { - if (m_subType == GccToolChain::LinuxIcc) { - const QString fileName = tcd.compilerPath.completeBaseName(); - if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) || - (tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc"))) { - return autoDetectToolChain(tcd, toolchainConstructor()); - } - return {}; - } + Toolchains result; - if (m_subType == GccToolChain::MinGW) { - const QString fileName = tcd.compilerPath.completeBaseName(); - - const bool cCompiler = tcd.language == Constants::C_LANGUAGE_ID - && ((fileName.startsWith("gcc") || fileName.endsWith("gcc")) - || fileName == "cc"); - - const bool cxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID - && ((fileName.startsWith("g++") || fileName.endsWith("g++")) - || (fileName.startsWith("c++") || fileName.endsWith("c++"))); - - if (cCompiler || cxxCompiler) { - return autoDetectToolChain(tcd, toolchainConstructor(), [](const ToolChain *tc) { - return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor; - }); - } - - return {}; - } - - if (m_subType == GccToolChain::Clang) { - 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 == "cc" && resolvedSymlinksFileName.contains("clang"))); - - const bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID - && (fileName.startsWith("clang++") - || (fileName == "c++" && resolvedSymlinksFileName.contains("clang"))); - - if (isCCompiler || isCxxCompiler) - return autoDetectToolChain(tcd, toolchainConstructor()); - - return {}; - } + // 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 resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName(); - const bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID + // Linux ICC + + if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) || + (tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc"))) { + result += autoDetectToolChain(tcd, &constructLinuxIccToolchain); + } + + // MingW + + const bool cCompiler = tcd.language == Constants::C_LANGUAGE_ID + && ((fileName.startsWith("gcc") || fileName.endsWith("gcc")) + || fileName == "cc"); + + const bool cxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID + && ((fileName.startsWith("g++") || fileName.endsWith("g++")) + || (fileName.startsWith("c++") || fileName.endsWith("c++"))); + + if (cCompiler || cxxCompiler) { + result += autoDetectToolChain(tcd, &constructMinGWToolchain, [](const ToolChain *tc) { + return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor; + }); + } + + // Clang + + bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID + && ((fileName.startsWith("clang") && !fileName.startsWith("clang++")) + || (fileName == "cc" && resolvedSymlinksFileName.contains("clang"))); + + bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID + && (fileName.startsWith("clang++") + || (fileName == "c++" && resolvedSymlinksFileName.contains("clang"))); + + if (isCCompiler || isCxxCompiler) + result += autoDetectToolChain(tcd, &constructClangToolchain); + + // GCC + + isCCompiler = tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc") || fileName.endsWith("gcc") || (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.endsWith("g++") || (fileName == "c++" && !resolvedSymlinksFileName.contains("clang"))); if (isCCompiler || isCxxCompiler) { - return autoDetectToolChain(tcd, toolchainConstructor(), [](const ToolChain *tc) { + result += autoDetectToolChain(tcd, &constructRealGccToolchain, [](const ToolChain *tc) { return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor; }); } - return {}; + + return result; } static FilePaths findCompilerCandidates(const ToolchainDetector &detector, @@ -1910,22 +1956,6 @@ QString GccToolChain::sysRoot() const 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() { 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) : m_flags(flags) { diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 7694cc524c4..fb8909d3881 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -180,22 +180,18 @@ private: QMetaObject::Connection m_thisToolchainRemovedConnection; }; -// -------------------------------------------------------------------------- -// Factories -// -------------------------------------------------------------------------- namespace Internal { + class GccToolChainFactory : public ToolChainFactory { public: - GccToolChainFactory(); + explicit GccToolChainFactory(GccToolChain::SubType subType); Toolchains autoDetect(const ToolchainDetector &detector) const final; Toolchains detectForImport(const ToolChainDescription &tcd) const final; -protected: - GccToolChain::SubType m_subType = GccToolChain::RealGcc; - +private: enum class DetectVariants { Yes, No }; using ToolchainChecker = std::function; static Toolchains autoDetectToolchains(const QString &compilerName, @@ -208,24 +204,8 @@ protected: static Toolchains autoDetectToolChain(const ToolChainDescription &tcd, const ToolChainConstructor &constructor, const ToolchainChecker &checker = {}); -}; -class ClangToolChainFactory : public GccToolChainFactory -{ -public: - ClangToolChainFactory(); -}; - -class MingwToolChainFactory : public GccToolChainFactory -{ -public: - MingwToolChainFactory(); -}; - -class LinuxIccToolChainFactory : public GccToolChainFactory -{ -public: - LinuxIccToolChainFactory(); + const bool m_autoDetecting; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 3b199217212..b85e7abafce 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -626,15 +626,16 @@ public: MsvcToolChainFactory m_mscvToolChainFactory; ClangClToolChainFactory m_clangClToolChainFactory; #else - LinuxIccToolChainFactory m_linuxToolChainFactory; + GccToolChainFactory m_linuxToolChainFactory{GccToolChain::LinuxIcc}; #endif #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 - GccToolChainFactory m_gccToolChainFactory; - ClangToolChainFactory m_clangToolChainFactory; + GccToolChainFactory m_gccToolChainFactory{GccToolChain::RealGcc}; + GccToolChainFactory m_clangToolChainFactory{GccToolChain::Clang}; CustomToolChainFactory m_customToolChainFactory; DesktopDeviceFactory m_desktopDeviceFactory; diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index f4ceb06720d..5d51c501715 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -671,8 +671,7 @@ void ToolChainFactory::setSupportsAllLanguages(bool supportsAllLanguages) m_supportsAllLanguages = supportsAllLanguages; } -void ToolChainFactory::setToolchainConstructor - (const ToolChainConstructor &toolchainContructor) +void ToolChainFactory::setToolchainConstructor(const ToolChainConstructor &toolchainContructor) { m_toolchainConstructor = toolchainContructor; }