diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index b8392f5cdf3..39819a3d590 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -302,13 +302,13 @@ ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner HeaderPathsCachePtr headerPathsCache = m_headerPathsCache; - return [env, compilerCommand, headerPathsCache, languageId] - (const QStringList &flags, const QString &fileName) { + return [env, compilerCommand, headerPathsCache, languageId](const QStringList &flags, + const QString &fileName, + const QString &) { Q_UNUSED(flags) Q_UNUSED(fileName) - const HeaderPaths paths = dumpHeaderPaths(compilerCommand, languageId, - env.toStringList()); + const HeaderPaths paths = dumpHeaderPaths(compilerCommand, languageId, env.toStringList()); headerPathsCache->insert({}, paths); return paths; @@ -318,7 +318,7 @@ ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner HeaderPaths IarToolChain::builtInHeaderPaths(const QStringList &cxxFlags, const FileName &fileName) const { - return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString()); + return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), ""); } void IarToolChain::addToEnvironment(Environment &env) const diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index 647fbb8f133..c7d62677aad 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -315,8 +315,8 @@ ToolChain::BuiltInHeaderPathsRunner KeilToolchain::createBuiltInHeaderPathsRunne HeaderPathsCachePtr headerPathsCache = m_headerPathsCache; - return [compilerCommand, headerPathsCache] - (const QStringList &flags, const QString &fileName) { + return [compilerCommand, + headerPathsCache](const QStringList &flags, const QString &fileName, const QString &) { Q_UNUSED(flags) Q_UNUSED(fileName) @@ -330,7 +330,7 @@ ToolChain::BuiltInHeaderPathsRunner KeilToolchain::createBuiltInHeaderPathsRunne HeaderPaths KeilToolchain::builtInHeaderPaths(const QStringList &cxxFlags, const FileName &fileName) const { - return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString()); + return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), ""); } void KeilToolchain::addToEnvironment(Environment &env) const diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index 4c9bbfbf7fc..7551e1744a4 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -298,13 +298,13 @@ ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunne HeaderPathsCachePtr headerPathsCache = m_headerPathsCache; - return [env, compilerCommand, headerPathsCache, languageId, abi] - (const QStringList &flags, const QString &fileName) { + return [env, compilerCommand, headerPathsCache, languageId, abi](const QStringList &flags, + const QString &fileName, + const QString &) { Q_UNUSED(flags) Q_UNUSED(fileName) - const HeaderPaths paths = dumpHeaderPaths(compilerCommand, env.toStringList(), - abi); + const HeaderPaths paths = dumpHeaderPaths(compilerCommand, env.toStringList(), abi); headerPathsCache->insert({}, paths); return paths; @@ -312,9 +312,9 @@ ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunne } HeaderPaths SdccToolChain::builtInHeaderPaths(const QStringList &cxxFlags, - const FileName &fileName) const + const FileName &fileName) const { - return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString()); + return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), ""); } void SdccToolChain::addToEnvironment(Environment &env) const diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index 32a7151397e..a4750070504 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -92,6 +92,11 @@ bool isGccCompiler(const QString &compilerName) || (compilerName.contains("g++") && !compilerName.contains("clang")); } +bool isClCompatibleCompiler(const QString &compilerName) +{ + return compilerName.endsWith("cl"); +} + Core::Id getCompilerId(QString compilerName) { if (Utils::HostOsInfo::isWindowsHost()) { @@ -99,9 +104,9 @@ Core::Id getCompilerId(QString compilerName) compilerName.chop(4); if (isGccCompiler(compilerName)) return ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID; - - // Default is clang-cl - return ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID; + if (isClCompatibleCompiler(compilerName)) + return ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID; + return ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID; } if (isGccCompiler(compilerName)) return ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID; @@ -196,8 +201,7 @@ void addDriverModeFlagIfNeeded(const ToolChain *toolchain, CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile, Kit *kit, - ToolChain *&cToolchain, - ToolChain *&cxxToolchain, + CppTools::KitInfo &kitInfo, const QString &workingDir, const Utils::FileName &fileName, QStringList flags) @@ -212,7 +216,8 @@ CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile, flags, headerPaths, macros, - fileKind); + fileKind, + kitInfo.sysRootPath); CppTools::RawProjectPart rpp; rpp.setProjectFileLocation(projectFile.toString()); @@ -224,21 +229,23 @@ CppTools::RawProjectPart makeRawProjectPart(const Utils::FileName &projectFile, if (fileKind == CppTools::ProjectFile::Kind::CHeader || fileKind == CppTools::ProjectFile::Kind::CSource) { - if (!cToolchain) { - cToolchain = toolchainFromFlags(kit, originalFlags, - ProjectExplorer::Constants::C_LANGUAGE_ID); - ToolChainKitAspect::setToolChain(kit, cToolchain); + if (!kitInfo.cToolChain) { + kitInfo.cToolChain = toolchainFromFlags(kit, + originalFlags, + ProjectExplorer::Constants::C_LANGUAGE_ID); + ToolChainKitAspect::setToolChain(kit, kitInfo.cToolChain); } - addDriverModeFlagIfNeeded(cToolchain, flags, originalFlags); - rpp.setFlagsForC({cToolchain, flags}); + addDriverModeFlagIfNeeded(kitInfo.cToolChain, flags, originalFlags); + rpp.setFlagsForC({kitInfo.cToolChain, flags}); } else { - if (!cxxToolchain) { - cxxToolchain = toolchainFromFlags(kit, originalFlags, - ProjectExplorer::Constants::CXX_LANGUAGE_ID); - ToolChainKitAspect::setToolChain(kit, cxxToolchain); + if (!kitInfo.cxxToolChain) { + kitInfo.cxxToolChain = toolchainFromFlags(kit, + originalFlags, + ProjectExplorer::Constants::CXX_LANGUAGE_ID); + ToolChainKitAspect::setToolChain(kit, kitInfo.cxxToolChain); } - addDriverModeFlagIfNeeded(cxxToolchain, flags, originalFlags); - rpp.setFlagsForCxx({cxxToolchain, flags}); + addDriverModeFlagIfNeeded(kitInfo.cxxToolChain, flags, originalFlags); + rpp.setFlagsForCxx({kitInfo.cxxToolChain, flags}); } return rpp; @@ -433,8 +440,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts(const Utils::FileName CppTools::RawProjectPart rpp = makeRawProjectPart(projectFile, m_kit.get(), - kitInfo.cToolChain, - kitInfo.cxxToolChain, + kitInfo, entry.workingDir, entry.fileName, entry.flags); diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp index 31dbcadf944..ff931cc3879 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp @@ -98,7 +98,8 @@ void filteredFlags(const QString &fileName, QStringList &flags, HeaderPaths &headerPaths, Macros ¯os, - CppTools::ProjectFile::Kind &fileKind) + CppTools::ProjectFile::Kind &fileKind, + QString &sysRoot) { if (flags.empty()) return; @@ -182,6 +183,12 @@ void filteredFlags(const QString &fileName, continue; } + if (flag.startsWith("--sysroot=")) { + if (sysRoot.isEmpty()) + sysRoot = flag.mid(10); + continue; + } + if ((flag.startsWith("-std=") || flag.startsWith("/std:")) && fileKind == CppTools::ProjectFile::Unclassified) { const bool cpp = (flag.contains("c++") || flag.contains("gnu++")); diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h index 52b251723a9..be3c7939201 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.h @@ -45,7 +45,8 @@ void filteredFlags(const QString &fileName, QStringList &flags, QVector &headerPaths, QVector ¯os, - CppTools::ProjectFile::Kind &fileKind); + CppTools::ProjectFile::Kind &fileKind, + QString &sysRoot); QStringList splitCommandLine(QString commandLine, QSet &flagsCache); diff --git a/src/plugins/cpptools/cppprojectinfogenerator.cpp b/src/plugins/cpptools/cppprojectinfogenerator.cpp index c177c7a7d91..f50f003263e 100644 --- a/src/plugins/cpptools/cppprojectinfogenerator.cpp +++ b/src/plugins/cpptools/cppprojectinfogenerator.cpp @@ -182,7 +182,9 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart( // Header paths if (tcInfo.headerPathsRunner) { const ProjectExplorer::HeaderPaths builtInHeaderPaths - = tcInfo.headerPathsRunner(flags.commandLineFlags, tcInfo.sysRootPath); + = tcInfo.headerPathsRunner(flags.commandLineFlags, + tcInfo.sysRootPath, + tcInfo.targetTriple); ProjectExplorer::HeaderPaths &headerPaths = part->headerPaths; for (const ProjectExplorer::HeaderPath &header : builtInHeaderPaths) { diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index 0a1a2e5b050..599ed387ce1 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -169,7 +169,7 @@ ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRun const HeaderPaths builtInHeaderPaths = m_builtInHeaderPaths; // This runner must be thread-safe! - return [builtInHeaderPaths](const QStringList &cxxFlags, const QString &) { + return [builtInHeaderPaths](const QStringList &cxxFlags, const QString &, const QString &) { HeaderPaths flagHeaderPaths; for (const QString &cxxFlag : cxxFlags) { if (cxxFlag.startsWith(QLatin1String("-I"))) { @@ -184,7 +184,7 @@ ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRun HeaderPaths CustomToolChain::builtInHeaderPaths(const QStringList &cxxFlags, const FileName &fileName) const { - return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString()); + return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), ""); } void CustomToolChain::addToEnvironment(Environment &env) const diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 6f1d076621c..c11552582a6 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -569,52 +569,83 @@ void GccToolChain::initExtraHeaderPathsFunction(ExtraHeaderPathsFunction &&extra m_extraHeaderPathsFunction = std::move(extraHeaderPathsFunction); } +HeaderPaths GccToolChain::builtInHeaderPaths(const Utils::Environment &env, + const Utils::FileName &compilerCommand, + const QStringList &platformCodeGenFlags, + OptionsReinterpreter reinterpretOptions, + std::shared_ptr> headerCache, + Core::Id languageId, + ExtraHeaderPathsFunction extraHeaderPathsFunction, + const QStringList &flags, + const QString &sysRoot, + const QString &originalTargetTriple) +{ + QStringList arguments = gccPrepareArguments(flags, + sysRoot, + platformCodeGenFlags, + languageId, + reinterpretOptions); + + // Must be clang case only. + if (!originalTargetTriple.isEmpty()) + arguments << "-target" << originalTargetTriple; + + const Utils::optional cachedPaths = headerCache->check(arguments); + if (cachedPaths) + return cachedPaths.value(); + + HeaderPaths paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env), + arguments, + env.toStringList()); + extraHeaderPathsFunction(paths); + headerCache->insert(arguments, paths); + + qCDebug(gccLog) << "Reporting header paths to code model:"; + for (const HeaderPath &hp : paths) { + qCDebug(gccLog) << compilerCommand.toUserOutput() + << (languageId == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [") + << arguments.join(", ") << "]" << hp.path; + } + + return paths; +} + ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner() const { // Using a clean environment breaks ccache/distcc/etc. Environment env = Environment::systemEnvironment(); addToEnvironment(env); - const Utils::FileName compilerCommand = m_compilerCommand; - const QStringList platformCodeGenFlags = m_platformCodeGenFlags; - OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter; - QTC_CHECK(reinterpretOptions); - std::shared_ptr> headerCache = m_headerPathsCache; - Core::Id languageId = language(); - // This runner must be thread-safe! - return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, headerCache, languageId, - extraHeaderPathsFunction = m_extraHeaderPathsFunction] - (const QStringList &flags, const QString &sysRoot) { - - QStringList arguments = gccPrepareArguments(flags, sysRoot, platformCodeGenFlags, - languageId, reinterpretOptions); - - const Utils::optional cachedPaths = headerCache->check(arguments); - if (cachedPaths) - return cachedPaths.value(); - - HeaderPaths paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env), - arguments, env.toStringList()); - extraHeaderPathsFunction(paths); - headerCache->insert(arguments, paths); - - qCDebug(gccLog) << "Reporting header paths to code model:"; - for (const HeaderPath &hp : paths) { - qCDebug(gccLog) << compilerCommand.toUserOutput() - << (languageId == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [") - << arguments.join(", ") << "]" - << hp.path; - } - - return paths; + return [env, + compilerCommand = m_compilerCommand, + platformCodeGenFlags = m_platformCodeGenFlags, + reinterpretOptions = m_optionsReinterpreter, + headerCache = m_headerPathsCache, + languageId = language(), + extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags, + const QString &sysRoot, + const QString &) { + return builtInHeaderPaths(env, + compilerCommand, + platformCodeGenFlags, + reinterpretOptions, + headerCache, + languageId, + extraHeaderPathsFunction, + flags, + sysRoot, + /*target=*/""); // Target must be empty for gcc. }; } HeaderPaths GccToolChain::builtInHeaderPaths(const QStringList &flags, - const FileName &sysRoot) const + const FileName &sysRootPath) const { - return createBuiltInHeaderPathsRunner()(flags, sysRoot.toString()); + return createBuiltInHeaderPathsRunner()(flags, + sysRootPath.isEmpty() ? sysRoot() + : sysRootPath.toString(), + originalTargetTriple()); } void GccToolChain::addCommandPathToEnvironment(const FileName &command, Environment &env) @@ -1398,6 +1429,35 @@ QString ClangToolChain::sysRoot() const return mingwCompiler.parentDir().parentDir().toString(); } +ToolChain::BuiltInHeaderPathsRunner ClangToolChain::createBuiltInHeaderPathsRunner() const +{ + // Using a clean environment breaks ccache/distcc/etc. + Environment env = Environment::systemEnvironment(); + addToEnvironment(env); + + // This runner must be thread-safe! + return [env, + compilerCommand = m_compilerCommand, + platformCodeGenFlags = m_platformCodeGenFlags, + reinterpretOptions = m_optionsReinterpreter, + headerCache = m_headerPathsCache, + languageId = language(), + extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags, + const QString &sysRoot, + const QString &target) { + return builtInHeaderPaths(env, + compilerCommand, + platformCodeGenFlags, + reinterpretOptions, + headerCache, + languageId, + extraHeaderPathsFunction, + flags, + sysRoot, + target); + }; +} + std::unique_ptr ClangToolChain::createConfigurationWidget() { return std::make_unique(this); diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index b34614cde88..bace4cc96be 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -86,7 +86,7 @@ public: BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; HeaderPaths builtInHeaderPaths(const QStringList &flags, - const Utils::FileName &sysRoot) const override; + const Utils::FileName &sysRootPath) const override; void addToEnvironment(Utils::Environment &env) const override; QString makeCommand(const Utils::Environment &environment) const override; @@ -151,6 +151,17 @@ protected: using ExtraHeaderPathsFunction = std::function; void initExtraHeaderPathsFunction(ExtraHeaderPathsFunction &&extraHeaderPathsFunction) const; + static HeaderPaths builtInHeaderPaths(const Utils::Environment &env, + const Utils::FileName &compilerCommand, + const QStringList &platformCodeGenFlags, + OptionsReinterpreter reinterpretOptions, + std::shared_ptr> headerCache, + Core::Id languageId, + ExtraHeaderPathsFunction extraHeaderPathsFunction, + const QStringList &flags, + const QString &sysRoot, + const QString &originalTargetTriple); + static HeaderPaths gccHeaderPaths(const Utils::FileName &gcc, const QStringList &args, const QStringList &env); @@ -179,12 +190,16 @@ private: Core::Id languageId, OptionsReinterpreter reinterpretOptions); +protected: Utils::FileName m_compilerCommand; QStringList m_platformCodeGenFlags; QStringList m_platformLinkerFlags; OptionsReinterpreter m_optionsReinterpreter = [](const QStringList &v) { return v; }; + mutable std::shared_ptr> m_headerPathsCache; + mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {}; +private: Abi m_targetAbi; mutable QList m_supportedAbis; mutable QString m_originalTargetTriple; @@ -192,8 +207,6 @@ private: mutable QString m_version; mutable std::shared_ptr> m_predefinedMacrosCache; - mutable std::shared_ptr> m_headerPathsCache; - mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {}; friend class Internal::GccToolChainConfigWidget; friend class Internal::GccToolChainFactory; @@ -226,6 +239,8 @@ public: QString originalTargetTriple() const override; QString sysRoot() const override; + BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; + std::unique_ptr createConfigurationWidget() override; QVariantMap toMap() const override; diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 9c86a706869..021076f8608 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -1131,7 +1131,7 @@ ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunne Utils::Environment env(m_lastEnvironment); addToEnvironment(env); - return [this, env](const QStringList &, const QString &) { + return [this, env](const QStringList &, const QString &, const QString &) { QMutexLocker locker(m_headerPathsMutex); if (m_headerPaths.isEmpty()) { foreach (const QString &path, @@ -1146,7 +1146,7 @@ ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunne HeaderPaths MsvcToolChain::builtInHeaderPaths(const QStringList &cxxflags, const Utils::FileName &sysRoot) const { - return createBuiltInHeaderPathsRunner()(cxxflags, sysRoot.toString()); + return createBuiltInHeaderPathsRunner()(cxxflags, sysRoot.toString(), ""); } void MsvcToolChain::addToEnvironment(Utils::Environment &env) const diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index f5c80c12b67..84d005ff3db 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -126,11 +126,11 @@ public: virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0; // A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread. - using BuiltInHeaderPathsRunner = std::function; + using BuiltInHeaderPathsRunner = std::function; virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const = 0; virtual HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, - const Utils::FileName &sysRoot) const = 0; + const Utils::FileName &sysRoot) const = 0; virtual void addToEnvironment(Utils::Environment &env) const = 0; virtual QString makeCommand(const Utils::Environment &env) const = 0;