diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2020-05-29 15:46:26 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-06-19 13:11:53 +0000 |
commit | 8cb74f88f9a7680e6205e2cc3ed7407e02f49540 (patch) | |
tree | 47a470484e272b37a617fd6b6df631b474990914 /src/plugins/clangtools | |
parent | 119a3c1ce99420e578af1a10195f779d5d33a83b (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.cpp | 18 | ||||
-rw-r--r-- | src/plugins/clangtools/clangtoolruncontrol.h | 3 | ||||
-rw-r--r-- | src/plugins/clangtools/executableinfo.cpp | 56 | ||||
-rw-r--r-- | src/plugins/clangtools/executableinfo.h | 5 |
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: |