aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/projectexplorer
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2024-02-02 10:56:42 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2024-02-05 10:44:13 +0000
commit05d9e50aff16e18f1e9b48efd136916274a7d38b (patch)
tree3a53032a2836f89d224879ae1267d195668f46f9 /src/plugins/projectexplorer
parent220237d029b52b8673ca41c470ed58f7fdfbab1e (diff)
ProjectExplorer: Check full ABI, not just word width
... when choosing the default MSVC for clang-cl. Fixes: QTCREATORBUG-30060 Change-Id: I59c4e7dbf227596cbd57c5421eb5a3da7a16c0a0 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Diffstat (limited to 'src/plugins/projectexplorer')
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp143
1 files changed, 85 insertions, 58 deletions
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index e767a62db8..67d3f32781 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -37,11 +37,12 @@
#include <QVector>
#include <QVersionNumber>
-#include <QLabel>
#include <QComboBox>
+#include <QDateTime>
#include <QFormLayout>
+#include <QLabel>
-#include <optional>
+#include <utility>
using namespace Utils;
@@ -1566,70 +1567,54 @@ void ClangClToolchainConfigWidget::setFromClangClToolchain()
m_compilerCommand->setFilePath(clangClToolchain->clangPath());
}
-static const MsvcToolchain *findMsvcToolChain(unsigned char wordWidth, Abi::OSFlavor flavor)
-{
- return Utils::findOrDefault(g_availableMsvcToolchains,
- [wordWidth, flavor](const MsvcToolchain *tc) {
- const Abi abi = tc->targetAbi();
- return abi.osFlavor() == flavor && wordWidth == abi.wordWidth();
- });
-}
-
-static const MsvcToolchain *findMsvcToolChain(const QString &displayedVarsBat)
-{
- return Utils::findOrDefault(g_availableMsvcToolchains,
- [&displayedVarsBat] (const MsvcToolchain *tc) {
- return msvcVarsToDisplay(*tc) == displayedVarsBat;
- });
-}
-
-static QVersionNumber clangClVersion(const FilePath &clangClPath)
+class ClangClInfo
{
- QString error;
- QString dllversion = winGetDLLVersion(Utils::WinDLLFileVersion, clangClPath.toString(), &error);
+public:
+ FilePath filePath() const { return m_filePath; }
+ QVersionNumber version() const { return m_version; }
+ Abi defaultAbi() const { return m_defaultAbi; }
- if (!dllversion.isEmpty())
- return QVersionNumber::fromString(dllversion);
+ static ClangClInfo getInfo(const FilePath &filePath);
- Process clangClProcess;
- clangClProcess.setCommand({clangClPath, {"--version"}});
- clangClProcess.runBlocking();
- if (clangClProcess.result() != ProcessResult::FinishedWithSuccess)
- return {};
- const QRegularExpressionMatch match = QRegularExpression(
- QStringLiteral("clang version (\\d+(\\.\\d+)+)"))
- .match(clangClProcess.cleanedStdOut());
- if (!match.hasMatch())
- return {};
- return QVersionNumber::fromString(match.captured(1));
-}
+private:
+ FilePath m_filePath;
+ QVersionNumber m_version;
+ Abi m_defaultAbi;
+ static inline QHash<FilePath, std::pair<ClangClInfo, QDateTime>> m_cache;
+};
static const MsvcToolchain *selectMsvcToolChain(const QString &displayedVarsBat,
- const FilePath &clangClPath,
- unsigned char wordWidth)
+ const FilePath &clangClPath)
{
- const MsvcToolchain *toolChain = nullptr;
if (!displayedVarsBat.isEmpty()) {
- toolChain = findMsvcToolChain(displayedVarsBat);
- if (toolChain)
- return toolChain;
+ if (const auto tc = Utils::findOrDefault(g_availableMsvcToolchains,
+ [&displayedVarsBat](const MsvcToolchain *tc) {
+ return msvcVarsToDisplay(*tc)
+ == displayedVarsBat;
+ }))
+ return tc;
}
QTC_CHECK(displayedVarsBat.isEmpty());
- const QVersionNumber version = clangClVersion(clangClPath);
- if (version.majorVersion() >= 6) {
- toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2022Flavor);
- if (!toolChain)
- toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2019Flavor);
- if (!toolChain)
- toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2017Flavor);
- }
- if (!toolChain) {
- toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2015Flavor);
- if (!toolChain)
- toolChain = findMsvcToolChain(wordWidth, Abi::WindowsMsvc2013Flavor);
+ const ClangClInfo clangClInfo = ClangClInfo::getInfo(clangClPath);
+ QList<Abi::OSFlavor> flavors;
+ if (clangClInfo.version().majorVersion() >= 6)
+ flavors << Abi::WindowsMsvc2022Flavor << Abi::WindowsMsvc2019Flavor
+ << Abi::WindowsMsvc2017Flavor;
+ flavors << Abi::WindowsMsvc2015Flavor << Abi::WindowsMsvc2013Flavor;
+ for (const Abi::OSFlavor flavor : flavors) {
+ if (const auto tc = Utils::findOrDefault(g_availableMsvcToolchains,
+ [&clangClInfo, flavor](const MsvcToolchain *tc) {
+ const Abi abi = tc->targetAbi();
+ return abi.osFlavor() == flavor
+ && abi.isCompatibleWith(
+ clangClInfo.defaultAbi())
+ && tc->hostPrefersToolchain();
+ })) {
+ return tc;
+ }
}
- return toolChain;
+ return nullptr;
}
static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath,
@@ -1638,8 +1623,7 @@ static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath,
bool isDefault = false)
{
Toolchains res;
- const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32;
- const MsvcToolchain *toolChain = selectMsvcToolChain(displayedVarsBat, clangClPath, wordWidth);
+ const MsvcToolchain *toolChain = selectMsvcToolChain(displayedVarsBat, clangClPath);
if (!toolChain) {
qWarning("Unable to find a suitable MSVC version for \"%s\".",
@@ -1650,7 +1634,7 @@ static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath,
const Abi targetAbi = toolChain->targetAbi();
const QString name = QString("%1LLVM %2 bit based on %3")
.arg(QLatin1String(isDefault ? "Default " : ""))
- .arg(wordWidth)
+ .arg(targetAbi.wordWidth())
.arg(Abi::toString(targetAbi.osFlavor()).toUpper());
for (auto language : {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) {
ClangClToolchain *tc = static_cast<ClangClToolchain *>(
@@ -2292,6 +2276,49 @@ void setupClangClToolchain()
#endif
}
+ClangClInfo ClangClInfo::getInfo(const FilePath &filePath)
+{
+ QTC_ASSERT(!filePath.isEmpty(), return {});
+
+ auto &entry = m_cache[filePath];
+ ClangClInfo &info = entry.first;
+ const QDateTime lastModified = filePath.lastModified();
+ if (entry.second == lastModified)
+ return info;
+
+ entry.second = lastModified;
+ Process clangClProcess;
+ clangClProcess.setCommand({filePath, {"--version"}});
+ clangClProcess.runBlocking();
+ if (clangClProcess.result() == ProcessResult::FinishedWithSuccess) {
+ const QString stdOut = clangClProcess.cleanedStdOut();
+ const QRegularExpressionMatch versionMatch
+ = QRegularExpression("clang version (\\d+(\\.\\d+)+)").match(stdOut);
+ if (versionMatch.hasMatch())
+ info.m_version = QVersionNumber::fromString(versionMatch.captured(1));
+ const QString targetKey = "Target:";
+ int startOffset = stdOut.indexOf(targetKey);
+ if (startOffset != -1) {
+ startOffset += targetKey.length();
+ const int endOffset = stdOut.indexOf('\n', startOffset);
+ if (endOffset != -1) {
+ const Abi detectedAbi = Abi::abiFromTargetTriplet(
+ stdOut.mid(startOffset, endOffset - startOffset).trimmed());
+
+ // Abi::fromTargetTriple() always detects clang triples as msys,
+ // but here in clang-cl context we know that's wrong.
+ info.m_defaultAbi = Abi(detectedAbi.architecture(),
+ detectedAbi.os(),
+ Abi::UnknownFlavor,
+ detectedAbi.binaryFormat(),
+ detectedAbi.wordWidth());
+ }
+ }
+ }
+ m_cache.insert(filePath, entry);
+ return info;
+}
+
} // namespace ProjectExplorer::Internal
Q_DECLARE_METATYPE(ProjectExplorer::Internal::MsvcToolchain::Platform)