aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/clangtools
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2020-05-29 15:46:26 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2020-06-19 13:11:53 +0000
commit8cb74f88f9a7680e6205e2cc3ed7407e02f49540 (patch)
tree47a470484e272b37a617fd6b6df631b474990914 /src/plugins/clangtools
parent119a3c1ce99420e578af1a10195f779d5d33a83b (diff)
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>
Diffstat (limited to 'src/plugins/clangtools')
-rw-r--r--src/plugins/clangtools/clangtoolruncontrol.cpp18
-rw-r--r--src/plugins/clangtools/clangtoolruncontrol.h3
-rw-r--r--src/plugins/clangtools/executableinfo.cpp56
-rw-r--r--src/plugins/clangtools/executableinfo.h5
4 files changed, 72 insertions, 10 deletions
diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp
index 5eca0a6515..090e9d8216 100644
--- a/src/plugins/clangtools/clangtoolruncontrol.cpp
+++ b/src/plugins/clangtools/clangtoolruncontrol.cpp
@@ -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();
diff --git a/src/plugins/clangtools/clangtoolruncontrol.h b/src/plugins/clangtools/clangtoolruncontrol.h
index 936e839d6d..f497413247 100644
--- a/src/plugins/clangtools/clangtoolruncontrol.h
+++ b/src/plugins/clangtools/clangtoolruncontrol.h
@@ -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();
diff --git a/src/plugins/clangtools/executableinfo.cpp b/src/plugins/clangtools/executableinfo.cpp
index 84c6099094..88cf579f0e 100644
--- a/src/plugins/clangtools/executableinfo.cpp
+++ b/src/plugins/clangtools/executableinfo.cpp
@@ -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
diff --git a/src/plugins/clangtools/executableinfo.h b/src/plugins/clangtools/executableinfo.h
index f3988a71f5..95e61df456 100644
--- a/src/plugins/clangtools/executableinfo.h
+++ b/src/plugins/clangtools/executableinfo.h
@@ -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: