diff options
21 files changed, 87 insertions, 340 deletions
diff --git a/qbs/modules/libclang/functions.js b/qbs/modules/libclang/functions.js index 7d5e4149fca..192473391ae 100644 --- a/qbs/modules/libclang/functions.js +++ b/qbs/modules/libclang/functions.js @@ -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") diff --git a/qbs/modules/libclang/libclang.qbs b/qbs/modules/libclang/libclang.qbs index 3b68faa0bb7..eeb233f12a9 100644 --- a/qbs/modules/libclang/libclang.qbs +++ b/qbs/modules/libclang/libclang.qbs @@ -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 diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index 8950c6ed9b2..ce1cba0e1fa 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -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; } diff --git a/src/plugins/clangpchmanager/clangpchmanager.qbs b/src/plugins/clangpchmanager/clangpchmanager.qbs index b8ade5b6ce1..8e7c5447a6c 100644 --- a/src/plugins/clangpchmanager/clangpchmanager.qbs +++ b/src/plugins/clangpchmanager/clangpchmanager.qbs @@ -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; } diff --git a/src/plugins/clangrefactoring/clangrefactoring.qbs b/src/plugins/clangrefactoring/clangrefactoring.qbs index d76bca9f489..9778e1a3d04 100644 --- a/src/plugins/clangrefactoring/clangrefactoring.qbs +++ b/src/plugins/clangrefactoring/clangrefactoring.qbs @@ -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; } diff --git a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp index 812984cafcf..9058774f596 100644 --- a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp +++ b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp @@ -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 diff --git a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h index 629fe4d8192..7b23b35d5d0 100644 --- a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h +++ b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h @@ -45,9 +45,6 @@ public: QWidget *parent = 0); ~ClangStaticAnalyzerConfigWidget(); - void updateDetectedVersionLabel(bool executableIsValid, - const ClangExecutableVersion &providedVersion); - private: Ui::ClangStaticAnalyzerConfigWidget *m_ui; ClangToolsSettings *m_settings; diff --git a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui index d4cb9c60e8d..69a9d28063b 100644 --- a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui +++ b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui @@ -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> diff --git a/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp b/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp index 392608e759c..31d9efb518f 100644 --- a/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp +++ b/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp @@ -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())); diff --git a/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp index 5684ae875e6..e9585665337 100644 --- a/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp +++ b/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp @@ -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, diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index 4e0b609dd17..d2e03f48a47 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -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; diff --git a/src/plugins/clangtools/clangtools.pro b/src/plugins/clangtools/clangtools.pro index 847f4bc9f46..505b01ebbeb 100644 --- a/src/plugins/clangtools/clangtools.pro +++ b/src/plugins/clangtools/clangtools.pro @@ -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 diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs index 9601b3793b6..0875b052911 100644 --- a/src/plugins/clangtools/clangtools.qbs +++ b/src/plugins/clangtools/clangtools.qbs @@ -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", diff --git a/src/plugins/clangtools/clangtoolssettings.cpp b/src/plugins/clangtools/clangtoolssettings.cpp index 5c51ed84713..50bad3f82af 100644 --- a/src/plugins/clangtools/clangtoolssettings.cpp +++ b/src/plugins/clangtools/clangtoolssettings.cpp @@ -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(); } diff --git a/src/plugins/clangtools/clangtoolssettings.h b/src/plugins/clangtools/clangtoolssettings.h index 0739d630ec0..528407fe50b 100644 --- a/src/plugins/clangtools/clangtoolssettings.h +++ b/src/plugins/clangtools/clangtoolssettings.h @@ -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 diff --git a/src/plugins/clangtools/clangtoolsunittests.cpp b/src/plugins/clangtools/clangtoolsunittests.cpp index b98f9ff8feb..3c31d933700 100644 --- a/src/plugins/clangtools/clangtoolsunittests.cpp +++ b/src/plugins/clangtools/clangtoolsunittests.cpp @@ -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")); diff --git a/src/plugins/clangtools/clangtoolsutils.cpp b/src/plugins/clangtools/clangtoolsutils.cpp index cd43b397371..3e811500ac9 100644 --- a/src/plugins/clangtools/clangtoolsutils.cpp +++ b/src/plugins/clangtools/clangtoolsutils.cpp @@ -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 diff --git a/src/plugins/clangtools/clangtoolsutils.h b/src/plugins/clangtools/clangtoolsutils.h index a63c9db3707..6d3a7a90caf 100644 --- a/src/plugins/clangtools/clangtoolsutils.h +++ b/src/plugins/clangtools/clangtoolsutils.h @@ -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 diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 93e6ed3c10d..57f937fb18b 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -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) { diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h index 2f860e510bd..87dc46ff26a 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.h +++ b/src/plugins/cpptools/compileroptionsbuilder.h @@ -90,7 +90,6 @@ private: QByteArray macroOption(const ProjectExplorer::Macro ¯o) const; QByteArray toDefineOption(const ProjectExplorer::Macro ¯o) 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) { diff --git a/src/shared/clang/clang_defines.pri b/src/shared/clang/clang_defines.pri index e1d219989f0..4453c8ba6de 100644 --- a/src/shared/clang/clang_defines.pri +++ b/src/shared/clang/clang_defines.pri @@ -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}\\\"\"" |