summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-12-11 16:17:09 +0100
committerIvan Donchevskii <ivan.donchevskii@qt.io>2019-01-10 08:37:23 +0000
commit4c191572044d4483f09b3b8d0f76ef164bd8f225 (patch)
tree8f12faf8927494d48a4e4c89a80f78265b76804a
parent03a042d5498215d3324451e5629f504b65e49daa (diff)
downloadqt-creator-4c191572044d4483f09b3b8d0f76ef164bd8f225.tar.gz
ProjectExplorer: Allow to select MSVC environment for clang-cl
clang-cl compiler can work with multiple MSVC toolchains. Let's make a combobox out of all available MSVC scripts + vars to switch the MSVC base for manual clang-cl toolchains. Fixes: QTCREATORBUG-21604 Change-Id: Iac3c726a813bb593d4350886e98aa636c94b52cf Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp113
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.h15
2 files changed, 105 insertions, 23 deletions
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 004328c620..413f80a565 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -57,6 +57,7 @@
#include <QVersionNumber>
#include <QLabel>
+#include <QComboBox>
#include <QFormLayout>
#define KEY_ROOT "ProjectExplorer.MsvcToolChain."
@@ -783,12 +784,12 @@ MsvcToolChain::MsvcToolChain(const QString &name,
MsvcToolChain::MsvcToolChain(const MsvcToolChain &other)
: ToolChain(other)
+ , m_headerPathsMutex(new QMutex)
, m_environmentModifications(other.m_environmentModifications)
, m_debuggerCommand(other.m_debuggerCommand)
, m_predefinedMacrosCache(other.m_predefinedMacrosCache)
, m_lastEnvironment(other.m_lastEnvironment)
, m_resultEnvironment(other.m_resultEnvironment)
- , m_headerPathsMutex(new QMutex)
, m_abi(other.m_abi)
, m_vcvarsBat(other.m_vcvarsBat)
, m_varsBatArg(other.m_varsBatArg)
@@ -810,6 +811,14 @@ MsvcToolChain::MsvcToolChain(const MsvcToolChain &other)
setDisplayName(other.displayName());
}
+static void addToAvailableMsvcToolchains(const MsvcToolChain *toolchain)
+{
+ if (toolchain->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
+ return;
+
+ g_availableMsvcToolchains.push_back(toolchain);
+}
+
MsvcToolChain::MsvcToolChain(Core::Id typeId,
const QString &name,
const Abi &abi,
@@ -818,13 +827,15 @@ MsvcToolChain::MsvcToolChain(Core::Id typeId,
Core::Id l,
Detection d)
: ToolChain(typeId, d)
+ , m_headerPathsMutex(new QMutex)
, m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>())
, m_lastEnvironment(Utils::Environment::systemEnvironment())
- , m_headerPathsMutex(new QMutex)
, m_abi(abi)
, m_vcvarsBat(varsBat)
, m_varsBatArg(varsBatArg)
{
+ addToAvailableMsvcToolchains(this);
+
setLanguage(l);
initEnvModWatcher(Utils::runAsync(envModThreadPool(),
&MsvcToolChain::environmentModifications,
@@ -872,6 +883,7 @@ MsvcToolChain::MsvcToolChain()
MsvcToolChain::~MsvcToolChain()
{
+ g_availableMsvcToolchains.removeOne(this);
delete m_headerPathsMutex;
}
@@ -967,6 +979,8 @@ bool MsvcToolChain::fromMap(const QVariantMap &data)
return false;
m_vcvarsBat = QDir::fromNativeSeparators(data.value(QLatin1String(varsBatKeyC)).toString());
m_varsBatArg = data.value(QLatin1String(varsBatArgKeyC)).toString();
+ addToAvailableMsvcToolchains(this);
+
const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
m_abi = Abi::fromString(abiString);
m_environmentModifications = Utils::EnvironmentItem::itemsFromVariantList(
@@ -1218,17 +1232,22 @@ MsvcBasedToolChainConfigWidget::MsvcBasedToolChainConfigWidget(ToolChain *tc)
m_mainLayout->addRow(tr("Initialization:"), m_varsBatDisplayLabel);
}
+static QString msvcVarsToDisplay(const MsvcToolChain &tc)
+{
+ QString varsBatDisplay = QDir::toNativeSeparators(tc.varsBat());
+ if (!tc.varsBatArg().isEmpty()) {
+ varsBatDisplay += QLatin1Char(' ');
+ varsBatDisplay += tc.varsBatArg();
+ }
+ return varsBatDisplay;
+}
+
void MsvcBasedToolChainConfigWidget::setFromMsvcToolChain()
{
const auto *tc = static_cast<const MsvcToolChain *>(toolChain());
QTC_ASSERT(tc, return );
m_nameDisplayLabel->setText(tc->displayName());
- QString varsBatDisplay = QDir::toNativeSeparators(tc->varsBat());
- if (!tc->varsBatArg().isEmpty()) {
- varsBatDisplay += QLatin1Char(' ');
- varsBatDisplay += tc->varsBatArg();
- }
- m_varsBatDisplayLabel->setText(varsBatDisplay);
+ m_varsBatDisplayLabel->setText(msvcVarsToDisplay(*tc));
}
// --------------------------------------------------------------------------
@@ -1246,9 +1265,15 @@ MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc)
// ClangClToolChainConfigWidget
// --------------------------------------------------------------------------
-ClangClToolChainConfigWidget::ClangClToolChainConfigWidget(ToolChain *tc)
- : MsvcBasedToolChainConfigWidget(tc)
+ClangClToolChainConfigWidget::ClangClToolChainConfigWidget(ToolChain *tc) :
+ MsvcBasedToolChainConfigWidget(tc),
+ m_varsBatDisplayCombo(new QComboBox(this))
{
+ m_mainLayout->removeRow(m_mainLayout->rowCount() - 1);
+
+ m_varsBatDisplayCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+ m_mainLayout->addRow(tr("Initialization:"), m_varsBatDisplayCombo);
+
if (tc->isAutoDetected()) {
m_llvmDirLabel = new QLabel(this);
m_llvmDirLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
@@ -1274,7 +1299,16 @@ ClangClToolChainConfigWidget::ClangClToolChainConfigWidget(ToolChain *tc)
void ClangClToolChainConfigWidget::setFromClangClToolChain()
{
- setFromMsvcToolChain();
+ const auto *currentTC = static_cast<const MsvcToolChain *>(toolChain());
+ m_nameDisplayLabel->setText(currentTC->displayName());
+ m_varsBatDisplayCombo->clear();
+ m_varsBatDisplayCombo->addItem(msvcVarsToDisplay(*currentTC));
+ for (const MsvcToolChain *tc : g_availableMsvcToolchains) {
+ const QString varsToDisplay = msvcVarsToDisplay(*tc);
+ if (m_varsBatDisplayCombo->findText(varsToDisplay) == -1)
+ m_varsBatDisplayCombo->addItem(varsToDisplay);
+ }
+
const auto *clangClToolChain = static_cast<const ClangClToolChain *>(toolChain());
if (clangClToolChain->isAutoDetected())
m_llvmDirLabel->setText(QDir::toNativeSeparators(clangClToolChain->clangPath()));
@@ -1291,6 +1325,14 @@ static const MsvcToolChain *findMsvcToolChain(unsigned char wordWidth, Abi::OSFl
});
}
+static const MsvcToolChain *findMsvcToolChain(const QString &displayedVarsBat)
+{
+ return Utils::findOrDefault(g_availableMsvcToolchains,
+ [&displayedVarsBat] (const MsvcToolChain *tc) {
+ return msvcVarsToDisplay(*tc) == displayedVarsBat;
+ });
+}
+
static QVersionNumber clangClVersion(const QString &clangClPath)
{
Utils::SynchronousProcess clangClProcess;
@@ -1306,9 +1348,18 @@ static QVersionNumber clangClVersion(const QString &clangClPath)
return QVersionNumber::fromString(match.captured(1));
}
-static const MsvcToolChain *selectMsvcToolChain(const QString &clangClPath, unsigned char wordWidth)
+static const MsvcToolChain *selectMsvcToolChain(const QString &displayedVarsBat,
+ const QString &clangClPath,
+ unsigned char wordWidth)
{
const MsvcToolChain *toolChain = nullptr;
+ if (!displayedVarsBat.isEmpty()) {
+ toolChain = findMsvcToolChain(displayedVarsBat);
+ if (toolChain)
+ return toolChain;
+ }
+
+ QTC_CHECK(displayedVarsBat.isEmpty());
const QVersionNumber version = clangClVersion(clangClPath);
if (version.majorVersion() >= 6)
toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2017Flavor);
@@ -1322,11 +1373,12 @@ static const MsvcToolChain *selectMsvcToolChain(const QString &clangClPath, unsi
static QList<ToolChain *> detectClangClToolChainInPath(const QString &clangClPath,
const QList<ToolChain *> &alreadyKnown,
+ const QString &displayedVarsBat,
bool isDefault = false)
{
QList<ToolChain *> res;
const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32;
- const MsvcToolChain *toolChain = selectMsvcToolChain(clangClPath, wordWidth);
+ const MsvcToolChain *toolChain = selectMsvcToolChain(displayedVarsBat, clangClPath, wordWidth);
if (!toolChain) {
qWarning("Unable to find a suitable MSVC version for \"%s\".",
@@ -1378,7 +1430,10 @@ void ClangClToolChainConfigWidget::applyImpl()
return;
}
- QList<ToolChain *> results = detectClangClToolChainInPath(clangClPath.toString(), {});
+ const QString displayedVarsBat = m_varsBatDisplayCombo->currentText();
+ QList<ToolChain *> results = detectClangClToolChainInPath(clangClPath.toString(),
+ {},
+ displayedVarsBat);
if (results.isEmpty()) {
clangClToolChain->resetMsvcToolChain();
@@ -1400,6 +1455,11 @@ void ClangClToolChainConfigWidget::discardImpl()
setFromClangClToolChain();
}
+void ClangClToolChainConfigWidget::makeReadOnlyImpl()
+{
+ m_varsBatDisplayCombo->setEnabled(false);
+}
+
// --------------------------------------------------------------------------
// ClangClToolChain, piggy-backing on MSVC2015 and providing the compiler
// clang-cl.exe as a [to some extent] compatible drop-in replacement for cl.
@@ -1545,6 +1605,22 @@ LanguageVersion ClangClToolChain::msvcLanguageVersion(const QStringList &cxxflag
return MsvcToolChain::msvcLanguageVersion(cxxflags, language, macros);
}
+void ClangClToolChain::toolChainUpdated()
+{
+ MsvcToolChain::toolChainUpdated();
+ ToolChain::toolChainUpdated();
+}
+
+ClangClToolChain::BuiltInHeaderPathsRunner ClangClToolChain::createBuiltInHeaderPathsRunner() const
+{
+ {
+ QMutexLocker locker(m_headerPathsMutex);
+ m_headerPaths.clear();
+ }
+
+ return MsvcToolChain::createBuiltInHeaderPathsRunner();
+}
+
// --------------------------------------------------------------------------
// MsvcToolChainFactory
// --------------------------------------------------------------------------
@@ -1725,9 +1801,6 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
detectCppBuildTools2015(&results);
- for (const ToolChain *toolchain : results)
- g_availableMsvcToolchains.append(static_cast<const MsvcToolChain *>(toolchain));
-
return results;
}
@@ -1760,7 +1833,7 @@ QList<ToolChain *> ClangClToolChainFactory::autoDetect(const QList<ToolChain *>
.parentDir()
.appendPath("clang-cl.exe")
.toString();
- results.append(detectClangClToolChainInPath(qtCreatorsClang, alreadyKnown, true));
+ results.append(detectClangClToolChainInPath(qtCreatorsClang, alreadyKnown, "", true));
known.append(results);
}
@@ -1769,7 +1842,7 @@ QList<ToolChain *> ClangClToolChainFactory::autoDetect(const QList<ToolChain *>
const QString path = QDir::cleanPath(registry.value(QStringLiteral(".")).toString());
const QString clangClPath = compilerFromPath(path);
if (!path.isEmpty()) {
- results.append(detectClangClToolChainInPath(clangClPath, known));
+ results.append(detectClangClToolChainInPath(clangClPath, known, ""));
known.append(results);
}
}
@@ -1777,7 +1850,7 @@ QList<ToolChain *> ClangClToolChainFactory::autoDetect(const QList<ToolChain *>
const Utils::Environment systemEnvironment = Utils::Environment::systemEnvironment();
const Utils::FileName clangClPath = systemEnvironment.searchInPath("clang-cl");
if (!clangClPath.isEmpty())
- results.append(detectClangClToolChainInPath(clangClPath.toString(), known));
+ results.append(detectClangClToolChainInPath(clangClPath.toString(), known, ""));
return results;
}
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
index f8cfefbead..90c941c412 100644
--- a/src/plugins/projectexplorer/msvctoolchain.h
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -36,6 +36,7 @@
#include <utils/optional.h>
QT_FORWARD_DECLARE_CLASS(QLabel)
+QT_FORWARD_DECLARE_CLASS(QComboBox)
QT_FORWARD_DECLARE_CLASS(QVersionNumber)
namespace Utils {
@@ -153,6 +154,10 @@ protected:
QString varsBatArg);
void initEnvModWatcher(const QFuture<GenerateEnvResult> &future);
+protected:
+ mutable QMutex *m_headerPathsMutex = nullptr;
+ mutable HeaderPaths m_headerPaths;
+
private:
void updateEnvironmentModifications(QList<Utils::EnvironmentItem> modifications);
@@ -165,8 +170,6 @@ private:
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
- mutable QMutex *m_headerPathsMutex = nullptr;
- mutable HeaderPaths m_headerPaths;
protected:
Abi m_abi;
@@ -191,6 +194,7 @@ public:
QVariantMap toMap() const override;
bool fromMap(const QVariantMap &data) override;
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
const QList<MsvcToolChain *> &msvcToolchains() const;
QString clangPath() const { return m_clangPath; }
@@ -206,6 +210,9 @@ public:
bool operator==(const ToolChain &) const override;
private:
+ void toolChainUpdated() override;
+
+private:
QString m_clangPath;
};
@@ -266,7 +273,7 @@ protected:
void setFromMsvcToolChain();
-private:
+protected:
QLabel *m_nameDisplayLabel;
QLabel *m_varsBatDisplayLabel;
};
@@ -297,11 +304,13 @@ public:
protected:
void applyImpl() override;
void discardImpl() override;
+ void makeReadOnlyImpl() override;
private:
void setFromClangClToolChain();
QLabel *m_llvmDirLabel = nullptr;
+ QComboBox *m_varsBatDisplayCombo = nullptr;
Utils::PathChooser *m_compilerCommand = nullptr;
};