aboutsummaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@qt.io>2017-12-07 23:28:55 -0800
committerJake Petroules <jake.petroules@qt.io>2017-12-19 21:25:20 +0000
commit5b9da6dc85c55e3a76611c3ac78c1015119c2ac2 (patch)
tree3c2dc92d2b89b1a39c1ed078d95588ba2efa2b37 /share
parentc356842556073a22e5b555120d6bacf88c6719bd (diff)
Validate the compiler's target platform as well as arch and endianness
This helps to block inappropriate host compilers when cross compiling. Change-Id: Ied22fce094fdb726babea4e94a7ef1d78afc9a98 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'share')
-rw-r--r--share/qbs/imports/qbs/ModUtils/utils.js47
-rw-r--r--share/qbs/imports/qbs/Probes/GccProbe.qbs2
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs2
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs66
4 files changed, 95 insertions, 22 deletions
diff --git a/share/qbs/imports/qbs/ModUtils/utils.js b/share/qbs/imports/qbs/ModUtils/utils.js
index 79bcd9935..28ac2244e 100644
--- a/share/qbs/imports/qbs/ModUtils/utils.js
+++ b/share/qbs/imports/qbs/ModUtils/utils.js
@@ -498,14 +498,14 @@ var BlackboxOutputArtifactTracker = (function () {
return BlackboxOutputArtifactTracker;
})();
-function guessArchitecture(m) {
- function hasAnyOf(m, tokens) {
- for (var i = 0; i < tokens.length; ++i) {
- if (m[tokens[i]] !== undefined)
- return true;
- }
+function hasAnyOf(m, tokens) {
+ for (var i = 0; i < tokens.length; ++i) {
+ if (m[tokens[i]] !== undefined)
+ return true;
}
+}
+function guessArchitecture(m) {
var architecture;
if (m) {
// based on the search algorithm from qprocessordetection.h in qtbase
@@ -571,3 +571,38 @@ function guessArchitecture(m) {
return Utilities.canonicalArchitecture(architecture);
}
+
+function guessTargetPlatform(m) {
+ if (m) {
+ if (hasAnyOf(m, ["__ANDROID__", "ANDROID"]))
+ return "android";
+ if (hasAnyOf(m, ["__QNXNTO__"]))
+ return "qnx";
+ if (hasAnyOf(m, ["__INTEGRITY"]))
+ return "integrity";
+ if (hasAnyOf(m, ["__vxworks"]))
+ return "vxworks";
+ if (hasAnyOf(m, ["__APPLE__"]))
+ return "darwin";
+ if (hasAnyOf(m, ["WIN32", "_WIN32", "__WIN32__", "__NT__"]))
+ return "windows";
+ if (hasAnyOf(m, ["_AIX"]))
+ return "aix";
+ if (hasAnyOf(m, ["hpux", "__hpux"]))
+ return "hpux";
+ if (hasAnyOf(m, ["__sun", "sun"]))
+ return "solaris";
+ if (hasAnyOf(m, ["__linux__", "__linux"]))
+ return "linux";
+ if (hasAnyOf(m, ["__FreeBSD__", "__DragonFly__", "__FreeBSD_kernel__"]))
+ return "freebsd";
+ if (hasAnyOf(m, ["__NetBSD__"]))
+ return "netbsd";
+ if (hasAnyOf(m, ["__OpenBSD__"]))
+ return "openbsd";
+ if (hasAnyOf(m, ["__GNU__"]))
+ return "hurd";
+ if (hasAnyOf(m, ["__HAIKU__"]))
+ return "haiku";
+ }
+}
diff --git a/share/qbs/imports/qbs/Probes/GccProbe.qbs b/share/qbs/imports/qbs/Probes/GccProbe.qbs
index 3b0902bc5..8dceb531a 100644
--- a/share/qbs/imports/qbs/Probes/GccProbe.qbs
+++ b/share/qbs/imports/qbs/Probes/GccProbe.qbs
@@ -48,6 +48,7 @@ PathProbe {
// Outputs
property string architecture
property string endianness
+ property string targetPlatform
property stringList includePaths
property stringList libraryPaths
property stringList frameworkPaths
@@ -95,6 +96,7 @@ PathProbe {
// We have to dump the compiler's macros; -dumpmachine is not suitable because it is not
// always complete (for example, the subarch is not included for arm architectures).
architecture = ModUtils.guessArchitecture(macros);
+ targetPlatform = ModUtils.guessTargetPlatform(macros);
switch (macros["__BYTE_ORDER__"]) {
case "__ORDER_BIG_ENDIAN__":
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index d636e3bb8..17cfb4905 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -348,6 +348,8 @@ Module {
property bool _skipAllChecks: false // Internal, for testing only.
+ property bool validateTargetTriple: true
+
// TODO: The following four rules could use a convenience base item if rule properties
// were available in Artifact items and prepare scripts.
Rule {
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index 824bdd18d..7773e3d5d 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -278,29 +278,62 @@ CppModule {
+ "cpp.compilerName instead.");
}
- var validator = new ModUtils.PropertyValidator("cpp");
- validator.setRequiredProperty("architecture", architecture,
- "you might want to re-run 'qbs-setup-toolchains'");
+ var isWrongTriple = false;
+
if (gccProbe.architecture) {
- validator.addCustomValidator("architecture", architecture, function (value) {
- return Utilities.canonicalArchitecture(architecture) === Utilities.canonicalArchitecture(gccProbe.architecture);
- }, "'" + architecture + "' differs from the architecture produced by this compiler (" +
- gccProbe.architecture +")");
- } else {
+ if (Utilities.canonicalArchitecture(architecture)
+ !== Utilities.canonicalArchitecture(gccProbe.architecture))
+ isWrongTriple = true;
+ } else if (architecture) {
// This is a warning and not an error on the rare chance some new architecture comes
// about which qbs does not know about the macros of. But it *might* still work.
- if (architecture)
- console.warn("Unknown architecture '" + architecture + "' " +
- "may not be supported by this compiler.");
+ console.warn("Unknown architecture '" + architecture + "' " +
+ "may not be supported by this compiler.");
}
if (gccProbe.endianness) {
- validator.addCustomValidator("endianness", endianness, function (value) {
- return endianness === gccProbe.endianness;
- }, "'" + endianness + "' differs from the endianness produced by this compiler (" +
- gccProbe.endianness + ")");
+ if (endianness !== gccProbe.endianness)
+ isWrongTriple = true;
} else if (endianness) {
- console.warn("Could not detect endianness ('" + endianness + "' given)");
+ console.warn("Could not detect endianness ('"
+ + endianness + "' given)");
+ }
+
+ if (gccProbe.targetPlatform) {
+ // Can't differentiate Darwin OSes at the compiler level alone
+ if (gccProbe.targetPlatform === "darwin"
+ ? !qbs.targetOS.contains("darwin")
+ : qbs.targetPlatform !== gccProbe.targetPlatform)
+ isWrongTriple = true;
+ } else if (qbs.targetPlatform) {
+ console.warn("Could not detect target platform ('"
+ + qbs.targetPlatform + "' given)");
+ }
+
+ if (isWrongTriple) {
+ var realTriple = [
+ Utilities.canonicalArchitecture(gccProbe.architecture),
+ gccProbe.targetPlatform,
+ gccProbe.endianness ? gccProbe.endianness + "-endian" : undefined
+ ].join("-");
+ var givenTriple = [
+ Utilities.canonicalArchitecture(architecture),
+ qbs.targetPlatform,
+ endianness ? endianness + "-endian" : undefined
+ ].join("-");
+ var msg = "The selected compiler '" + compilerPath + "' produces code for '" +
+ realTriple + "', but '" + givenTriple + "' was given, which is incompatible.";
+ if (validateTargetTriple) {
+ msg += " If you are absolutely certain that your configuration is correct " +
+ "(check the values of the qbs.architecture, qbs.targetPlatform, " +
+ "and qbs.endianness properties) and that this message has been " +
+ "emitted in error, set the cpp.validateTargetTriple property to " +
+ "false. However, you should consider submitting a bug report in any " +
+ "case.";
+ throw ModUtils.ModuleError(msg);
+ } else {
+ console.warn(msg);
+ }
}
var validateFlagsFunction = function (value) {
@@ -314,6 +347,7 @@ CppModule {
return true;
}
+ var validator = new ModUtils.PropertyValidator("cpp");
var msg = "'-target', '-triple', '-arch' and '-march' cannot appear in flags; set qbs.architecture instead";
validator.addCustomValidator("assemblerFlags", assemblerFlags, validateFlagsFunction, msg);
validator.addCustomValidator("cppFlags", cppFlags, validateFlagsFunction, msg);