aboutsummaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@qt.io>2018-02-15 15:09:10 -0800
committerJake Petroules <jake.petroules@qt.io>2018-02-21 23:20:57 +0000
commitf4f295b5197d7a38dfba5675ff576929ec8aee48 (patch)
treed40348593af18eb903a41d429191daa05b92c92d /share
parent9379e0eae0f05614313083c8b46b8dae6da8b230 (diff)
Only use fallback values for the -std= command line option when needed
Instead of always using the fallback value, we instead always use the standard value unless we know we're running an older toolchain which does not support it. This alleviates the potential for differing behavior in newer versions of compilers which may attempt to remain compatible with earlier drafts of corresponding standards. [ChangeLog] Always use standard values for -std= when possible Change-Id: I61ff3ecd863caa24cb8fb54500e62dc310a2af02 Reviewed-by: Jake Petroules <jake.petroules@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'share')
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs7
-rw-r--r--share/qbs/modules/cpp/gcc.js107
2 files changed, 97 insertions, 17 deletions
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index b4ef22c8d..377b89ede 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -290,6 +290,13 @@ Module {
description: "The version of the C++ standard with which the code must comply."
}
+ property bool useLanguageVersionFallback
+ PropertyOptions {
+ name: "useLanguageVersionFallback"
+ description: "whether to explicitly use the language standard version fallback values in " +
+ "compiler command line invocations"
+ }
+
property string cxxStandardLibrary
PropertyOptions {
name: "cxxStandardLibrary"
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 07f0a6e94..ab0f5f123 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -629,6 +629,80 @@ function handleCpuFeatures(input, flags) {
}
}
+function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVersion,
+ useLanguageVersionFallback) {
+ // NEVER use the fallback values (safety brake for users in case our version map is ever wrong)
+ if (useLanguageVersionFallback === false)
+ return languageVersion;
+
+ // Deprecated, but compatible with older compiler versions.
+ // Note that these versions are the first to support the *value* to the -std= command line
+ // option, not necessarily the first versions where support for that language standard was
+ // considered fully implemented. Tested manually.
+ var languageVersionsMap = {
+ "c++11": {
+ "fallback": "c++0x",
+ "toolchains": [
+ {"name": "xcode", "version": "4.3"},
+ {"name": "clang", "version": "3.0"},
+ {"name": "gcc", "version": "4.7"}
+ ]
+ },
+ "c11": {
+ "fallback": "c1x",
+ "toolchains": [
+ {"name": "xcode", "version": "5.0"},
+ {"name": "clang", "version": "3.1"},
+ {"name": "gcc", "version": "4.7"}
+ ]
+ },
+ "c++14": {
+ "fallback": "c++1y",
+ "toolchains": [
+ {"name": "xcode", "version": "6.3"},
+ {"name": "clang", "version": "3.5"},
+ {"name": "gcc", "version": "4.9"}
+ ]
+ },
+ "c++17": {
+ "fallback": "c++1z",
+ "toolchains": [
+ {"name": "xcode", "version": "9.3"},
+ {"name": "clang", "version": "5.0"},
+ {"name": "gcc", "version": "5.1"}
+ ]
+ },
+ "c++20": {
+ "fallback": "c++2a",
+ "toolchains": [
+ {"name": "xcode"}, // not yet implemented
+ {"name": "clang"}, // not yet implemented
+ {"name": "gcc"} // not yet implemented
+ ]
+ }
+ };
+
+ var m = languageVersionsMap[languageVersion];
+ if (m) {
+ for (var idx = 0; idx < m.toolchains.length; ++idx) {
+ var tc = m.toolchains[idx];
+ if (toolchain.contains(tc.name)) {
+ // If we found our toolchain and it doesn't yet support the language standard
+ // we're requesting, or we're using an older version that only supports the
+ // preliminary flag, use that.
+ if (useLanguageVersionFallback
+ || !tc.version
+ || Utilities.versionCompare(compilerVersion, tc.version) < 0)
+ return m.fallback;
+ break;
+ }
+ }
+ }
+
+ // If we didn't find our toolchain at all, simply use the standard value.
+ return languageVersion;
+}
+
function compilerFlags(project, product, input, output, explicitlyDependsOn) {
var i;
@@ -788,27 +862,26 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
}
}
- if (tag === "c" || tag === "objc") {
- var cVersion = input.cpp.cLanguageVersion;
- if (cVersion) {
- var gccCVersionsMap = {
- "c11": "c1x" // Deprecated, but compatible with older gcc versions.
- };
- args.push("-std=" + (gccCVersionsMap[cVersion] || cVersion));
+ function currentLanguageVersion(tag) {
+ switch (tag) {
+ case "c":
+ case "objc":
+ return input.cpp.cLanguageVersion;
+ case "cpp":
+ case "objcpp":
+ return input.cpp.cxxLanguageVersion;
}
}
- if (tag === "cpp" || tag === "objcpp") {
- var cxxVersion = input.cpp.cxxLanguageVersion;
- if (cxxVersion) {
- var gccCxxVersionsMap = {
- "c++11": "c++0x", // Deprecated, but compatible with older gcc versions.
- "c++14": "c++1y",
- "c++17": "c++1z",
- };
- args.push("-std=" + (gccCxxVersionsMap[cxxVersion] || cxxVersion));
- }
+ var langVersion = currentLanguageVersion(tag);
+ if (langVersion) {
+ args.push("-std=" + standardFallbackValueOrDefault(product.qbs.toolchain,
+ product.cpp.compilerVersion,
+ langVersion,
+ product.cpp.useLanguageVersionFallback));
+ }
+ if (tag === "cpp" || tag === "objcpp") {
var cxxStandardLibrary = product.cpp.cxxStandardLibrary;
if (cxxStandardLibrary && product.qbs.toolchain.contains("clang")) {
args.push("-stdlib=" + cxxStandardLibrary);