ClangTools: Use resource dir from tool instead of hard-coded one

This makes it more likely that using other clang-tidy and clazy binaries
than the ones shipped with Qt Creator will work.

Done-with: Nikolai Kosjar
Fixes: QTCREATORBUG-23672
Change-Id: I8c44e037ca8d50505fe10032034edaf4f408d52c
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Nikolai Kosjar
2020-05-29 15:46:26 +02:00
committed by Christian Kandeler
parent 119a3c1ce9
commit 8cb74f88f9
4 changed files with 72 additions and 10 deletions

View File

@@ -31,6 +31,7 @@
#include "clangtoolsprojectsettings.h" #include "clangtoolsprojectsettings.h"
#include "clangtoolssettings.h" #include "clangtoolssettings.h"
#include "clangtoolsutils.h" #include "clangtoolsutils.h"
#include "executableinfo.h"
#include <debugger/analyzer/analyzerconstants.h> #include <debugger/analyzer/analyzerconstants.h>
@@ -153,7 +154,8 @@ private:
bool m_success = false; bool m_success = false;
}; };
static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos) static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos, const FilePath &clangResourceDir,
const QString &clangVersion)
{ {
AnalyzeUnits unitsToAnalyze; AnalyzeUnits unitsToAnalyze;
const UsePrecompiledHeaders usePrecompiledHeaders = CppTools::getPchUsage(); const UsePrecompiledHeaders usePrecompiledHeaders = CppTools::getPchUsage();
@@ -163,8 +165,8 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
UseTweakedHeaderPaths::Yes, UseTweakedHeaderPaths::Yes,
UseLanguageDefines::No, UseLanguageDefines::No,
UseBuildSystemWarnings::No, UseBuildSystemWarnings::No,
QString(CLANG_VERSION), clangVersion,
QString(CLANG_RESOURCE_DIR)); clangResourceDir.toString());
QStringList arguments = extraClangToolsPrependOptions(); QStringList arguments = extraClangToolsPrependOptions();
arguments.append(optionsBuilder.build(fileInfo.kind, usePrecompiledHeaders)); arguments.append(optionsBuilder.build(fileInfo.kind, usePrecompiledHeaders));
arguments.append(extraClangToolsAppendOptions()); arguments.append(extraClangToolsAppendOptions());
@@ -174,11 +176,12 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
return unitsToAnalyze; return unitsToAnalyze;
} }
AnalyzeUnits ClangToolRunWorker::unitsToAnalyze() AnalyzeUnits ClangToolRunWorker::unitsToAnalyze(const FilePath &clangResourceDir,
const QString &clangVersion)
{ {
QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits()); QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits());
return toAnalyzeUnits(m_fileInfos); return toAnalyzeUnits(m_fileInfos, clangResourceDir, clangVersion);
} }
static QDebug operator<<(QDebug debug, const Utils::Environment &environment) static QDebug operator<<(QDebug debug, const Utils::Environment &environment)
@@ -285,7 +288,10 @@ void ClangToolRunWorker::start()
Utils::NormalMessageFormat); Utils::NormalMessageFormat);
// Collect files // Collect files
const AnalyzeUnits unitsToProcess = unitsToAnalyze(); const auto clangResourceDirAndVersion =
getClangResourceDirAndVersion(runControl()->runnable().executable);
const AnalyzeUnits unitsToProcess = unitsToAnalyze(clangResourceDirAndVersion.first,
clangResourceDirAndVersion.second);
qCDebug(LOG) << "Files to process:" << unitsToProcess; qCDebug(LOG) << "Files to process:" << unitsToProcess;
m_queue.clear(); m_queue.clear();

View File

@@ -93,7 +93,8 @@ private:
QList<RunnerCreator> runnerCreators(); QList<RunnerCreator> runnerCreators();
template <class T> ClangToolRunner *createRunner(); template <class T> ClangToolRunner *createRunner();
AnalyzeUnits unitsToAnalyze(); AnalyzeUnits unitsToAnalyze(const Utils::FilePath &clangResourceDir,
const QString &clangVersion);
void analyzeNextFile(); void analyzeNextFile();
void handleFinished(); void handleFinished();

