aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2017-08-22 17:12:47 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2017-08-23 15:09:56 +0000
commit29ff75ef89d93934bdbc38e24398e766e6597508 (patch)
tree1db4075256f98eeb9536b3750c15ddc0e80eb82a
parent1b046f750bb3bd26d97073c648662c672eb0fc95 (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.md2
-rw-r--r--share/qbs/modules/cpp/msvc.js25
-rw-r--r--tests/auto/blackbox/testdata/cxx-language-version/cxx-language-version.qbs30
-rw-r--r--tests/auto/blackbox/testdata/cxx-language-version/main.cpp1
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp77
-rw-r--r--tests/auto/blackbox/tst_blackbox.h2
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();