From 2b7c5deadc91c1933f8748c16282eb282f2dc557 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 15 Sep 2017 17:33:16 +0200 Subject: [PATCH] GccToolChain: Improve findLocalCompiler Improve findLocalCompiler to better match the semantics of icecc/distcc. Task-number: QTCREATORBUG-18902 Change-Id: I06e7957d37bff449ce0188dd5d19e88d25f8e459 Reviewed-by: Orgad Shaneh --- src/plugins/projectexplorer/gcctoolchain.cpp | 32 +++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 9800908a53d..1948fdc178b 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -431,14 +431,32 @@ bool GccToolChain::isValid() const static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath, const Environment &env) { - const Utils::FileName path = env.searchInPath(compilerPath.fileName(), QStringList(), - [](const QString &pathEntry) { - return !pathEntry.contains("icecc") - && !pathEntry.contains("distcc"); - }); + // Find the "real" compiler if icecc, distcc or similar are in use. Ignore ccache, since that + // is local already. - QTC_ASSERT(!path.isEmpty(), return compilerPath); - return path; + // Get the path to the compiler, ignoring direct calls to icecc and distcc as we can not + // do anything about those. + const Utils::FileName compilerDir = compilerPath.parentDir(); + const QString compilerDirString = compilerDir.toString(); + if (!compilerDirString.contains("icecc") && !compilerDirString.contains("distcc")) + return compilerPath; + + QStringList pathComponents = env.path(); + auto it = std::find_if(pathComponents.begin(), pathComponents.end(), + [compilerDir](const QString &p) { + return Utils::FileName::fromString(p) == compilerDir; + }); + if (it != pathComponents.end()) { + std::rotate(pathComponents.begin(), it, pathComponents.end()); + pathComponents.removeFirst(); // remove directory of compilerPath + // No need to put it at the end again, it is in PATH anyway... + } + + // This effectively searches the PATH twice, once via pathComponents and once via PATH itself: + // searchInPath filters duplicates, so that will not hurt. + const Utils::FileName path = env.searchInPath(compilerPath.fileName(), pathComponents); + + return path.isEmpty() ? compilerPath : path; } ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() const