forked from qt-creator/qt-creator
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:
committed by
Christian Kandeler
parent
119a3c1ce9
commit
8cb74f88f9
@@ -31,6 +31,7 @@
|
||||
#include "clangtoolsprojectsettings.h"
|
||||
#include "clangtoolssettings.h"
|
||||
#include "clangtoolsutils.h"
|
||||
#include "executableinfo.h"
|
||||
|
||||
#include <debugger/analyzer/analyzerconstants.h>
|
||||
|
||||
@@ -153,7 +154,8 @@ private:
|
||||
bool m_success = false;
|
||||
};
|
||||
|
||||
static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
|
||||
static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos, const FilePath &clangResourceDir,
|
||||
const QString &clangVersion)
|
||||
{
|
||||
AnalyzeUnits unitsToAnalyze;
|
||||
const UsePrecompiledHeaders usePrecompiledHeaders = CppTools::getPchUsage();
|
||||
@@ -163,8 +165,8 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
|
||||
UseTweakedHeaderPaths::Yes,
|
||||
UseLanguageDefines::No,
|
||||
UseBuildSystemWarnings::No,
|
||||
QString(CLANG_VERSION),
|
||||
QString(CLANG_RESOURCE_DIR));
|
||||
clangVersion,
|
||||
clangResourceDir.toString());
|
||||
QStringList arguments = extraClangToolsPrependOptions();
|
||||
arguments.append(optionsBuilder.build(fileInfo.kind, usePrecompiledHeaders));
|
||||
arguments.append(extraClangToolsAppendOptions());
|
||||
@@ -174,11 +176,12 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
|
||||
return unitsToAnalyze;
|
||||
}
|
||||
|
||||
AnalyzeUnits ClangToolRunWorker::unitsToAnalyze()
|
||||
AnalyzeUnits ClangToolRunWorker::unitsToAnalyze(const FilePath &clangResourceDir,
|
||||
const QString &clangVersion)
|
||||
{
|
||||
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)
|
||||
@@ -285,7 +288,10 @@ void ClangToolRunWorker::start()
|
||||
Utils::NormalMessageFormat);
|
||||
|
||||
// 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;
|
||||
|
||||
m_queue.clear();
|
||||
|
@@ -93,7 +93,8 @@ private:
|
||||
QList<RunnerCreator> runnerCreators();
|
||||
template <class T> ClangToolRunner *createRunner();
|
||||
|
||||
AnalyzeUnits unitsToAnalyze();
|
||||
AnalyzeUnits unitsToAnalyze(const Utils::FilePath &clangResourceDir,
|
||||
const QString &clangVersion);
|
||||
void analyzeNextFile();
|
||||
|
||||
void handleFinished();
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <utils/environment.h>
|
||||
#include <utils/synchronousprocess.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
@@ -42,7 +43,9 @@ using namespace Utils;
|
||||
namespace ClangTools {
|
||||
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())
|
||||
return {};
|
||||
@@ -52,8 +55,10 @@ static QString runExecutable(const Utils::CommandLine &commandLine)
|
||||
Environment::setupEnglishOutput(&env);
|
||||
cpp.setEnvironment(env.toStringList());
|
||||
|
||||
SynchronousProcessResponse response = cpp.runBlocking(commandLine);
|
||||
if (response.result != SynchronousProcessResponse::Finished || response.exitCode != 0) {
|
||||
const SynchronousProcessResponse response = cpp.runBlocking(commandLine);
|
||||
if (response.result != SynchronousProcessResponse::Finished
|
||||
&& (failSilently == FailSilently::No
|
||||
|| response.result != SynchronousProcessResponse::FinishedError)) {
|
||||
Core::MessageManager::write(response.exitMessage(commandLine.toUserOutput(), 10));
|
||||
Core::MessageManager::write(QString::fromUtf8(response.allRawOutput()));
|
||||
return {};
|
||||
@@ -162,5 +167,50 @@ ClazyStandaloneInfo::ClazyStandaloneInfo(const QString &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 ClangTools
|
||||
|
@@ -25,12 +25,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QPair>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
|
||||
namespace ClangTools {
|
||||
namespace Internal {
|
||||
|
||||
QPair<Utils::FilePath, QString> getClangResourceDirAndVersion(const Utils::FilePath &clangToolPath);
|
||||
|
||||
class ClangTidyInfo
|
||||
{
|
||||
public:
|
||||
|
Reference in New Issue
Block a user