diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2019-10-10 11:04:01 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2019-10-11 12:49:06 +0000 |
commit | 5165c037ebbc3948d777595610bc62beb275a9a8 (patch) | |
tree | 892f6116167c2887df571ad341c1371af2848ab4 /src/plugins/projectexplorer/gcctoolchain.cpp | |
parent | 7a87dc0484bfe91ef7cba27e4b84993acd954beb (diff) |
Clang: Avoid consuming gcc internal include paths
Given the (default) include paths of GCC, e.g.
/usr/include/c++/7
/usr/include/x86_64-linux-gnu/c++/7
/usr/include/c++/7/backward
/usr/lib/gcc/x86_64-linux-gnu/7/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
discard gcc-internal paths like /usr/lib/gcc/x86_64-linux-gnu/7/include
as they are not relevant for clang and even confuse it with regard to
#include_next.
Paths below the gcc install dir are considered as gcc-internal. The
install dir is queried with
$ gcc -print-search-dirs
Some GCC distributions, like MinGW, ship the standard library headers in
the install dir. Ensure to not discard these.
Fixes: QTCREATORBUG-22898
Change-Id: Ia85258fb01b72ad073e71390e003fe8268e3b01f
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins/projectexplorer/gcctoolchain.cpp')
-rw-r--r-- | src/plugins/projectexplorer/gcctoolchain.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 8c1c9e2952b..e7616473986 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -232,6 +232,23 @@ static QString gccVersion(const FilePath &path, const QStringList &env) return QString::fromLocal8Bit(runGcc(path, arguments, env)).trimmed(); } +static Utils::FilePath gccInstallDir(const FilePath &path, const QStringList &env) +{ + const QStringList arguments("-print-search-dirs"); + QString output = QString::fromLocal8Bit(runGcc(path, arguments, env)).trimmed(); + // Expected output looks like this: + // install: /usr/lib/gcc/x86_64-linux-gnu/7/ + // ... + // Note that clang also supports "-print-search-dirs". However, the + // install dir is not part of the output (tested with clang-8/clang-9). + + const QString prefix = "install: "; + const QString line = QTextStream(&output).readLine(); + if (!line.startsWith(prefix)) + return {}; + return Utils::FilePath::fromString(QDir::cleanPath(line.mid(prefix.size()))); +} + // -------------------------------------------------------------------------- // GccToolChain // -------------------------------------------------------------------------- @@ -269,6 +286,15 @@ void GccToolChain::setOriginalTargetTriple(const QString &targetTriple) toolChainUpdated(); } +void GccToolChain::setInstallDir(const Utils::FilePath &installDir) +{ + if (m_installDir == installDir) + return; + + m_installDir = installDir; + toolChainUpdated(); +} + QString GccToolChain::defaultDisplayName() const { QString type = typeDisplayName(); @@ -310,6 +336,13 @@ QString GccToolChain::version() const return m_version; } +FilePath GccToolChain::installDir() const +{ + if (m_installDir.isEmpty()) + m_installDir = detectInstallDir(); + return m_installDir; +} + void GccToolChain::setTargetAbi(const Abi &abi) { if (abi == m_targetAbi) @@ -715,6 +748,7 @@ void GccToolChain::resetToolChain(const FilePath &path) const DetectedAbisResult detectedAbis = detectSupportedAbis(); m_supportedAbis = detectedAbis.supportedAbis; m_originalTargetTriple = detectedAbis.originalTargetTriple; + m_installDir = installDir(); m_targetAbi = Abi(); if (!m_supportedAbis.isEmpty()) { @@ -856,6 +890,13 @@ QString GccToolChain::detectVersion() const return gccVersion(findLocalCompiler(m_compilerCommand, env), env.toStringList()); } +Utils::FilePath GccToolChain::detectInstallDir() const +{ + Environment env = Environment::systemEnvironment(); + addToEnvironment(env); + return gccInstallDir(findLocalCompiler(m_compilerCommand, env), env.toStringList()); +} + // -------------------------------------------------------------------------- // GccToolChainFactory // -------------------------------------------------------------------------- @@ -1119,6 +1160,9 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const ToolChainDescr const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(localCompilerPath, systemEnvironment.toStringList(), macros); + const Utils::FilePath installDir = gccInstallDir(localCompilerPath, + systemEnvironment.toStringList()); + for (const Abi &abi : detectedAbis.supportedAbis) { std::unique_ptr<GccToolChain> tc(dynamic_cast<GccToolChain *>(create())); if (!tc) @@ -1134,6 +1178,7 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const ToolChainDescr tc->setSupportedAbis(detectedAbis.supportedAbis); tc->setTargetAbi(abi); tc->setOriginalTargetTriple(detectedAbis.originalTargetTriple); + tc->setInstallDir(installDir); tc->setDisplayName(tc->defaultDisplayName()); // reset displayname if (!checker || checker(tc.get())) result.append(tc.release()); @@ -1192,6 +1237,7 @@ void GccToolChainConfigWidget::applyImpl() tc->setSupportedAbis(m_abiWidget->supportedAbis()); tc->setTargetAbi(m_abiWidget->currentAbi()); } + tc->setInstallDir(tc->detectInstallDir()); tc->setOriginalTargetTriple(tc->detectSupportedAbis().originalTargetTriple); tc->setDisplayName(displayName); // reset display name tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text())); |