diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2017-08-22 17:12:47 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2017-08-23 15:09:56 +0000 |
commit | 29ff75ef89d93934bdbc38e24398e766e6597508 (patch) | |
tree | 1db4075256f98eeb9536b3750c15ddc0e80eb82a | |
parent | 1b046f750bb3bd26d97073c648662c672eb0fc95 (diff) |
Support MSVC's /std option
We failed to notice that it was introduced with update 3 of VS 2013.
[ChangeLog] The cpp.cxxLanguageVersion property now gets mapped to
MSVC's /std option, if applicable.
Change-Id: I00d45aecefb2ad27f2b5891d62d591179f2dbeec
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r-- | changelogs/changes-1.9.0.md | 2 | ||||
-rw-r--r-- | share/qbs/modules/cpp/msvc.js | 25 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs | 30 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata/cxx-language-version/main.cpp | 1 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.cpp | 77 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.h | 2 |
6 files changed, 135 insertions, 2 deletions
diff --git a/changelogs/changes-1.9.0.md b/changelogs/changes-1.9.0.md index 55345c1cc..2e3cbfa09 100644 --- a/changelogs/changes-1.9.0.md +++ b/changelogs/changes-1.9.0.md @@ -41,6 +41,8 @@ upward (see the `ld64` man page for more information). * The property `cpp.useCxxPrecompiledHeader`, as well as the variants for the other languages, now defaults to true. +* The property `cpp.cxxLanguageVersion` now gets mapped to MSVC's `/std` option, + if applicable. # Apple * Added support for building macOS disk images. diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js index a79523ca9..6ca6dad00 100644 --- a/share/qbs/modules/cpp/msvc.js +++ b/share/qbs/modules/cpp/msvc.js @@ -43,6 +43,25 @@ function compilerVersionDefine(cpp) { return result; } +function addLanguageVersionFlag(input, args) { + var cxxVersion = input.cpp.cxxLanguageVersion; + if (!cxxVersion) + return; + + // Visual C++ 2013, Update 3 + var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0; + if (!hasStdOption) + return; + + var flag; + if (cxxVersion === "c++14") + flag = "/std:c++14"; + else if (cxxVersion !== "c++11" && cxxVersion !== "c++98") + flag = "/std:c++latest"; + if (flag) + args.push(flag); +} + function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) { var i; var debugInformation = input.cpp.debugInformation; @@ -148,10 +167,12 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli args.push("/FI" + FileInfo.toWindowsSeparators(prefixHeaders[i])); // Language - if (tag === "cpp") + if (tag === "cpp") { args.push("/TP"); - else if (tag === "c") + addLanguageVersionFlag(input, args); + } else if (tag === "c") { args.push("/TC"); + } // Whether we're compiling a precompiled header or normal source file var pchOutput = outputs[tag + "_pch"] ? outputs[tag + "_pch"][0] : undefined; diff --git a/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs new file mode 100644 index 000000000..436c64c5e --- /dev/null +++ b/tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs @@ -0,0 +1,30 @@ +import qbs + +CppApplication { + name: "app" + + files: ["main.cpp"] + + Probe { + id: compilerProbe + property stringList toolchain: qbs.toolchain + property string compilerVersion: cpp.compilerVersion + + configure: { + var isNewerMsvc; + var isOlderMsvc; + var isGcc; + if (toolchain.contains("msvc")) { + if (compilerVersion >= "18.00.30723") + isNewerMsvc = true; + else + isOlderMsvc = true; + } else { + isGcc = true; + } + console.info("is newer MSVC: " + isNewerMsvc); + console.info("is older MSVC: " + isOlderMsvc); + console.info("is GCC: " + isGcc); + } + } +} diff --git a/tests/auto/blackbox/testdata/cxx-language-version/main.cpp b/tests/auto/blackbox/testdata/cxx-language-version/main.cpp new file mode 100644 index 000000000..237c8ce18 --- /dev/null +++ b/tests/auto/blackbox/testdata/cxx-language-version/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 3e6fe72b9..6aa0fed2f 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -1052,6 +1052,83 @@ void TestBlackbox::conflictingArtifacts() QVERIFY2(m_qbsStderr.contains("Conflicting artifacts"), m_qbsStderr.constData()); } +void TestBlackbox::cxxLanguageVersion() +{ + QDir::setCurrent(testDataDir + "/cxx-language-version"); + rmDirR(relativeBuildDir()); + QFETCH(QString, version); + QFETCH(QVariantMap, requiredFlags); + QFETCH(QVariantMap, forbiddenFlags); + QbsRunParameters resolveParams; + resolveParams.command = "resolve"; + resolveParams.arguments << "--force-probe-execution"; + if (!version.isEmpty()) + resolveParams.arguments << ("modules.cpp.cxxLanguageVersion:" + version); + QCOMPARE(runQbs(resolveParams), 0); + QString mapKey; + if (m_qbsStdout.contains("is newer MSVC: true")) + mapKey = "msvc-new"; + else if (m_qbsStdout.contains("is older MSVC: true")) + mapKey = "msvc_old"; + else if (m_qbsStdout.contains("is GCC: true")) + mapKey = "gcc"; + QVERIFY2(!mapKey.isEmpty(), m_qbsStdout.constData()); + QbsRunParameters buildParams; + buildParams.expectFailure = mapKey == "gcc" && (version == "c++17" || version == "c++21"); + buildParams.arguments = QStringList({"--command-echo-mode", "command-line"}); + const int retVal = runQbs(buildParams); + if (!buildParams.expectFailure) + QCOMPARE(retVal, 0); + const QString requiredFlag = requiredFlags.value(mapKey).toString(); + if (!requiredFlag.isEmpty()) + QVERIFY2(m_qbsStdout.contains(requiredFlag.toLocal8Bit()), m_qbsStdout.constData()); + const QString forbiddenFlag = forbiddenFlags.value(mapKey).toString(); + if (!forbiddenFlag.isEmpty()) + QVERIFY2(!m_qbsStdout.contains(forbiddenFlag.toLocal8Bit()), m_qbsStdout.constData()); +} + +void TestBlackbox::cxxLanguageVersion_data() +{ + QTest::addColumn<QString>("version"); + QTest::addColumn<QVariantMap>("requiredFlags"); + QTest::addColumn<QVariantMap>("forbiddenFlags"); + + QTest::newRow("C++98") + << QString("c++98") + << QVariantMap({std::make_pair(QString("gcc"), QString("-std=c++98"))}) + << QVariantMap({std::make_pair(QString("msvc-old"), QString("/std:")), + std::make_pair(QString("msvc-new"), QString("/std:"))}); + QTest::newRow("C++11") + << QString("c++11") + << QVariantMap({std::make_pair(QString("gcc"), QString("-std=c++0x"))}) + << QVariantMap({std::make_pair(QString("msvc-old"), QString("/std:")), + std::make_pair(QString("msvc-new"), QString("/std:"))}); + QTest::newRow("C++14") + << QString("c++14") + << QVariantMap({std::make_pair(QString("gcc"), QString("-std=c++1y")), + std::make_pair(QString("msvc-new"), QString("/std:c++14")) + }) + << QVariantMap({std::make_pair(QString("msvc-old"), QString("/std:"))}); + QTest::newRow("C++17") + << QString("c++17") + << QVariantMap({std::make_pair(QString("gcc"), QString("-std=c++17")), + std::make_pair(QString("msvc-new"), QString("/std:c++latest")) + }) + << QVariantMap({std::make_pair(QString("msvc-old"), QString("/std:"))}); + QTest::newRow("C++21") + << QString("c++21") + << QVariantMap({std::make_pair(QString("gcc"), QString("-std=c++21")), + std::make_pair(QString("msvc-new"), QString("/std:c++latest")) + }) + << QVariantMap({std::make_pair(QString("msvc-old"), QString("/std:"))}); + QTest::newRow("default") + << QString() + << QVariantMap() + << QVariantMap({std::make_pair(QString("gcc"), QString("-std=")), + std::make_pair(QString("msvc-old"), QString("/std:")), + std::make_pair(QString("msvc-new"), QString("/std:"))}); +} + void TestBlackbox::renameDependency() { QDir::setCurrent(testDataDir + "/renameDependency"); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 9b48fa40d..2f620017a 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -62,6 +62,8 @@ private slots: void conditionalExport(); void conditionalFileTagger(); void conflictingArtifacts(); + void cxxLanguageVersion(); + void cxxLanguageVersion_data(); void dependenciesProperty(); void dependencyProfileMismatch(); void deprecatedProperty(); |