From 378b057a9f29829ac0c2e38c408df8e9568a9791 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 9 Jul 2015 17:19:21 +0200 Subject: By default, look for the clang executable in Creator's libexec dir. It will be part of the installation from 3.5 on. Also look explicitly for "clang-cl" on Windows now, as we do not ship clang.exe. Change-Id: I67e22ed4251791dd59015dd6f9648c7a14d941d7 Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzerconfigwidget.cpp | 26 +++++++++++++++--- .../clangstaticanalyzerconstants.h | 1 - .../clangstaticanalyzersettings.cpp | 31 +++++++++++++++++----- .../clangstaticanalyzersettings.h | 3 ++- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp index 6bc81cac64..58fa6d0c47 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp @@ -40,11 +40,31 @@ ClangStaticAnalyzerConfigWidget::ClangStaticAnalyzerConfigWidget( chooser->setHistoryCompleter(QLatin1String("ClangStaticAnalyzer.ClangCommand.History")); chooser->setPromptDialogTitle(tr("Clang Command")); const auto validator = [chooser](Utils::FancyLineEdit *edit, QString *errorMessage) { - return chooser->defaultValidationFunction()(edit, errorMessage) - && isClangExecutableUsable(chooser->fileName().toString(), 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; + } + return chooser->defaultValidationFunction()(helperPathChooser->lineEdit(), errorMessage) + && isClangExecutableUsable(helperPathChooser->fileName().toString(), errorMessage); }; chooser->setValidationFunction(validator); - chooser->setPath(settings->clangExecutable()); + bool clangExeIsSet; + const QString clangExe = settings->clangExecutable(&clangExeIsSet); + chooser->lineEdit()->setPlaceholderText(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::changed, [settings](const QString &path) { settings->setClangExecutable(path); }); diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerconstants.h b/plugins/clangstaticanalyzer/clangstaticanalyzerconstants.h index 1114730614..bc696b5b9d 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerconstants.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerconstants.h @@ -22,7 +22,6 @@ namespace ClangStaticAnalyzer { namespace Constants { -const char CLANG_EXECUTABLE_BASE_NAME[] = "clang"; const char SETTINGS_ID[] = "ClangStaticAnalyzer"; const char CLANGSTATICANALYZER_RUN_MODE[] = "ClangStaticAnalyzer.RunMode"; diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzersettings.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzersettings.cpp index 97c456ff81..3ab12ef958 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzersettings.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzersettings.cpp @@ -46,14 +46,34 @@ ClangStaticAnalyzerSettings *ClangStaticAnalyzerSettings::instance() return &instance; } -QString ClangStaticAnalyzerSettings::clangExecutable() const +static QString clangExecutableFileName() { + return QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "clang-cl.exe" : "clang"); +} + +QString ClangStaticAnalyzerSettings::defaultClangExecutable() const +{ + const QString shippedBinary = Core::ICore::libexecPath() + QLatin1Char('/') + + clangExecutableFileName(); + if (QFileInfo(shippedBinary).isExecutable()) + return shippedBinary; + return clangExecutableFileName(); +} + +QString ClangStaticAnalyzerSettings::clangExecutable(bool *isSet) const +{ + if (m_clangExecutable.isEmpty()) { + if (isSet) + *isSet = false; + return defaultClangExecutable(); + } + if (isSet) + *isSet = true; return m_clangExecutable; } void ClangStaticAnalyzerSettings::setClangExecutable(const QString &exectuable) { - QTC_ASSERT(!exectuable.isEmpty(), return); m_clangExecutable = exectuable; } @@ -73,10 +93,7 @@ void ClangStaticAnalyzerSettings::readSettings() QSettings *settings = Core::ICore::settings(); settings->beginGroup(QLatin1String(Constants::SETTINGS_ID)); - const QString defaultClangExecutable = Utils::HostOsInfo::withExecutableSuffix( - QLatin1String(Constants::CLANG_EXECUTABLE_BASE_NAME)); - setClangExecutable(settings->value(QLatin1String(clangExecutableKey), - defaultClangExecutable).toString()); + setClangExecutable(settings->value(QLatin1String(clangExecutableKey)).toString()); const int defaultSimultaneousProcesses = qMax(0, QThread::idealThreadCount() / 2); setSimultaneousProcesses(settings->value(QLatin1String(simultaneousProcessesKey), @@ -89,7 +106,7 @@ void ClangStaticAnalyzerSettings::writeSettings() const { QSettings *settings = Core::ICore::settings(); settings->beginGroup(QLatin1String(Constants::SETTINGS_ID)); - settings->setValue(QLatin1String(clangExecutableKey), clangExecutable()); + settings->setValue(QLatin1String(clangExecutableKey), m_clangExecutable); settings->setValue(QLatin1String(simultaneousProcessesKey), simultaneousProcesses()); settings->endGroup(); } diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzersettings.h b/plugins/clangstaticanalyzer/clangstaticanalyzersettings.h index 70f85d4912..c4b9794736 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzersettings.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzersettings.h @@ -31,7 +31,8 @@ public: void writeSettings() const; - QString clangExecutable() const; + QString defaultClangExecutable() const; + QString clangExecutable(bool *isSet = nullptr) const; void setClangExecutable(const QString &exectuable); int simultaneousProcesses() const; -- cgit v1.2.1