forked from qt-creator/qt-creator
ClangTools: Remove clang executable settings
We use custom clang executable and it does not make sense anymore to give a choice of changing it. Change-Id: Icf86042ac3fcd08c320ef2bbdaabef1102b023b5 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -74,6 +74,11 @@ function libDir(llvmConfig)
|
|||||||
return FileInfo.fromNativeSeparators(readOutput(llvmConfig, ["--libdir"]));
|
return FileInfo.fromNativeSeparators(readOutput(llvmConfig, ["--libdir"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function binDir(llvmConfig)
|
||||||
|
{
|
||||||
|
return FileInfo.fromNativeSeparators(readOutput(llvmConfig, ["--bindir"]));
|
||||||
|
}
|
||||||
|
|
||||||
function version(llvmConfig)
|
function version(llvmConfig)
|
||||||
{
|
{
|
||||||
return readOutput(llvmConfig, ["--version"]).replace(/(\d+\.\d+\.\d+).*/, "$1")
|
return readOutput(llvmConfig, ["--version"]).replace(/(\d+\.\d+\.\d+).*/, "$1")
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Module {
|
|||||||
property string llvmVersion
|
property string llvmVersion
|
||||||
property string llvmIncludeDir
|
property string llvmIncludeDir
|
||||||
property string llvmLibDir
|
property string llvmLibDir
|
||||||
|
property string llvmBinDir
|
||||||
property stringList llvmLibs
|
property stringList llvmLibs
|
||||||
property stringList llvmToolingLibs
|
property stringList llvmToolingLibs
|
||||||
property stringList llvmToolingDefines
|
property stringList llvmToolingDefines
|
||||||
@@ -28,6 +29,7 @@ Module {
|
|||||||
llvmVersion = ClangFunctions.version(llvmConfig);
|
llvmVersion = ClangFunctions.version(llvmConfig);
|
||||||
llvmIncludeDir = ClangFunctions.includeDir(llvmConfig);
|
llvmIncludeDir = ClangFunctions.includeDir(llvmConfig);
|
||||||
llvmLibDir = ClangFunctions.libDir(llvmConfig);
|
llvmLibDir = ClangFunctions.libDir(llvmConfig);
|
||||||
|
llvmBinDir = ClangFunctions.binDir(llvmConfig);
|
||||||
llvmLibs = ClangFunctions.libraries(targetOS);
|
llvmLibs = ClangFunctions.libraries(targetOS);
|
||||||
llvmToolingLibs = ClangFunctions.toolingLibs(llvmConfig, targetOS);
|
llvmToolingLibs = ClangFunctions.toolingLibs(llvmConfig, targetOS);
|
||||||
llvmBuildMode = ClangFunctions.buildMode(llvmConfig);
|
llvmBuildMode = ClangFunctions.buildMode(llvmConfig);
|
||||||
@@ -43,6 +45,7 @@ Module {
|
|||||||
property string llvmVersion: clangProbe.llvmVersion
|
property string llvmVersion: clangProbe.llvmVersion
|
||||||
property string llvmIncludeDir: clangProbe.llvmIncludeDir
|
property string llvmIncludeDir: clangProbe.llvmIncludeDir
|
||||||
property string llvmLibDir: clangProbe.llvmLibDir
|
property string llvmLibDir: clangProbe.llvmLibDir
|
||||||
|
property string llvmBinDir: clangProbe.llvmBinDir
|
||||||
property stringList llvmLibs: clangProbe.llvmLibs
|
property stringList llvmLibs: clangProbe.llvmLibs
|
||||||
property stringList llvmToolingLibs: clangProbe.llvmToolingLibs
|
property stringList llvmToolingLibs: clangProbe.llvmToolingLibs
|
||||||
property string llvmBuildMode: clangProbe.llvmBuildMode
|
property string llvmBuildMode: clangProbe.llvmBuildMode
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ QtcPlugin {
|
|||||||
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
|
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
|
||||||
"include");
|
"include");
|
||||||
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
|
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
|
||||||
|
defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
|
||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ QtcPlugin {
|
|||||||
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
|
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
|
||||||
"include");
|
"include");
|
||||||
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
|
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
|
||||||
|
defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
|
||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ QtcPlugin {
|
|||||||
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
|
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
|
||||||
"include");
|
"include");
|
||||||
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
|
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
|
||||||
|
defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
|
||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,50 +43,7 @@ ClangStaticAnalyzerConfigWidget::ClangStaticAnalyzerConfigWidget(
|
|||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
Utils::PathChooser * const chooser = m_ui->clangExecutableChooser;
|
m_ui->simultaneousProccessesSpinBox->setValue(settings->savedSimultaneousProcesses());
|
||||||
chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
|
|
||||||
chooser->setHistoryCompleter(QLatin1String("ClangStaticAnalyzer.ClangCommand.History"));
|
|
||||||
chooser->setPromptDialogTitle(tr("Clang Command"));
|
|
||||||
const auto validator = [chooser, this](Utils::FancyLineEdit *edit, QString *errorMessage) {
|
|
||||||
const QString currentFilePath = chooser->fileName().toString();
|
|
||||||
Utils::PathChooser pc;
|
|
||||||
Utils::PathChooser *helperPathChooser;
|
|
||||||
if (currentFilePath.isEmpty()) {
|
|
||||||
pc.setExpectedKind(chooser->expectedKind());
|
|
||||||
pc.setPath(edit->placeholderText());
|
|
||||||
helperPathChooser = &pc;
|
|
||||||
} else {
|
|
||||||
helperPathChooser = chooser;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool isExecutableValid =
|
|
||||||
chooser->defaultValidationFunction()(helperPathChooser->lineEdit(), errorMessage)
|
|
||||||
&& isClangExecutableUsable(helperPathChooser->fileName().toString(), errorMessage);
|
|
||||||
|
|
||||||
const ClangExecutableVersion detectedVersion = isExecutableValid
|
|
||||||
? clangExecutableVersion(helperPathChooser->fileName().toString())
|
|
||||||
: ClangExecutableVersion();
|
|
||||||
updateDetectedVersionLabel(isExecutableValid, detectedVersion);
|
|
||||||
|
|
||||||
return isExecutableValid;
|
|
||||||
};
|
|
||||||
chooser->setValidationFunction(validator);
|
|
||||||
bool clangExeIsSet;
|
|
||||||
const QString clangExe = settings->clangExecutable(&clangExeIsSet);
|
|
||||||
chooser->lineEdit()->setPlaceholderText(QDir::toNativeSeparators(
|
|
||||||
settings->defaultClangExecutable()));
|
|
||||||
if (clangExeIsSet) {
|
|
||||||
chooser->setPath(clangExe);
|
|
||||||
} else {
|
|
||||||
// Setting an empty string does not trigger the validator, as that is the initial value
|
|
||||||
// in the line edit.
|
|
||||||
chooser->setPath(QLatin1String(" "));
|
|
||||||
chooser->lineEdit()->clear();
|
|
||||||
}
|
|
||||||
connect(m_ui->clangExecutableChooser, &Utils::PathChooser::rawPathChanged,
|
|
||||||
[settings](const QString &path) { settings->setClangExecutable(path); });
|
|
||||||
|
|
||||||
m_ui->simultaneousProccessesSpinBox->setValue(settings->simultaneousProcesses());
|
|
||||||
m_ui->simultaneousProccessesSpinBox->setMinimum(1);
|
m_ui->simultaneousProccessesSpinBox->setMinimum(1);
|
||||||
m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount());
|
m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount());
|
||||||
connect(m_ui->simultaneousProccessesSpinBox,
|
connect(m_ui->simultaneousProccessesSpinBox,
|
||||||
@@ -99,29 +56,5 @@ ClangStaticAnalyzerConfigWidget::~ClangStaticAnalyzerConfigWidget()
|
|||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerConfigWidget::updateDetectedVersionLabel(
|
|
||||||
bool isExecutableValid,
|
|
||||||
const ClangExecutableVersion &providedVersion)
|
|
||||||
{
|
|
||||||
QLabel &label = *m_ui->detectedVersionLabel;
|
|
||||||
|
|
||||||
if (isExecutableValid) {
|
|
||||||
if (providedVersion.isValid()) {
|
|
||||||
if (providedVersion.isSupportedVersion()) {
|
|
||||||
label.setText(tr("Version: %1, supported.")
|
|
||||||
.arg(providedVersion.toString()));
|
|
||||||
} else {
|
|
||||||
label.setText(tr("Version: %1, unsupported (supported version is %2).")
|
|
||||||
.arg(providedVersion.toString())
|
|
||||||
.arg(ClangExecutableVersion::supportedVersionAsString()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
label.setText(tr("Version: Could not determine version."));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
label.setText(tr("Version: Set valid executable first."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangTools
|
} // namespace ClangTools
|
||||||
|
|||||||
@@ -45,9 +45,6 @@ public:
|
|||||||
QWidget *parent = 0);
|
QWidget *parent = 0);
|
||||||
~ClangStaticAnalyzerConfigWidget();
|
~ClangStaticAnalyzerConfigWidget();
|
||||||
|
|
||||||
void updateDetectedVersionLabel(bool executableIsValid,
|
|
||||||
const ClangExecutableVersion &providedVersion);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ClangStaticAnalyzerConfigWidget *m_ui;
|
Ui::ClangStaticAnalyzerConfigWidget *m_ui;
|
||||||
ClangToolsSettings *m_settings;
|
ClangToolsSettings *m_settings;
|
||||||
|
|||||||
@@ -21,34 +21,13 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Clang executable:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="Utils::PathChooser" name="clangExecutableChooser" native="true"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="detectedVersionLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Simultaneous processes:</string>
|
<string>Simultaneous processes:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="0" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSpinBox" name="simultaneousProccessesSpinBox">
|
<widget class="QSpinBox" name="simultaneousProccessesSpinBox">
|
||||||
@@ -93,14 +72,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>Utils::PathChooser</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">utils/pathchooser.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "clangstaticanalyzertool.h"
|
#include "clangstaticanalyzertool.h"
|
||||||
#include "clangtoolsutils.h"
|
#include "clangtoolsutils.h"
|
||||||
|
|
||||||
|
#include <cpptools/compileroptionsbuilder.h>
|
||||||
#include <cpptools/projectinfo.h>
|
#include <cpptools/projectinfo.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
#include <projectexplorer/kitmanager.h>
|
#include <projectexplorer/kitmanager.h>
|
||||||
@@ -166,9 +167,8 @@ static QList<Target *> validTargets(Project *project)
|
|||||||
|
|
||||||
const ToolChain * const toolchain = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
const ToolChain * const toolchain = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
|
||||||
QTC_ASSERT(toolchain, return false);
|
QTC_ASSERT(toolchain, return false);
|
||||||
bool hasClangExecutable;
|
|
||||||
clangExecutableFromSettings(&hasClangExecutable);
|
if (CppTools::clangExecutable(CLANG_BINDIR).isEmpty()) {
|
||||||
if (!hasClangExecutable) {
|
|
||||||
qWarning("Project \"%s\": Skipping target \"%s\" since no suitable clang was found for the toolchain.",
|
qWarning("Project \"%s\": Skipping target \"%s\" since no suitable clang was found for the toolchain.",
|
||||||
qPrintable(projectFileName),
|
qPrintable(projectFileName),
|
||||||
qPrintable(target->displayName()));
|
qPrintable(target->displayName()));
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl(RunControl *runCont
|
|||||||
|
|
||||||
ClangToolRunner *ClangStaticAnalyzerRunControl::createRunner()
|
ClangToolRunner *ClangStaticAnalyzerRunControl::createRunner()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!m_clangExecutable.isEmpty(), return 0);
|
|
||||||
QTC_ASSERT(!m_clangLogFileDir.isEmpty(), return 0);
|
QTC_ASSERT(!m_clangLogFileDir.isEmpty(), return 0);
|
||||||
|
|
||||||
auto runner = new ClangStaticAnalyzerRunner(m_clangExecutable,
|
auto runner = new ClangStaticAnalyzerRunner(m_clangExecutable,
|
||||||
|
|||||||
@@ -145,18 +145,11 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
|
|||||||
return unitsToAnalyze;
|
return unitsToAnalyze;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString clangResourceDir(const QString &clangExecutable, const QString &clangVersion)
|
|
||||||
{
|
|
||||||
QDir llvmDir = QFileInfo(clangExecutable).dir();
|
|
||||||
llvmDir.cdUp();
|
|
||||||
return llvmDir.absolutePath() + clangIncludePath(clangVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
AnalyzeUnits ClangToolRunControl::sortedUnitsToAnalyze(const QString &clangVersion)
|
AnalyzeUnits ClangToolRunControl::sortedUnitsToAnalyze(const QString &clangVersion)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits());
|
QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits());
|
||||||
|
|
||||||
const QString clangResourceDirectory = clangResourceDir(m_clangExecutable, clangVersion);
|
const QString clangResourceDirectory = clangIncludeDirectory(m_clangExecutable, clangVersion);
|
||||||
AnalyzeUnits units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(), clangVersion,
|
AnalyzeUnits units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(), clangVersion,
|
||||||
clangResourceDirectory);
|
clangResourceDirectory);
|
||||||
|
|
||||||
@@ -179,7 +172,9 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClangToolRunControl::ClangToolRunControl(RunControl *runControl, Target *target)
|
ClangToolRunControl::ClangToolRunControl(RunControl *runControl, Target *target)
|
||||||
: RunWorker(runControl), m_target(target)
|
: RunWorker(runControl)
|
||||||
|
, m_clangExecutable(CppTools::clangExecutable(CLANG_BINDIR))
|
||||||
|
, m_target(target)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,9 +203,18 @@ void ClangToolRunControl::start()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString &toolName = tool()->name();
|
||||||
|
if (m_clangExecutable.isEmpty()) {
|
||||||
|
const QString errorMessage = tr("%1 : Can't find clang executable, stop.").arg(toolName);
|
||||||
|
appendMessage(errorMessage, Utils::ErrorMessageFormat);
|
||||||
|
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
|
TaskHub::requestPopup();
|
||||||
|
reportFailure();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(m_target->project());
|
m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(m_target->project());
|
||||||
|
|
||||||
const QString toolName = tool()->name();
|
|
||||||
// Some projects provides CompilerCallData once a build is finished,
|
// Some projects provides CompilerCallData once a build is finished,
|
||||||
if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) {
|
if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) {
|
||||||
// If it's more than a release/debug build configuration change, e.g.
|
// If it's more than a release/debug build configuration change, e.g.
|
||||||
@@ -225,42 +229,6 @@ void ClangToolRunControl::start()
|
|||||||
appendMessage(tr("Running %1 on %2").arg(toolName).arg(projectFile.toUserOutput()),
|
appendMessage(tr("Running %1 on %2").arg(toolName).arg(projectFile.toUserOutput()),
|
||||||
Utils::NormalMessageFormat);
|
Utils::NormalMessageFormat);
|
||||||
|
|
||||||
// Check clang executable
|
|
||||||
bool isValidClangExecutable;
|
|
||||||
const QString executable = clangExecutableFromSettings(&isValidClangExecutable);
|
|
||||||
if (!isValidClangExecutable) {
|
|
||||||
const QString errorMessage = toolName
|
|
||||||
+ tr(": Invalid executable \"%1\", stop.").arg(executable);
|
|
||||||
appendMessage(errorMessage, Utils::ErrorMessageFormat);
|
|
||||||
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
|
||||||
TaskHub::requestPopup();
|
|
||||||
reportFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check clang version
|
|
||||||
const ClangExecutableVersion version = clangExecutableVersion(executable);
|
|
||||||
if (!version.isValid()) {
|
|
||||||
const QString warningMessage
|
|
||||||
= toolName + tr(": Running with possibly unsupported version, "
|
|
||||||
"could not determine version from executable \"%1\".")
|
|
||||||
.arg(executable);
|
|
||||||
appendMessage(warningMessage, Utils::StdErrFormat);
|
|
||||||
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
|
|
||||||
TaskHub::requestPopup();
|
|
||||||
} else if (!version.isSupportedVersion()) {
|
|
||||||
const QString warningMessage
|
|
||||||
= toolName + tr(": Running with unsupported version %1, "
|
|
||||||
"supported version is %2.")
|
|
||||||
.arg(version.toString())
|
|
||||||
.arg(ClangExecutableVersion::supportedVersionAsString());
|
|
||||||
appendMessage(warningMessage, Utils::StdErrFormat);
|
|
||||||
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
|
|
||||||
TaskHub::requestPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_clangExecutable = executable;
|
|
||||||
|
|
||||||
// Create log dir
|
// Create log dir
|
||||||
Utils::TemporaryDirectory temporaryDir("qtc-clangtools-XXXXXX");
|
Utils::TemporaryDirectory temporaryDir("qtc-clangtools-XXXXXX");
|
||||||
temporaryDir.setAutoRemove(false);
|
temporaryDir.setAutoRemove(false);
|
||||||
@@ -276,7 +244,7 @@ void ClangToolRunControl::start()
|
|||||||
m_clangLogFileDir = temporaryDir.path();
|
m_clangLogFileDir = temporaryDir.path();
|
||||||
|
|
||||||
// Collect files
|
// Collect files
|
||||||
const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(version.toString());
|
const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(CLANG_VERSION);
|
||||||
qCDebug(LOG) << "Files to process:" << unitsToProcess;
|
qCDebug(LOG) << "Files to process:" << unitsToProcess;
|
||||||
m_unitsToProcess = unitsToProcess;
|
m_unitsToProcess = unitsToProcess;
|
||||||
m_initialFilesToProcessSize = m_unitsToProcess.count();
|
m_initialFilesToProcessSize = m_unitsToProcess.count();
|
||||||
@@ -298,7 +266,7 @@ void ClangToolRunControl::start()
|
|||||||
// Start process(es)
|
// Start process(es)
|
||||||
qCDebug(LOG) << "Environment:" << m_environment;
|
qCDebug(LOG) << "Environment:" << m_environment;
|
||||||
m_runners.clear();
|
m_runners.clear();
|
||||||
const int parallelRuns = ClangToolsSettings::instance()->simultaneousProcesses();
|
const int parallelRuns = ClangToolsSettings::instance()->savedSimultaneousProcesses();
|
||||||
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
|
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
|
||||||
m_success = true;
|
m_success = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
include(../../qtcreatorplugin.pri)
|
include(../../qtcreatorplugin.pri)
|
||||||
include(../../shared/clang/clang_installation.pri)
|
include(../../shared/clang/clang_installation.pri)
|
||||||
|
|
||||||
|
include(../../shared/clang/clang_defines.pri)
|
||||||
|
|
||||||
requires(!isEmpty(LLVM_VERSION))
|
requires(!isEmpty(LLVM_VERSION))
|
||||||
|
|
||||||
LIBS += $$LIBCLANG_LIBS
|
LIBS += $$LIBCLANG_LIBS
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import qbs
|
import qbs
|
||||||
|
import qbs.FileInfo
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "ClangTools"
|
name: "ClangTools"
|
||||||
@@ -26,6 +27,19 @@ QtcPlugin {
|
|||||||
cpp.dynamicLibraries: base.concat(libclang.llvmLibs)
|
cpp.dynamicLibraries: base.concat(libclang.llvmLibs)
|
||||||
cpp.rpaths: base.concat(libclang.llvmLibDir)
|
cpp.rpaths: base.concat(libclang.llvmLibDir)
|
||||||
|
|
||||||
|
cpp.defines: {
|
||||||
|
var defines = base;
|
||||||
|
defines.push("CLANGPCHMANAGER_LIB");
|
||||||
|
|
||||||
|
// The following defines are used to determine the clang include path for intrinsics.
|
||||||
|
defines.push('CLANG_VERSION="' + libclang.llvmVersion + '"');
|
||||||
|
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
|
||||||
|
"include");
|
||||||
|
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
|
||||||
|
defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
|
||||||
|
return defines;
|
||||||
|
}
|
||||||
|
|
||||||
files: [
|
files: [
|
||||||
"clangstaticanalyzerconfigwidget.cpp",
|
"clangstaticanalyzerconfigwidget.cpp",
|
||||||
"clangstaticanalyzerconfigwidget.h",
|
"clangstaticanalyzerconfigwidget.h",
|
||||||
|
|||||||
@@ -35,14 +35,12 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
static const char clangExecutableKey[] = "clangExecutable";
|
|
||||||
static const char simultaneousProcessesKey[] = "simultaneousProcesses";
|
static const char simultaneousProcessesKey[] = "simultaneousProcesses";
|
||||||
|
|
||||||
namespace ClangTools {
|
namespace ClangTools {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
ClangToolsSettings::ClangToolsSettings()
|
ClangToolsSettings::ClangToolsSettings()
|
||||||
: m_simultaneousProcesses(-1)
|
|
||||||
{
|
{
|
||||||
readSettings();
|
readSettings();
|
||||||
}
|
}
|
||||||
@@ -53,36 +51,9 @@ ClangToolsSettings *ClangToolsSettings::instance()
|
|||||||
return &instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString clangExecutableFileName()
|
int ClangToolsSettings::savedSimultaneousProcesses() const
|
||||||
{
|
{
|
||||||
return QLatin1String("clang" QTC_HOST_EXE_SUFFIX);
|
return m_savedSimultaneousProcesses;
|
||||||
}
|
|
||||||
|
|
||||||
QString ClangToolsSettings::defaultClangExecutable() const
|
|
||||||
{
|
|
||||||
const QString shippedBinary = Core::ICore::libexecPath()
|
|
||||||
+ QLatin1String("/clang/bin/")
|
|
||||||
+ clangExecutableFileName();
|
|
||||||
if (QFileInfo(shippedBinary).isExecutable())
|
|
||||||
return shippedBinary;
|
|
||||||
return clangExecutableFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ClangToolsSettings::clangExecutable(bool *isSet) const
|
|
||||||
{
|
|
||||||
if (m_clangExecutable.isEmpty()) {
|
|
||||||
if (isSet)
|
|
||||||
*isSet = false;
|
|
||||||
return defaultClangExecutable();
|
|
||||||
}
|
|
||||||
if (isSet)
|
|
||||||
*isSet = true;
|
|
||||||
return m_clangExecutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangToolsSettings::setClangExecutable(const QString &exectuable)
|
|
||||||
{
|
|
||||||
m_clangExecutable = exectuable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClangToolsSettings::simultaneousProcesses() const
|
int ClangToolsSettings::simultaneousProcesses() const
|
||||||
@@ -92,7 +63,6 @@ int ClangToolsSettings::simultaneousProcesses() const
|
|||||||
|
|
||||||
void ClangToolsSettings::setSimultaneousProcesses(int processes)
|
void ClangToolsSettings::setSimultaneousProcesses(int processes)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(processes >=1, return);
|
|
||||||
m_simultaneousProcesses = processes;
|
m_simultaneousProcesses = processes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,21 +71,22 @@ void ClangToolsSettings::readSettings()
|
|||||||
QSettings *settings = Core::ICore::settings();
|
QSettings *settings = Core::ICore::settings();
|
||||||
settings->beginGroup(QLatin1String(Constants::SETTINGS_ID));
|
settings->beginGroup(QLatin1String(Constants::SETTINGS_ID));
|
||||||
|
|
||||||
setClangExecutable(settings->value(QLatin1String(clangExecutableKey)).toString());
|
|
||||||
|
|
||||||
const int defaultSimultaneousProcesses = qMax(0, QThread::idealThreadCount() / 2);
|
const int defaultSimultaneousProcesses = qMax(0, QThread::idealThreadCount() / 2);
|
||||||
setSimultaneousProcesses(settings->value(QLatin1String(simultaneousProcessesKey),
|
m_savedSimultaneousProcesses = m_simultaneousProcesses
|
||||||
defaultSimultaneousProcesses).toInt());
|
= settings->value(QString(simultaneousProcessesKey),
|
||||||
|
defaultSimultaneousProcesses).toInt();
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangToolsSettings::writeSettings() const
|
void ClangToolsSettings::writeSettings()
|
||||||
{
|
{
|
||||||
QSettings *settings = Core::ICore::settings();
|
QSettings *settings = Core::ICore::settings();
|
||||||
settings->beginGroup(QLatin1String(Constants::SETTINGS_ID));
|
settings->beginGroup(QString(Constants::SETTINGS_ID));
|
||||||
settings->setValue(QLatin1String(clangExecutableKey), m_clangExecutable);
|
settings->setValue(QString(simultaneousProcessesKey), m_simultaneousProcesses);
|
||||||
settings->setValue(QLatin1String(simultaneousProcessesKey), simultaneousProcesses());
|
|
||||||
|
m_savedSimultaneousProcesses = m_simultaneousProcesses;
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,9 @@ class ClangToolsSettings
|
|||||||
public:
|
public:
|
||||||
static ClangToolsSettings *instance();
|
static ClangToolsSettings *instance();
|
||||||
|
|
||||||
void writeSettings() const;
|
void writeSettings();
|
||||||
|
|
||||||
QString defaultClangExecutable() const;
|
int savedSimultaneousProcesses() const;
|
||||||
QString clangExecutable(bool *isSet = nullptr) const;
|
|
||||||
void setClangExecutable(const QString &exectuable);
|
|
||||||
|
|
||||||
int simultaneousProcesses() const;
|
int simultaneousProcesses() const;
|
||||||
void setSimultaneousProcesses(int processes);
|
void setSimultaneousProcesses(int processes);
|
||||||
@@ -48,8 +46,8 @@ private:
|
|||||||
ClangToolsSettings();
|
ClangToolsSettings();
|
||||||
void readSettings();
|
void readSettings();
|
||||||
|
|
||||||
QString m_clangExecutable;
|
int m_simultaneousProcesses = -1;
|
||||||
int m_simultaneousProcesses;
|
int m_savedSimultaneousProcesses = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -62,9 +62,8 @@ void ClangToolsUnitTests::initTestCase()
|
|||||||
Constants::CXX_LANGUAGE_ID);
|
Constants::CXX_LANGUAGE_ID);
|
||||||
if (!toolchain)
|
if (!toolchain)
|
||||||
QSKIP("This test requires that there is a kit with a toolchain.");
|
QSKIP("This test requires that there is a kit with a toolchain.");
|
||||||
bool hasClangExecutable;
|
|
||||||
clangExecutableFromSettings(&hasClangExecutable);
|
if (CppTools::clangExecutable(CLANG_BINDIR).isEmpty())
|
||||||
if (!hasClangExecutable)
|
|
||||||
QSKIP("No clang suitable for analyzing found");
|
QSKIP("No clang suitable for analyzing found");
|
||||||
|
|
||||||
m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(QLatin1String(":/unit-tests"));
|
m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(QLatin1String(":/unit-tests"));
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
#include "clangtoolsdiagnostic.h"
|
#include "clangtoolsdiagnostic.h"
|
||||||
#include "clangtoolssettings.h"
|
#include "clangtoolssettings.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
@@ -38,118 +40,14 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
static bool isFileExecutable(const QString &executablePath)
|
|
||||||
{
|
|
||||||
if (executablePath.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const QFileInfo fileInfo(executablePath);
|
|
||||||
return fileInfo.isFile() && fileInfo.isExecutable();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ClangTools {
|
namespace ClangTools {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
QString clangExecutableFromSettings(bool *isValid)
|
|
||||||
{
|
|
||||||
QString executable = ClangToolsSettings::instance()->clangExecutable();
|
|
||||||
if (executable.isEmpty()) {
|
|
||||||
*isValid = false;
|
|
||||||
return executable;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString hostExeSuffix = QLatin1String(QTC_HOST_EXE_SUFFIX);
|
|
||||||
const Qt::CaseSensitivity caseSensitivity = Utils::HostOsInfo::fileNameCaseSensitivity();
|
|
||||||
const bool hasSuffix = executable.endsWith(hostExeSuffix, caseSensitivity);
|
|
||||||
|
|
||||||
const QFileInfo fileInfo = QFileInfo(executable);
|
|
||||||
if (fileInfo.isAbsolute()) {
|
|
||||||
if (!hasSuffix)
|
|
||||||
executable.append(hostExeSuffix);
|
|
||||||
} else {
|
|
||||||
const Utils::Environment &environment = Utils::Environment::systemEnvironment();
|
|
||||||
const QString executableFromPath = environment.searchInPath(executable).toString();
|
|
||||||
if (executableFromPath.isEmpty()) {
|
|
||||||
*isValid = false;
|
|
||||||
return executable;
|
|
||||||
}
|
|
||||||
executable = executableFromPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
*isValid = isFileExecutable(executable) && isClangExecutableUsable(executable);
|
|
||||||
return executable;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString createFullLocationString(const Debugger::DiagnosticLocation &location)
|
QString createFullLocationString(const Debugger::DiagnosticLocation &location)
|
||||||
{
|
{
|
||||||
return location.filePath + QLatin1Char(':') + QString::number(location.line)
|
return location.filePath + QLatin1Char(':') + QString::number(location.line)
|
||||||
+ QLatin1Char(':') + QString::number(location.column);
|
+ QLatin1Char(':') + QString::number(location.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isClangExecutableUsable(const QString &filePath, QString *errorMessage)
|
|
||||||
{
|
|
||||||
const QFileInfo fi(filePath);
|
|
||||||
if (fi.isSymLink() && fi.symLinkTarget().contains(QLatin1String("icecc"))) {
|
|
||||||
if (errorMessage) {
|
|
||||||
*errorMessage = QCoreApplication::translate("ClangTools",
|
|
||||||
"The chosen file \"%1\" seems to point to an icecc binary not suitable "
|
|
||||||
"for analyzing.\nPlease set a real Clang executable.")
|
|
||||||
.arg(filePath);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClangExecutableVersion clangExecutableVersion(const QString &executable)
|
|
||||||
{
|
|
||||||
const ClangExecutableVersion invalidVersion;
|
|
||||||
|
|
||||||
// Sanity checks
|
|
||||||
const QFileInfo fileInfo(executable);
|
|
||||||
const bool isExecutableFile = fileInfo.isFile() && fileInfo.isExecutable();
|
|
||||||
if (!isExecutableFile)
|
|
||||||
return invalidVersion;
|
|
||||||
|
|
||||||
// Get version output
|
|
||||||
Utils::Environment environment = Utils::Environment::systemEnvironment();
|
|
||||||
Utils::Environment::setupEnglishOutput(&environment);
|
|
||||||
Utils::SynchronousProcess runner;
|
|
||||||
runner.setEnvironment(environment.toStringList());
|
|
||||||
runner.setTimeoutS(10);
|
|
||||||
// We would prefer "-dumpversion", but that one is only there for GCC compatibility
|
|
||||||
// and returns some static/old version.
|
|
||||||
// See also https://bugs.llvm.org/show_bug.cgi?id=28597
|
|
||||||
const QStringList arguments(QLatin1String(("--version")));
|
|
||||||
const Utils::SynchronousProcessResponse response = runner.runBlocking(executable, arguments);
|
|
||||||
if (response.result != Utils::SynchronousProcessResponse::Finished)
|
|
||||||
return invalidVersion;
|
|
||||||
const QString output = response.stdOut();
|
|
||||||
|
|
||||||
// Parse version output
|
|
||||||
const QRegularExpression re(QLatin1String("clang version (\\d+)\\.(\\d+)\\.(\\d+)"));
|
|
||||||
const QRegularExpressionMatch reMatch = re.match(output);
|
|
||||||
if (re.captureCount() != 3)
|
|
||||||
return invalidVersion;
|
|
||||||
|
|
||||||
const QString majorString = reMatch.captured(1);
|
|
||||||
bool convertedSuccessfully = false;
|
|
||||||
const int major = majorString.toInt(&convertedSuccessfully);
|
|
||||||
if (!convertedSuccessfully)
|
|
||||||
return invalidVersion;
|
|
||||||
|
|
||||||
const QString minorString = reMatch.captured(2);
|
|
||||||
const int minor = minorString.toInt(&convertedSuccessfully);
|
|
||||||
if (!convertedSuccessfully)
|
|
||||||
return invalidVersion;
|
|
||||||
|
|
||||||
const QString patchString = reMatch.captured(3);
|
|
||||||
const int patch = patchString.toInt(&convertedSuccessfully);
|
|
||||||
if (!convertedSuccessfully)
|
|
||||||
return invalidVersion;
|
|
||||||
|
|
||||||
return ClangExecutableVersion(major, minor, patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangTools
|
} // namespace ClangTools
|
||||||
|
|||||||
@@ -39,36 +39,7 @@ namespace Debugger { class DiagnosticLocation; }
|
|||||||
namespace ClangTools {
|
namespace ClangTools {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
bool isClangExecutableUsable(const QString &filePath, QString *errorMessage = 0);
|
|
||||||
|
|
||||||
QString clangExecutableFromSettings(bool *isValid);
|
|
||||||
|
|
||||||
QString createFullLocationString(const Debugger::DiagnosticLocation &location);
|
QString createFullLocationString(const Debugger::DiagnosticLocation &location);
|
||||||
|
|
||||||
// CLANG-UPGRADE-CHECK: Adapt minimum version numbers.
|
|
||||||
class ClangExecutableVersion : public QVersionNumber {
|
|
||||||
public:
|
|
||||||
ClangExecutableVersion() : QVersionNumber(-1, -1, -1) {}
|
|
||||||
ClangExecutableVersion(int major, int minor, int micro)
|
|
||||||
: QVersionNumber(major, minor, micro) {}
|
|
||||||
|
|
||||||
bool isValid() const
|
|
||||||
{
|
|
||||||
return majorVersion() >= 0 && minorVersion() >= 0 && microVersion() >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSupportedVersion() const
|
|
||||||
{
|
|
||||||
return majorVersion() == 5 && minorVersion() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString supportedVersionAsString()
|
|
||||||
{
|
|
||||||
return QLatin1String("5.0");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ClangExecutableVersion clangExecutableVersion(const QString &absolutePath);
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangTools
|
} // namespace ClangTools
|
||||||
|
|||||||
@@ -528,7 +528,7 @@ void CompilerOptionsBuilder::addClangIncludeFolder()
|
|||||||
{
|
{
|
||||||
QTC_CHECK(!m_clangVersion.isEmpty());
|
QTC_CHECK(!m_clangVersion.isEmpty());
|
||||||
add(SYSTEM_INCLUDE_PREFIX);
|
add(SYSTEM_INCLUDE_PREFIX);
|
||||||
add(clangIncludeDirectory());
|
add(clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerOptionsBuilder::addProjectConfigFileInclude()
|
void CompilerOptionsBuilder::addProjectConfigFileInclude()
|
||||||
@@ -548,14 +548,23 @@ static QString creatorLibexecPath()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CompilerOptionsBuilder::clangIncludeDirectory() const
|
QString clangIncludeDirectory(const QString &clangVersion, const QString &clangResourceDirectory)
|
||||||
{
|
{
|
||||||
QDir dir(creatorLibexecPath() + "/clang" + clangIncludePath(m_clangVersion));
|
QDir dir(creatorLibexecPath() + "/clang" + clangIncludePath(clangVersion));
|
||||||
if (!dir.exists() || !QFileInfo(dir, "stdint.h").exists())
|
if (!dir.exists() || !QFileInfo(dir, "stdint.h").exists())
|
||||||
dir = QDir(m_clangResourceDirectory);
|
dir = QDir(clangResourceDirectory);
|
||||||
return QDir::toNativeSeparators(dir.canonicalPath());
|
return QDir::toNativeSeparators(dir.canonicalPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString clangExecutable(const QString &clangBinDirectory)
|
||||||
|
{
|
||||||
|
const QString hostExeSuffix(QTC_HOST_EXE_SUFFIX);
|
||||||
|
QDir executable(creatorLibexecPath() + "/clang/bin/clang" + hostExeSuffix);
|
||||||
|
if (!executable.exists())
|
||||||
|
executable = QDir(clangBinDirectory + "/clang" + hostExeSuffix);
|
||||||
|
return QDir::toNativeSeparators(executable.canonicalPath());
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()
|
void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()
|
||||||
{
|
{
|
||||||
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ private:
|
|||||||
QByteArray macroOption(const ProjectExplorer::Macro ¯o) const;
|
QByteArray macroOption(const ProjectExplorer::Macro ¯o) const;
|
||||||
QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const;
|
QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) const;
|
||||||
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
|
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
|
||||||
QString clangIncludeDirectory() const;
|
|
||||||
void addClangIncludeFolder();
|
void addClangIncludeFolder();
|
||||||
|
|
||||||
QStringList m_options;
|
QStringList m_options;
|
||||||
@@ -98,6 +97,11 @@ private:
|
|||||||
QString m_clangResourceDirectory;
|
QString m_clangResourceDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QString CPPTOOLS_EXPORT clangExecutable(const QString &clangBinDirectory);
|
||||||
|
|
||||||
|
QString CPPTOOLS_EXPORT clangIncludeDirectory(const QString &clangVersion,
|
||||||
|
const QString &clangResourceDirectory);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T clangIncludePath(const T &clangVersion)
|
T clangIncludePath(const T &clangVersion)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
|
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
|
||||||
CLANG_RESOURCE_DIR=$$clean_path($${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include)
|
CLANG_RESOURCE_DIR=$$clean_path($${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include)
|
||||||
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${CLANG_RESOURCE_DIR}\\\"\""
|
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${CLANG_RESOURCE_DIR}\\\"\""
|
||||||
|
CLANG_BINDIR=$$clean_path($${LLVM_BINDIR})
|
||||||
|
DEFINES += "\"CLANG_BINDIR=\\\"$${CLANG_BINDIR}\\\"\""
|
||||||
|
|||||||
Reference in New Issue
Block a user