diff options
author | Jake Petroules <jake.petroules@qt.io> | 2017-12-07 23:28:55 -0800 |
---|---|---|
committer | Jake Petroules <jake.petroules@qt.io> | 2017-12-19 21:25:20 +0000 |
commit | 5b9da6dc85c55e3a76611c3ac78c1015119c2ac2 (patch) | |
tree | 3c2dc92d2b89b1a39c1ed078d95588ba2efa2b37 /share | |
parent | c356842556073a22e5b555120d6bacf88c6719bd (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.js | 47 | ||||
-rw-r--r-- | share/qbs/imports/qbs/Probes/GccProbe.qbs | 2 | ||||
-rw-r--r-- | share/qbs/modules/cpp/CppModule.qbs | 2 | ||||
-rw-r--r-- | share/qbs/modules/cpp/GenericGCC.qbs | 66 |
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); |