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 "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();
|
||||||
|
@@ -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();
|
||||||
|
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
Reference in New Issue
Block a user