View File

@@ -31,6 +31,7 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
@@ -42,7 +43,9 @@ using namespace Utils;
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
static QString runExecutable(const Utils::CommandLine &commandLine) enum class FailSilently { Yes, No };
static QString runExecutable(const Utils::CommandLine &commandLine,
FailSilently failSilently = FailSilently::No)
{ {
if (commandLine.executable().isEmpty() || !commandLine.executable().toFileInfo().isExecutable()) if (commandLine.executable().isEmpty() || !commandLine.executable().toFileInfo().isExecutable())
return {}; return {};
@@ -52,8 +55,10 @@ static QString runExecutable(const Utils::CommandLine &commandLine)
Environment::setupEnglishOutput(&env); Environment::setupEnglishOutput(&env);
cpp.setEnvironment(env.toStringList()); cpp.setEnvironment(env.toStringList());
SynchronousProcessResponse response = cpp.runBlocking(commandLine); const SynchronousProcessResponse response = cpp.runBlocking(commandLine);
if (response.result != SynchronousProcessResponse::Finished || response.exitCode != 0) { if (response.result != SynchronousProcessResponse::Finished
&& (failSilently == FailSilently::No
|| response.result != SynchronousProcessResponse::FinishedError)) {
Core::MessageManager::write(response.exitMessage(commandLine.toUserOutput(), 10)); Core::MessageManager::write(response.exitMessage(commandLine.toUserOutput(), 10));
Core::MessageManager::write(QString::fromUtf8(response.allRawOutput())); Core::MessageManager::write(QString::fromUtf8(response.allRawOutput()));
return {}; return {};
@@ -162,5 +167,50 @@ ClazyStandaloneInfo::ClazyStandaloneInfo(const QString &executablePath)
, supportedChecks(querySupportedClazyChecks(executablePath)) , supportedChecks(querySupportedClazyChecks(executablePath))
{} {}
static FilePath queryResourceDir(const FilePath &clangToolPath)
{
QString output = runExecutable(CommandLine(clangToolPath, {"someFilePath", "--",
"-print-resource-dir"}),
FailSilently::Yes);
// Expected output is (clang-tidy 10):
// lib/clang/10.0.1
// Error while trying to load a compilation database:
// ...
// Parse
QTextStream stream(&output);
const QString path = clangToolPath.parentDir().parentDir()
.pathAppended(stream.readLine()).toString();
const auto filePath = FilePath::fromUserInput(QDir::cleanPath(path));
if (filePath.exists())
return filePath;
return {};
}
static QString queryVersion(const FilePath &clangToolPath)
{
QString output = runExecutable(CommandLine(clangToolPath, {"--version"}));
QTextStream stream(&output);
while (!stream.atEnd()) {
static const QStringList versionPrefixes{"LLVM version ", "clang version: "};
const QString line = stream.readLine().simplified();
for (const QString &prefix : versionPrefixes) {
if (line.startsWith(prefix))
return line.mid(prefix.length());
}
}
return {};
}
QPair<FilePath, QString> getClangResourceDirAndVersion(const FilePath &clangToolPath)
{
const FilePath dynamicResourceDir = queryResourceDir(clangToolPath);
const QString dynamicVersion = queryVersion(clangToolPath);
if (dynamicResourceDir.isEmpty() || dynamicVersion.isEmpty())
return qMakePair(FilePath::fromString(CLANG_RESOURCE_DIR), QString(CLANG_VERSION));
return qMakePair(dynamicResourceDir, dynamicVersion);
}
} // namespace Internal } // namespace Internal
} // namespace ClangTools } // namespace ClangTools

View File

@@ -25,12 +25,17 @@
#pragma once #pragma once
#include <utils/fileutils.h>
#include <QPair>
#include <QStringList> #include <QStringList>
#include <QVector> #include <QVector>
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
QPair<Utils::FilePath, QString> getClangResourceDirAndVersion(const Utils::FilePath &clangToolPath);
class ClangTidyInfo class ClangTidyInfo
{ {
public: public: