From 825d344f0676fbc3ffe17f30b30768f303ee62e2 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 31 Jul 2022 22:59:57 +0300 Subject: MSVC: Support cLanguageVersion It is supported since MSVC 16.8[1] and clang-cl 13[2]. [1] https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/ [2] https://github.com/llvm/llvm-project/commit/d087d805acb664e885e9c31a916f6cfa5dbc2186 Change-Id: I858beadf20c357d8a4c369ab7bc32f69ef956ebb Reviewed-by: Ivan Komissarov --- changelogs/changes-1.23.1.md | 1 + share/qbs/modules/cpp/msvc.js | 30 ++++++++++++++++++++-- .../maximum-c-language-version.qbs | 9 ++++--- tests/auto/blackbox/tst_blackbox.cpp | 10 +++++--- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/changelogs/changes-1.23.1.md b/changelogs/changes-1.23.1.md index 430a33bfe..dc4a23535 100644 --- a/changelogs/changes-1.23.1.md +++ b/changelogs/changes-1.23.1.md @@ -4,6 +4,7 @@ # Other modules * Fixed protobuf linking on macOS 11. * Added support for c17 and c2x values in cpp.cLanguageVersion +* Added support for cpp.cLanguageVersion for the MSVC toolchain # Contributors * Christian Kandeler diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js index b206bd4ba..1b70904c0 100644 --- a/share/qbs/modules/cpp/msvc.js +++ b/share/qbs/modules/cpp/msvc.js @@ -102,6 +102,12 @@ function hasCxx20Option(input) || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 13); } +function hasCVerOption(input) +{ + return Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30138.0") >= 0 + || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 13); +} + function supportsExternalIncludesOption(input) { if (input.qbs.toolchain.contains("clang-cl")) return false; // Exclude clang-cl. @@ -112,7 +118,7 @@ function supportsExternalIncludesOption(input) { return Utilities.versionCompare(input.cpp.compilerVersion, "19.16") >= 0; } -function addLanguageVersionFlag(input, args) { +function addCxxLanguageVersionFlag(input, args) { var cxxVersion = Cpp.languageVersion(input.cpp.cxxLanguageVersion, ["c++23", "c++20", "c++17", "c++14", "c++11", "c++98"], "C++"); if (!cxxVersion) @@ -138,6 +144,25 @@ function addLanguageVersionFlag(input, args) { args.push(flag); } +function addCLanguageVersionFlag(input, args) { + var cVersion = Cpp.languageVersion(input.cpp.cLanguageVersion, + ["c17", "c11"], "C"); + if (!cVersion) + return; + + var hasStdOption = hasCVerOption(input); + if (!hasStdOption) + return; + + var flag; + if (cVersion === "c17") + flag = "/std:c17"; + else if (cVersion === "c11") + flag = "/std:c11"; + if (flag) + args.push(flag); +} + function handleClangClArchitectureFlags(product, architecture, flags) { if (product.qbs.toolchain.contains("clang-cl")) { if (architecture === "x86") @@ -277,9 +302,10 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli // Language if (tag === "cpp") { args.push("/TP"); - addLanguageVersionFlag(input, args); + addCxxLanguageVersionFlag(input, args); } else if (tag === "c") { args.push("/TC"); + addCLanguageVersionFlag(input, args); } // Whether we're compiling a precompiled header or normal source file diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs index 320494d00..9f41570f8 100644 --- a/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs +++ b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs @@ -4,10 +4,13 @@ CppApplication { Probe { id: osProbe - property stringList toolchain: qbs.toolchain + property string toolchainType: qbs.toolchainType + property string compilerVersion: cpp.compilerVersion configure: { - if (toolchain.contains("msvc")) - console.info("is msvc"); + console.info("is msvc: " + (toolchainType === "msvc" || toolchainType === "clang-cl")); + var isOld = (toolchainType === "msvc" && compilerVersion < "19.29.30138") + || (toolchainType === "clang-cl" && compilerVersion < "13"); + console.info("is old msvc: " + isOld); found = true; } } diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index bfec09344..20d85d543 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -7916,14 +7916,18 @@ void TestBlackbox::maximumCLanguageVersion() QDir::setCurrent(testDataDir + "/maximum-c-language-version"); QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("products.app.enableNewestModule:true"))), 0); - if (m_qbsStdout.contains("is msvc")) - QSKIP("MSVC has no support for setting the C language version."); + const bool isMsvc = m_qbsStdout.contains("is msvc: true"); + if (isMsvc && m_qbsStdout.contains("is old msvc: true")) + QSKIP("MSVC supports setting the C language version only from version 16.8, and Clang from version 13."); QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line", "-n"})), 0); QVERIFY2(m_qbsStdout.contains("c11") || m_qbsStdout.contains("c1x"), m_qbsStdout.constData()); QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("products.app.enableNewestModule:false"))), 0); QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line", "-n"})), 0); - QVERIFY2(m_qbsStdout.contains("c99"), m_qbsStdout.constData()); + if (isMsvc) + QVERIFY2(!m_qbsStdout.contains("c11"), m_qbsStdout.constData()); + else + QVERIFY2(m_qbsStdout.contains("c99"), m_qbsStdout.constData()); } void TestBlackbox::maximumCxxLanguageVersion() -- cgit v1.2.1