diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index e44370a0df0..477d0004812 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,56 @@ AndroidToolChain::AndroidToolChain(const AndroidToolChain &tc) : AndroidToolChain::~AndroidToolChain() { } +static QString getArch(const QString &triple) +{ + if (triple.indexOf("x86_64") == 0) + return "x86_64"; + if (triple.indexOf("i686") == 0) + return "x86"; + if (triple.indexOf("mips64") == 0) + return "mips64"; + if (triple.indexOf("mips") == 0) + return "mips"; + if (triple.indexOf("aarch64") == 0) + return "arm64-v8a"; + return "armeabi-v7a"; +} + +// Paths added here are those that were used by qmake. They were taken from +// *qtsource*/qtbase/mkspecs/common/android-base-head.conf +// Adding them here allows us to use them for all build systems. +static void addSystemHeaderPaths(QList &paths, + const QString &triple, const QString &version) +{ + const Utils::FileName ndkPath = AndroidConfigurations::currentConfig().ndkLocation(); + + // Get short version (for example 4.9) + const QString clangVersion = version.left(version.lastIndexOf('.')); + Utils::FileName stdcppPath = ndkPath; + stdcppPath.appendPath("sources/cxx-stl/gnu-libstdc++/" + clangVersion); + Utils::FileName includePath = stdcppPath; + Utils::FileName cppLibsPath = stdcppPath; + cppLibsPath.appendPath("libs/" + getArch(triple) + "/include/"); + paths.prepend({cppLibsPath.toString(), ProjectExplorer::HeaderPath::GlobalHeaderPath}); + includePath.appendPath("include/"); + paths.prepend({includePath.toString(), ProjectExplorer::HeaderPath::GlobalHeaderPath}); + + paths.prepend({ndkPath.toString() + "/sysroot/usr/include/" + triple, + ProjectExplorer::HeaderPath::GlobalHeaderPath}); + paths.prepend({ndkPath.toString() + "/sysroot/usr/include", + ProjectExplorer::HeaderPath::GlobalHeaderPath}); +} + +AndroidToolChain::SystemHeaderPathsRunner AndroidToolChain::createSystemHeaderPathsRunner() const +{ + const QString triple = originalTargetTriple(); + const QString version = this->version(); + initExtraHeaderPathsFunction([triple, version] (QList &paths) { + addSystemHeaderPaths(paths, triple, version); + }); + return GccToolChain::createSystemHeaderPathsRunner(); +} + QString AndroidToolChain::typeDisplayName() const { return AndroidToolChainFactory::tr("Android GCC"); @@ -246,7 +297,9 @@ void AndroidToolChain::setSecondaryToolChain(bool b) GccToolChain::DetectedAbisResult AndroidToolChain::detectSupportedAbis() const { - return QList() << targetAbi(); + GccToolChain::DetectedAbisResult supportedAbis = GccToolChain::detectSupportedAbis(); + supportedAbis.supportedAbis = {targetAbi()}; + return supportedAbis; } // -------------------------------------------------------------------------- @@ -415,6 +468,7 @@ AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath, ToolChain::AutoDetection); tc->resetToolChain(compilerPath); } + QTC_ASSERT(!tc->originalTargetTriple().isEmpty(), continue); result.append(tc); toolChainBundle.append(tc); } diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index 4efc29ecd0a..4d37e4ae079 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -45,7 +45,7 @@ public: bool operator ==(const ProjectExplorer::ToolChain &) const override; ProjectExplorer::ToolChainConfigWidget *configurationWidget() override; - virtual Utils::FileName suggestedDebugger() const override; + Utils::FileName suggestedDebugger() const override; Utils::FileName suggestedGdbServer() const; QVariantMap toMap() const override; @@ -58,6 +58,8 @@ public: bool isSecondaryToolChain() const; void setSecondaryToolChain(bool b); + SystemHeaderPathsRunner createSystemHeaderPathsRunner() const override; + protected: DetectedAbisResult detectSupportedAbis() const override; diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 8f1ed2c4166..af9ce9bf2cb 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -451,16 +451,10 @@ bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro if (macro.key == "__cplusplus") return true; - // gcc 4.9 has: - // #define __has_include(STR) __has_include__(STR) - // #define __has_include_next(STR) __has_include_next__(STR) - // The right-hand sides are gcc built-ins that clang does not understand, and they'd - // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand - // side. - if (isGccOrMinGwToolchain(m_projectPart.toolchainType) - && macro.key.contains("has_include")) { + // Ignore for all compiler toolchains since LLVM has it's own implementation for + // __has_include(STR) and __has_include_next(STR) + if (macro.key.startsWith("__has_include")) return true; - } // If _FORTIFY_SOURCE is defined (typically in release mode), it will // enable the inclusion of extra headers to help catching buffer overflows diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 7308564924c..58b6117d4c7 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -579,6 +579,46 @@ WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const return flags; } +QStringList GccToolChain::gccPrepareArguments(const QStringList &flags, + const QString &sysRoot, + const QStringList &platformCodeGenFlags, + Core::Id languageId, + OptionsReinterpreter reinterpretOptions) +{ + QStringList arguments; + const bool hasKitSysroot = !sysRoot.isEmpty(); + if (hasKitSysroot) + arguments.append(QString::fromLatin1("--sysroot=%1").arg(sysRoot)); + + QStringList allFlags; + allFlags << platformCodeGenFlags << flags; + for (int i = 0; i < allFlags.size(); ++i) { + const QString &flag = allFlags.at(i); + if (flag.startsWith("-stdlib=") || flag.startsWith("--gcctoolchain=")) { + arguments << flag; + } else if (!hasKitSysroot) { + // pass build system's sysroot to compiler, if we didn't pass one from kit + if (flag.startsWith("--sysroot=")) { + arguments << flag; + } else if ((flag.startsWith("-isysroot") || flag.startsWith("--sysroot")) + && i < flags.size() - 1) { + arguments << flag << allFlags.at(i + 1); + ++i; + } + } + } + arguments << languageOption(languageId) << "-E" << "-v" << "-"; + arguments = reinterpretOptions(arguments); + + return arguments; +} + +// NOTE: extraHeaderPathsFunction must NOT capture this or it's members!!! +void GccToolChain::initExtraHeaderPathsFunction(ExtraHeaderPathsFunction &&extraHeaderPathsFunction) const +{ + m_extraHeaderPathsFunction = std::move(extraHeaderPathsFunction); +} + ToolChain::SystemHeaderPathsRunner GccToolChain::createSystemHeaderPathsRunner() const { // Using a clean environment breaks ccache/distcc/etc. @@ -593,42 +633,21 @@ ToolChain::SystemHeaderPathsRunner GccToolChain::createSystemHeaderPathsRunner() Core::Id languageId = language(); // This runner must be thread-safe! - return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, headerCache, languageId] + return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, headerCache, languageId, + extraHeaderPathsFunction = m_extraHeaderPathsFunction] (const QStringList &flags, const QString &sysRoot) { - // Prepare arguments - QStringList arguments; - const bool hasKitSysroot = !sysRoot.isEmpty(); - if (hasKitSysroot) - arguments.append(QString::fromLatin1("--sysroot=%1").arg(sysRoot)); - QStringList allFlags; - allFlags << platformCodeGenFlags << flags; - for (int i = 0; i < allFlags.size(); ++i) { - const QString &flag = allFlags.at(i); - if (flag.startsWith("-stdlib=") || flag.startsWith("--gcctoolchain=")) { - arguments << flag; - } else if (!hasKitSysroot) { - // pass build system's sysroot to compiler, if we didn't pass one from kit - if (flag.startsWith("--sysroot=")) { - arguments << flag; - } else if ((flag.startsWith("-isysroot") || flag.startsWith("--sysroot")) - && i < flags.size() - 1) { - arguments << flag << allFlags.at(i + 1); - ++i; - } - } - } - - arguments << languageOption(languageId) << "-E" << "-v" << "-"; - arguments = reinterpretOptions(arguments); + QStringList arguments = gccPrepareArguments(flags, sysRoot, platformCodeGenFlags, + languageId, reinterpretOptions); const Utils::optional> cachedPaths = headerCache->check(arguments); if (cachedPaths) return cachedPaths.value(); - const QList paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env), - arguments, - env.toStringList()); + QList paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env), + arguments, + env.toStringList()); + extraHeaderPathsFunction(paths); headerCache->insert(arguments, paths); qCDebug(gccLog) << "Reporting header paths to code model:"; diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index ad1007c239b..f2b0795aab5 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -208,6 +208,10 @@ protected: // that passes the initial options directly down to the gcc compiler using OptionsReinterpreter = std::function; void setOptionsReinterpreter(const OptionsReinterpreter &optionsReinterpreter); + + using ExtraHeaderPathsFunction = std::function &)>; + void initExtraHeaderPathsFunction(ExtraHeaderPathsFunction &&extraHeaderPathsFunction) const; + static QList gccHeaderPaths(const Utils::FileName &gcc, const QStringList &args, const QStringList &env); class WarningFlagAdder @@ -229,6 +233,11 @@ private: explicit GccToolChain(Detection d); void updateSupportedAbis() const; + static QStringList gccPrepareArguments(const QStringList &flags, + const QString &sysRoot, + const QStringList &platformCodeGenFlags, + Core::Id languageId, + OptionsReinterpreter reinterpretOptions); Utils::FileName m_compilerCommand; QStringList m_platformCodeGenFlags; @@ -244,6 +253,7 @@ private: mutable std::shared_ptr, 64>> m_predefinedMacrosCache; mutable std::shared_ptr>> m_headerPathsCache; + mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](QList &) {}; friend class Internal::GccToolChainConfigWidget; friend class Internal::GccToolChainFactory;