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:
Ivan Donchevskii
2018-04-30 15:26:36 +02:00
parent 80ae992c91
commit 52ac74b61c
21 changed files with 87 additions and 340 deletions

View File

@@ -74,6 +74,11 @@ function libDir(llvmConfig)
return FileInfo.fromNativeSeparators(readOutput(llvmConfig, ["--libdir"]));
}
function binDir(llvmConfig)
{
return FileInfo.fromNativeSeparators(readOutput(llvmConfig, ["--bindir"]));
}
function version(llvmConfig)
{
return readOutput(llvmConfig, ["--version"]).replace(/(\d+\.\d+\.\d+).*/, "$1")

View File

@@ -16,6 +16,7 @@ Module {
property string llvmVersion
property string llvmIncludeDir
property string llvmLibDir
property string llvmBinDir
property stringList llvmLibs
property stringList llvmToolingLibs
property stringList llvmToolingDefines
@@ -28,6 +29,7 @@ Module {
llvmVersion = ClangFunctions.version(llvmConfig);
llvmIncludeDir = ClangFunctions.includeDir(llvmConfig);
llvmLibDir = ClangFunctions.libDir(llvmConfig);
llvmBinDir = ClangFunctions.binDir(llvmConfig);
llvmLibs = ClangFunctions.libraries(targetOS);
llvmToolingLibs = ClangFunctions.toolingLibs(llvmConfig, targetOS);
llvmBuildMode = ClangFunctions.buildMode(llvmConfig);
@@ -43,6 +45,7 @@ Module {
property string llvmVersion: clangProbe.llvmVersion
property string llvmIncludeDir: clangProbe.llvmIncludeDir
property string llvmLibDir: clangProbe.llvmLibDir
property string llvmBinDir: clangProbe.llvmBinDir
property stringList llvmLibs: clangProbe.llvmLibs
property stringList llvmToolingLibs: clangProbe.llvmToolingLibs
property string llvmBuildMode: clangProbe.llvmBuildMode

View File

@@ -27,6 +27,7 @@ QtcPlugin {
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
"include");
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
return defines;
}

View File

@@ -23,6 +23,7 @@ QtcPlugin {
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
"include");
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
return defines;
}

View File

@@ -25,6 +25,7 @@ QtcPlugin {
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
"include");
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
return defines;
}

View File

@@ -43,50 +43,7 @@ ClangStaticAnalyzerConfigWidget::ClangStaticAnalyzerConfigWidget(
{
m_ui->setupUi(this);
Utils::PathChooser * const chooser = m_ui->clangExecutableChooser;
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->setValue(settings->savedSimultaneousProcesses());
m_ui->simultaneousProccessesSpinBox->setMinimum(1);
m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount());
connect(m_ui->simultaneousProccessesSpinBox,
@@ -99,29 +56,5 @@ ClangStaticAnalyzerConfigWidget::~ClangStaticAnalyzerConfigWidget()
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 ClangTools

View File

@@ -45,9 +45,6 @@ public:
QWidget *parent = 0);
~ClangStaticAnalyzerConfigWidget();
void updateDetectedVersionLabel(bool executableIsValid,
const ClangExecutableVersion &providedVersion);
private:
Ui::ClangStaticAnalyzerConfigWidget *m_ui;
ClangToolsSettings *m_settings;

View File

@@ -21,34 +21,13 @@
</property>
<layout class="QFormLayout" name="formLayout">
<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">
<property name="text">
<string>Simultaneous processes:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="simultaneousProccessesSpinBox">
@@ -93,14 +72,6 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -29,6 +29,7 @@
#include "clangstaticanalyzertool.h"
#include "clangtoolsutils.h"
#include <cpptools/compileroptionsbuilder.h>
#include <cpptools/projectinfo.h>
#include <projectexplorer/kitinformation.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);
QTC_ASSERT(toolchain, return false);
bool hasClangExecutable;
clangExecutableFromSettings(&hasClangExecutable);
if (!hasClangExecutable) {
if (CppTools::clangExecutable(CLANG_BINDIR).isEmpty()) {
qWarning("Project \"%s\": Skipping target \"%s\" since no suitable clang was found for the toolchain.",
qPrintable(projectFileName),
qPrintable(target->displayName()));

View File

@@ -147,7 +147,6 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl(RunControl *runCont
ClangToolRunner *ClangStaticAnalyzerRunControl::createRunner()
{
QTC_ASSERT(!m_clangExecutable.isEmpty(), return 0);
QTC_ASSERT(!m_clangLogFileDir.isEmpty(), return 0);
auto runner = new ClangStaticAnalyzerRunner(m_clangExecutable,

View File

@@ -145,18 +145,11 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
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)
{
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,
clangResourceDirectory);
@@ -179,7 +172,9 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
}
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;
}
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());
const QString toolName = tool()->name();
// Some projects provides CompilerCallData once a build is finished,
if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) {
// 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()),
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
Utils::TemporaryDirectory temporaryDir("qtc-clangtools-XXXXXX");
temporaryDir.setAutoRemove(false);
@@ -276,7 +244,7 @@ void ClangToolRunControl::start()
m_clangLogFileDir = temporaryDir.path();
// Collect files
const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(version.toString());
const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(CLANG_VERSION);
qCDebug(LOG) << "Files to process:" << unitsToProcess;
m_unitsToProcess = unitsToProcess;
m_initialFilesToProcessSize = m_unitsToProcess.count();
@@ -298,7 +266,7 @@ void ClangToolRunControl::start()
// Start process(es)
qCDebug(LOG) << "Environment:" << m_environment;
m_runners.clear();
const int parallelRuns = ClangToolsSettings::instance()->simultaneousProcesses();
const int parallelRuns = ClangToolsSettings::instance()->savedSimultaneousProcesses();
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
m_success = true;

View File

@@ -1,6 +1,8 @@
include(../../qtcreatorplugin.pri)
include(../../shared/clang/clang_installation.pri)
include(../../shared/clang/clang_defines.pri)
requires(!isEmpty(LLVM_VERSION))
LIBS += $$LIBCLANG_LIBS

View File

@@ -1,4 +1,5 @@
import qbs
import qbs.FileInfo
QtcPlugin {
name: "ClangTools"
@@ -26,6 +27,19 @@ QtcPlugin {
cpp.dynamicLibraries: base.concat(libclang.llvmLibs)
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: [
"clangstaticanalyzerconfigwidget.cpp",
"clangstaticanalyzerconfigwidget.h",

View File

@@ -35,14 +35,12 @@
#include <QFileInfo>
#include <QThread>
static const char clangExecutableKey[] = "clangExecutable";
static const char simultaneousProcessesKey[] = "simultaneousProcesses";
namespace ClangTools {
namespace Internal {
ClangToolsSettings::ClangToolsSettings()
: m_simultaneousProcesses(-1)
{
readSettings();
}
@@ -53,36 +51,9 @@ ClangToolsSettings *ClangToolsSettings::instance()
return &instance;
}
static QString clangExecutableFileName()
int ClangToolsSettings::savedSimultaneousProcesses() const
{
return QLatin1String("clang" QTC_HOST_EXE_SUFFIX);
}
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;
return m_savedSimultaneousProcesses;
}
int ClangToolsSettings::simultaneousProcesses() const
@@ -92,7 +63,6 @@ int ClangToolsSettings::simultaneousProcesses() const
void ClangToolsSettings::setSimultaneousProcesses(int processes)
{
QTC_ASSERT(processes >=1, return);
m_simultaneousProcesses = processes;
}
@@ -101,21 +71,22 @@ void ClangToolsSettings::readSettings()
QSettings *settings = Core::ICore::settings();
settings->beginGroup(QLatin1String(Constants::SETTINGS_ID));
setClangExecutable(settings->value(QLatin1String(clangExecutableKey)).toString());
const int defaultSimultaneousProcesses = qMax(0, QThread::idealThreadCount() / 2);
setSimultaneousProcesses(settings->value(QLatin1String(simultaneousProcessesKey),
defaultSimultaneousProcesses).toInt());
m_savedSimultaneousProcesses = m_simultaneousProcesses
= settings->value(QString(simultaneousProcessesKey),
defaultSimultaneousProcesses).toInt();
settings->endGroup();
}
void ClangToolsSettings::writeSettings() const
void ClangToolsSettings::writeSettings()
{
QSettings *settings = Core::ICore::settings();
settings->beginGroup(QLatin1String(Constants::SETTINGS_ID));
settings->setValue(QLatin1String(clangExecutableKey), m_clangExecutable);
settings->setValue(QLatin1String(simultaneousProcessesKey), simultaneousProcesses());
settings->beginGroup(QString(Constants::SETTINGS_ID));
settings->setValue(QString(simultaneousProcessesKey), m_simultaneousProcesses);
m_savedSimultaneousProcesses = m_simultaneousProcesses;
settings->endGroup();
}

View File

@@ -35,11 +35,9 @@ class ClangToolsSettings
public:
static ClangToolsSettings *instance();
void writeSettings() const;
void writeSettings();
QString defaultClangExecutable() const;
QString clangExecutable(bool *isSet = nullptr) const;
void setClangExecutable(const QString &exectuable);
int savedSimultaneousProcesses() const;
int simultaneousProcesses() const;
void setSimultaneousProcesses(int processes);
@@ -48,8 +46,8 @@ private:
ClangToolsSettings();
void readSettings();
QString m_clangExecutable;
int m_simultaneousProcesses;
int m_simultaneousProcesses = -1;
int m_savedSimultaneousProcesses = -1;
};
} // namespace Internal

View File

@@ -62,9 +62,8 @@ void ClangToolsUnitTests::initTestCase()
Constants::CXX_LANGUAGE_ID);
if (!toolchain)
QSKIP("This test requires that there is a kit with a toolchain.");
bool hasClangExecutable;
clangExecutableFromSettings(&hasClangExecutable);
if (!hasClangExecutable)
if (CppTools::clangExecutable(CLANG_BINDIR).isEmpty())
QSKIP("No clang suitable for analyzing found");
m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(QLatin1String(":/unit-tests"));

View File

@@ -28,6 +28,8 @@
#include "clangtoolsdiagnostic.h"
#include "clangtoolssettings.h"
#include <coreplugin/icore.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/hostosinfo.h>
@@ -38,118 +40,14 @@
#include <QFileInfo>
#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 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)
{
return location.filePath + QLatin1Char(':') + QString::number(location.line)
+ 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 ClangTools

View File

@@ -39,36 +39,7 @@ namespace Debugger { class DiagnosticLocation; }
namespace ClangTools {
namespace Internal {
bool isClangExecutableUsable(const QString &filePath, QString *errorMessage = 0);
QString clangExecutableFromSettings(bool *isValid);
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 ClangTools

View File

@@ -528,7 +528,7 @@ void CompilerOptionsBuilder::addClangIncludeFolder()
{
QTC_CHECK(!m_clangVersion.isEmpty());
add(SYSTEM_INCLUDE_PREFIX);
add(clangIncludeDirectory());
add(clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory));
}
void CompilerOptionsBuilder::addProjectConfigFileInclude()
@@ -548,14 +548,23 @@ static QString creatorLibexecPath()
#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())
dir = QDir(m_clangResourceDirectory);
dir = QDir(clangResourceDirectory);
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()
{
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {

View File

@@ -90,7 +90,6 @@ private:
QByteArray macroOption(const ProjectExplorer::Macro &macro) const;
QByteArray toDefineOption(const ProjectExplorer::Macro &macro) const;
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
QString clangIncludeDirectory() const;
void addClangIncludeFolder();
QStringList m_options;
@@ -98,6 +97,11 @@ private:
QString m_clangResourceDirectory;
};
QString CPPTOOLS_EXPORT clangExecutable(const QString &clangBinDirectory);
QString CPPTOOLS_EXPORT clangIncludeDirectory(const QString &clangVersion,
const QString &clangResourceDirectory);
template<class T>
T clangIncludePath(const T &clangVersion)
{

View File

@@ -1,3 +1,5 @@
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
CLANG_RESOURCE_DIR=$$clean_path($${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include)
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${CLANG_RESOURCE_DIR}\\\"\""
CLANG_BINDIR=$$clean_path($${LLVM_BINDIR})
DEFINES += "\"CLANG_BINDIR=\\\"$${CLANG_BINDIR}\\\"\""