ProjectExplorer: Avoid querying network compilers

...in case the network compiler is the first in PATH.

If e.g. /usr/lib/icecc/bin comes first in system PATH and it's the
compiler being auto-detected findLocalCompiler() returned
/usr/lib/icecc/bin instead of the real local compiler.

The "compilerPath" that findLocalCompiler() got was always additionally
prepended to the "env" it got. The additionally prepended one was
successfully skipped, but then it run into the original one.

Fix this by ensuring that findLocalCompiler() filters out all network
compilers and not only the first one.

Change-Id: Ia44eef67497d760714d72e8a28620f423c2860d2
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Nikolai Kosjar
2019-02-22 13:35:04 +01:00
committed by Christian Kandeler
parent 41da97fb2c
commit 478002acb7

View File

@@ -52,7 +52,6 @@
#include <QLoggingCategory>
#include <QRegularExpression>
#include <algorithm>
#include <memory>
namespace {
@@ -343,6 +342,11 @@ bool GccToolChain::isValid() const
return fi.isExecutable();
}
static bool isNetworkCompiler(const QString &dirPath)
{
return dirPath.contains("icecc") || dirPath.contains("distcc");
}
static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath,
const Environment &env)
{
@@ -351,21 +355,13 @@ static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath,
// Get the path to the compiler, ignoring direct calls to icecc and distcc as we cannot
// do anything about those.
const Utils::FileName compilerDir = compilerPath.parentDir();
const QString compilerDirString = compilerDir.toString();
if (!compilerDirString.contains("icecc") && !compilerDirString.contains("distcc"))
if (!isNetworkCompiler(compilerPath.parentDir().toString()))
return compilerPath;
FileNameList pathComponents = env.path();
auto it = std::find_if(pathComponents.begin(), pathComponents.end(),
[compilerDir](const FileName &p) {
return p == compilerDir;
// Filter out network compilers
const FileNameList pathComponents = Utils::filtered(env.path(), [] (const FileName &dirPath) {
return !isNetworkCompiler(dirPath.toString());
});
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.