aboutsummaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
Diffstat (limited to 'share')
-rw-r--r--share/qbs/imports/qbs/ModUtils/utils.js2
-rw-r--r--share/qbs/imports/qbs/Probes/IarProbe.qbs33
-rw-r--r--share/qbs/imports/qbs/Probes/KeilProbe.qbs3
-rw-r--r--share/qbs/imports/qbs/Probes/SdccProbe.qbs10
-rw-r--r--share/qbs/imports/qbs/base/AutotestRunner.qbs8
-rw-r--r--share/qbs/module-providers/Qt/templates/core.qbs4
-rw-r--r--share/qbs/modules/autotest/autotest.qbs1
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs6
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs39
-rw-r--r--share/qbs/modules/cpp/MingwBaseModule.qbs115
-rw-r--r--share/qbs/modules/cpp/gcc.js35
-rw-r--r--share/qbs/modules/cpp/iar.js415
-rw-r--r--share/qbs/modules/cpp/iar.qbs116
-rw-r--r--share/qbs/modules/cpp/keil.js373
-rw-r--r--share/qbs/modules/cpp/keil.qbs90
-rw-r--r--share/qbs/modules/cpp/msvc.js43
-rw-r--r--share/qbs/modules/cpp/sdcc.js176
-rw-r--r--share/qbs/modules/cpp/sdcc.qbs31
-rw-r--r--share/qbs/modules/cpp/windows-clang-mingw.qbs98
-rw-r--r--share/qbs/modules/cpp/windows-mingw.qbs88
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs48
21 files changed, 1088 insertions, 646 deletions
diff --git a/share/qbs/imports/qbs/ModUtils/utils.js b/share/qbs/imports/qbs/ModUtils/utils.js
index 84d62a556..5c1fb1ae5 100644
--- a/share/qbs/imports/qbs/ModUtils/utils.js
+++ b/share/qbs/imports/qbs/ModUtils/utils.js
@@ -566,6 +566,8 @@ function guessArchitecture(m) {
architecture = "avr";
} else if (hasAnyOf(m, ["__AVR32__"])) {
architecture = "avr32";
+ } else if (hasAnyOf(m, ["__MSP430__"])) {
+ architecture = "msp430";
}
}
diff --git a/share/qbs/imports/qbs/Probes/IarProbe.qbs b/share/qbs/imports/qbs/Probes/IarProbe.qbs
index 6e7fb7d64..d261e9065 100644
--- a/share/qbs/imports/qbs/Probes/IarProbe.qbs
+++ b/share/qbs/imports/qbs/Probes/IarProbe.qbs
@@ -65,34 +65,25 @@ PathProbe {
compilerFilePath, tag);
}
- // FIXME: Do we need dump the default paths for both C
- // and C++ languages?
- var defaultPaths = IAR.dumpDefaultPaths(
- compilerFilePath, languages[0]);
-
var macros = compilerDefinesByLanguage["c"]
|| compilerDefinesByLanguage["cpp"];
architecture = IAR.guessArchitecture(macros);
endianness = IAR.guessEndianness(macros);
- includePaths = defaultPaths.includePaths;
- var version = parseInt(macros["__VER__"], 10);
+ // FIXME: Do we need dump the default paths for both C
+ // and C++ languages?
+ var defaultPaths = IAR.dumpDefaultPaths(
+ compilerFilePath, languages[0]);
- if (architecture === "arm") {
- versionMajor = parseInt(version / 1000000);
- versionMinor = parseInt(version / 1000) % 1000;
- versionPatch = parseInt(version) % 1000;
- } else if (architecture === "mcs51") {
- versionMajor = parseInt(version / 100);
- versionMinor = parseInt(version % 100);
- versionPatch = 0;
- } else if (architecture === "avr") {
- versionMajor = parseInt(version / 100);
- versionMinor = parseInt(version % 100);
- versionPatch = 0;
- }
+ includePaths = defaultPaths.includePaths;
- found = version && architecture && endianness;
+ var version = IAR.guessVersion(macros, architecture);
+ if (version) {
+ versionMajor = version.major;
+ versionMinor = version.minor;
+ versionPatch = version.patch;
+ found = version && architecture && endianness;
+ }
}
}
diff --git a/share/qbs/imports/qbs/Probes/KeilProbe.qbs b/share/qbs/imports/qbs/Probes/KeilProbe.qbs
index 1955fe480..34afecb64 100644
--- a/share/qbs/imports/qbs/Probes/KeilProbe.qbs
+++ b/share/qbs/imports/qbs/Probes/KeilProbe.qbs
@@ -81,8 +81,7 @@ PathProbe {
versionMajor = version.major;
versionMinor = version.minor;
versionPatch = version.patch;
+ found = version.found && architecture && endianness;
}
-
- found = version.found && architecture && endianness;
}
}
diff --git a/share/qbs/imports/qbs/Probes/SdccProbe.qbs b/share/qbs/imports/qbs/Probes/SdccProbe.qbs
index b5f7d384e..3595bb158 100644
--- a/share/qbs/imports/qbs/Probes/SdccProbe.qbs
+++ b/share/qbs/imports/qbs/Probes/SdccProbe.qbs
@@ -64,10 +64,10 @@ PathProbe {
var defaultPaths = SDCC.dumpDefaultPaths(compilerFilePath, architecture);
includePaths = defaultPaths.includePaths;
- versionMajor = parseInt(macros["__SDCC_VERSION_MAJOR"], 10);
- versionMinor = parseInt(macros["__SDCC_VERSION_MINOR"], 10);
- versionPatch = parseInt(macros["__SDCC_VERSION_PATCH"], 10);
-
- found = macros["SDCC"];
+ var version = SDCC.guessVersion(macros);
+ versionMajor = version.major;
+ versionMinor = version.minor;
+ versionPatch = version.patch;
+ found = version.found;
}
}
diff --git a/share/qbs/imports/qbs/base/AutotestRunner.qbs b/share/qbs/imports/qbs/base/AutotestRunner.qbs
index ab9ba15f7..62ba7740b 100644
--- a/share/qbs/imports/qbs/base/AutotestRunner.qbs
+++ b/share/qbs/imports/qbs/base/AutotestRunner.qbs
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2019 Jochen Ulrich <jochenulrich@t-online.de>
** Contact: http://www.qt.io/licensing
**
** This file is part of Qbs.
@@ -42,6 +43,7 @@ Product {
property stringList wrapper: []
property string workingDir
property stringList auxiliaryInputs
+ property int timeout: -1
Depends {
productTypes: "autotest"
@@ -74,6 +76,7 @@ Product {
: FileInfo.path(commandFilePath);
var arguments = product.arguments;
var allowFailure = false;
+ var timeout = product.timeout;
if (input.autotest) {
// FIXME: We'd like to let the user override with an empty list, but
// qbscore turns undefined lists into empty ones at the moment.
@@ -83,6 +86,9 @@ Product {
if (input.autotest.workingDir)
workingDir = input.autotest.workingDir;
allowFailure = input.autotest.allowFailure;
+
+ if (input.autotest.timeout !== undefined)
+ timeout = input.autotest.timeout;
}
var fullCommandLine = product.wrapper
.concat([commandFilePath])
@@ -91,6 +97,8 @@ Product {
cmd.description = "Running test " + input.fileName;
cmd.environment = product.environment;
cmd.workingDirectory = workingDir;
+ cmd.timeout = timeout;
+ cmd.jobPool = "autotest-runner";
if (allowFailure)
cmd.maxExitCode = 32767;
return cmd;
diff --git a/share/qbs/module-providers/Qt/templates/core.qbs b/share/qbs/module-providers/Qt/templates/core.qbs
index 98bc0c4d3..8e990db22 100644
--- a/share/qbs/module-providers/Qt/templates/core.qbs
+++ b/share/qbs/module-providers/Qt/templates/core.qbs
@@ -105,6 +105,10 @@ Module {
condition: moduleConfig.contains("use_gold_linker")
cpp.linkerVariant: "gold"
}
+ Properties {
+ condition: !moduleConfig.contains("use_gold_linker") && qbs.toolchain.contains("gcc")
+ cpp.linkerVariant: original
+ }
cpp.cxxLanguageVersion: Utilities.versionCompare(version, "5.7.0") >= 0 ? "c++11" : original
cpp.enableCompilerDefinesByLanguage: ["cpp"].concat(
diff --git a/share/qbs/modules/autotest/autotest.qbs b/share/qbs/modules/autotest/autotest.qbs
index ba280169e..c8a1c5180 100644
--- a/share/qbs/modules/autotest/autotest.qbs
+++ b/share/qbs/modules/autotest/autotest.qbs
@@ -2,4 +2,5 @@ Module {
property stringList arguments
property bool allowFailure: false
property string workingDir
+ property int timeout
}
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index 200d91d09..50ce59b95 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -251,6 +251,12 @@ Module {
description: "additional compiler driver flags used for linking only"
}
+ property bool generateLinkerMapFile: false
+ PropertyOptions {
+ name: "generateLinkerMapFile"
+ description: "generate linker map file"
+ }
+
property bool positionIndependentCode: true
PropertyOptions {
name: "positionIndependentCode"
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index f9537884e..5ededc512 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -135,14 +135,14 @@ CppModule {
: undefined
property string binutilsPath: binutilsProbe.found ? binutilsProbe.path : toolchainInstallPath
- assemblerName: 'as'
+ assemblerName: 'as' + compilerExtension
compilerName: cxxCompilerName
- linkerName: 'ld'
- property string archiverName: 'ar'
- property string nmName: 'nm'
- property string objcopyName: "objcopy"
- property string stripName: "strip"
- property string dsymutilName: "dsymutil"
+ linkerName: 'ld' + compilerExtension
+ property string archiverName: 'ar' + compilerExtension
+ property string nmName: 'nm' + compilerExtension
+ property string objcopyName: "objcopy" + compilerExtension
+ property string stripName: "strip" + compilerExtension
+ property string dsymutilName: "dsymutil" + compilerExtension
property string lipoName
property string sysroot: qbs.sysroot
property string syslibroot: sysroot
@@ -227,18 +227,12 @@ CppModule {
if (product.version === undefined)
return undefined;
- if (!Gcc.isNumericProductVersion(product.version)) {
- // Dynamic library version numbers like "A" or "B" are common on Apple platforms, so
- // don't restrict the product version to a componentized version number here.
- if (cpp.imageFormat === "macho")
- return product.version;
-
- throw("product.version must be a string in the format x[.y[.z[.w]] "
- + "where each component is an integer");
- }
+ var coreVersion = product.version.match("^([0-9]+\.){0,3}[0-9]+");
+ if (!coreVersion)
+ return undefined;
var maxVersionParts = 3;
- var versionParts = product.version.split('.').slice(0, maxVersionParts);
+ var versionParts = coreVersion[0].split('.').slice(0, maxVersionParts);
// pad if necessary
for (var i = versionParts.length; i < maxVersionParts; ++i)
@@ -246,11 +240,12 @@ CppModule {
return versionParts.join('.');
}
+
property string soVersion: {
- var v = internalVersion;
- if (!Gcc.isNumericProductVersion(v))
+ if (!internalVersion)
return "";
- return v.split('.')[0];
+
+ return internalVersion.split('.')[0];
}
property var buildEnv: {
@@ -429,7 +424,7 @@ CppModule {
+ PathTools.bundleExecutableFilePath(product)
}
}];
- if (product.qbs.toolchain.contains("mingw")) {
+ if (product.cpp.imageFormat === "pe") {
artifacts.push({
fileTags: ["dynamiclibrary_import"],
filePath: FileInfo.joinPaths(product.destinationDirectory,
@@ -447,7 +442,7 @@ CppModule {
}
if (product.cpp.shouldCreateSymlinks && (!product.bundle || !product.bundle.isBundle)) {
- var maxVersionParts = Gcc.isNumericProductVersion(product.version) ? 3 : 1;
+ var maxVersionParts = product.cpp.internalVersion ? 3 : 1;
for (var i = 0; i < maxVersionParts; ++i) {
var symlink = {
filePath: product.destinationDirectory + "/"
diff --git a/share/qbs/modules/cpp/MingwBaseModule.qbs b/share/qbs/modules/cpp/MingwBaseModule.qbs
new file mode 100644
index 000000000..60ad28b08
--- /dev/null
+++ b/share/qbs/modules/cpp/MingwBaseModule.qbs
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.TextFile
+import qbs.Utilities
+import qbs.WindowsUtils
+
+import "setuprunenv.js" as SetupRunEnv
+
+GenericGCC {
+ condition: false
+
+ staticLibraryPrefix: "lib"
+ staticLibrarySuffix: ".a"
+ dynamicLibrarySuffix: ".dll"
+ executableSuffix: ".exe"
+ debugInfoSuffix: ".debug"
+ imageFormat: "pe"
+ windowsApiCharacterSet: "unicode"
+ platformDefines: base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
+ .concat("WIN32")
+
+ Properties {
+ condition: product.multiplexByQbsProperties.contains("buildVariants")
+ && qbs.buildVariants && qbs.buildVariants.length > 1
+ && qbs.buildVariant !== "release"
+ && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
+ variantSuffix: "d"
+ }
+
+ FileTagger {
+ patterns: ["*.manifest"]
+ fileTags: ["native.pe.manifest"]
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ inputs: ["native.pe.manifest"]
+ multiplex: true
+
+ outputFileTags: ["rc"]
+ outputArtifacts: {
+ if (product.type.containsAny(["application", "dynamiclibrary"])) {
+ return [{
+ filePath: input.completeBaseName + ".rc",
+ fileTags: ["rc"]
+ }];
+ }
+ return [];
+ }
+
+ prepare: {
+ var inputList = inputs["native.pe.manifest"];
+ // TODO: Emulate manifest merging like Microsoft's mt.exe tool does
+ if (inputList.length !== 1) {
+ throw("The MinGW toolchain does not support manifest merging; " +
+ "you may only specify a single manifest file to embed into your assembly.");
+ }
+
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.productType = product.type;
+ cmd.inputFilePath = inputList[0].filePath;
+ cmd.outputFilePath = output.filePath;
+ cmd.sourceCode = function() {
+ var tf;
+ try {
+ tf = new TextFile(outputFilePath, TextFile.WriteOnly);
+ if (productType.contains("application"))
+ tf.write("1 "); // CREATEPROCESS_MANIFEST_RESOURCE_ID
+ else if (productType.contains("dynamiclibrary"))
+ tf.write("2 "); // ISOLATIONAWARE_MANIFEST_RESOURCE_ID
+ tf.write("24 "); // RT_MANIFEST
+ tf.writeLine(Utilities.cStringQuote(inputFilePath));
+ } finally {
+ if (tf)
+ tf.close();
+ }
+ };
+ return [cmd];
+ }
+ }
+}
+
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 6936beb5e..0913b27d0 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -78,7 +78,7 @@ function collectLibraryDependencies(product, isDarwin) {
var publicDeps = {};
var objects = [];
var objectByFilePath = {};
- var tagForLinkingAgainstSharedLib = product.qbs.toolchain.contains("mingw")
+ var tagForLinkingAgainstSharedLib = product.cpp.imageFormat === "pe"
? "dynamiclibrary_import" : "dynamiclibrary";
function addObject(obj, addFunc) {
@@ -278,12 +278,11 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
}
if (isDarwin) {
- var internalVersion = product.cpp.internalVersion;
- if (internalVersion && isNumericProductVersion(internalVersion))
- args.push("-current_version", internalVersion);
+ if (product.cpp.internalVersion)
+ args.push("-current_version", product.cpp.internalVersion);
escapableLinkerFlags.push("-install_name", UnixUtils.soname(product,
primaryOutput.fileName));
- } else {
+ } else if (product.cpp.imageFormat === "elf") {
escapableLinkerFlags.push("-soname=" + UnixUtils.soname(product,
primaryOutput.fileName));
}
@@ -295,7 +294,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
if (primaryOutput.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) {
if (isDarwin)
escapableLinkerFlags.push("-headerpad_max_install_names");
- else
+ else if (product.cpp.imageFormat === "elf")
escapableLinkerFlags.push("--as-needed");
}
@@ -344,13 +343,15 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
return rpath;
}
- function isNotSystemRunPath(p) {
- return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
- && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
- };
- for (i in rpaths) {
- if (isNotSystemRunPath(rpaths[i]))
- escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i]));
+ if (!product.qbs.targetOS.contains("windows")) {
+ function isNotSystemRunPath(p) {
+ return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
+ && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
+ };
+ for (i in rpaths) {
+ if (isNotSystemRunPath(rpaths[i]))
+ escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i]));
+ }
}
if (product.cpp.entryPoint)
@@ -854,7 +855,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
}
var positionIndependentCode = input.cpp.positionIndependentCode;
- if (positionIndependentCode && !product.qbs.toolchain.contains("mingw"))
+ if (positionIndependentCode && !product.qbs.targetOS.contains("windows"))
args.push('-fPIC');
var cppFlags = input.cpp.cppFlags;
@@ -1035,7 +1036,7 @@ function linkerEnvVars(config, inputs)
function setResponseFileThreshold(command, product)
{
- if (product.qbs.toolchain.contains("mingw") && product.qbs.hostOS.contains("windows"))
+ if (product.qbs.targetOS.contains("windows") && product.qbs.hostOS.contains("windows"))
command.responseFileThreshold = 10000;
}
@@ -1432,10 +1433,6 @@ function debugInfoArtifacts(product, variants, debugInfoTagSuffix) {
return artifacts;
}
-function isNumericProductVersion(version) {
- return version && version.match(/^([0-9]+\.){0,3}[0-9]+$/);
-}
-
function dumpMacros(env, compilerFilePath, args, nullDevice, tag) {
var p = new Process();
try {
diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js
index 33093c0a3..b787901b2 100644
--- a/share/qbs/modules/cpp/iar.js
+++ b/share/qbs/modules/cpp/iar.js
@@ -36,33 +36,182 @@ var ModUtils = require("qbs.ModUtils");
var Process = require("qbs.Process");
var TemporaryDir = require("qbs.TemporaryDir");
var TextFile = require("qbs.TextFile");
-var Utilities = require("qbs.Utilities");
-var WindowsUtils = require("qbs.WindowsUtils");
-function guessArchitecture(macros)
-{
+function compilerName(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ return "iccarm";
+ case "mcs51":
+ return "icc8051";
+ case "avr":
+ return "iccavr";
+ case "stm8":
+ return "iccstm8";
+ case "msp430":
+ return "icc430";
+ }
+ throw "Unable to deduce compiler name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function assemblerName(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ return "iasmarm";
+ case "mcs51":
+ return "a8051";
+ case "avr":
+ return "aavr";
+ case "stm8":
+ return "iasmstm8";
+ case "msp430":
+ return "a430";
+ }
+ throw "Unable to deduce assembler name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function linkerName(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ return "ilinkarm";
+ case "stm8":
+ return "ilinkstm8";
+ case "mcs51":
+ case "avr":
+ case "msp430":
+ return "xlink";
+ }
+ throw "Unable to deduce linker name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function archiverName(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ case "stm8":
+ return "iarchive";
+ case "mcs51":
+ case "avr":
+ case "msp430":
+ return "xlib";
+ }
+ throw "Unable to deduce archiver name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function staticLibrarySuffix(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ case "stm8":
+ return ".a";
+ case "mcs51":
+ return ".r51";
+ case "avr":
+ return ".r90";
+ case "msp430":
+ return ".r43";
+ }
+ throw "Unable to deduce static library suffix for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function executableSuffix(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ case "stm8":
+ return ".out";
+ case "mcs51":
+ return qbs.debugInformation ? ".d51" : ".a51";
+ case "avr":
+ return qbs.debugInformation ? ".d90" : ".a90";
+ case "msp430":
+ return qbs.debugInformation ? ".d43" : ".a43";
+ }
+ throw "Unable to deduce executable suffix for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function objectSuffix(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ case "stm8":
+ return ".o";
+ case "mcs51":
+ return ".r51";
+ case "avr":
+ return ".r90";
+ case "msp430":
+ return ".r43";
+ }
+ throw "Unable to deduce object file suffix for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function imageFormat(qbs) {
+ switch (qbs.architecture) {
+ case "arm":
+ case "stm8":
+ return "elf";
+ case "mcs51":
+ case "avr":
+ case "msp430":
+ return "ubrof";
+ }
+ throw "Unable to deduce image format for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function guessArchitecture(macros) {
if (macros["__ICCARM__"] === "1")
return "arm";
else if (macros["__ICC8051__"] === "1")
return "mcs51";
else if (macros["__ICCAVR__"] === "1")
return "avr";
+ else if (macros["__ICCSTM8__"] === "1")
+ return "stm8";
+ else if (macros["__ICC430__"] === "1")
+ return "msp430";
}
-function guessEndianness(macros)
-{
+function guessEndianness(macros) {
if (macros["__LITTLE_ENDIAN__"] === "1")
return "little";
return "big"
}
-function cppLanguageOption(compilerFilePath)
+function guessVersion(macros, architecture)
{
+ var version = parseInt(macros["__VER__"], 10);
+ switch (architecture) {
+ case "arm":
+ return { major: parseInt(version / 1000000),
+ minor: parseInt(version / 1000) % 1000,
+ patch: parseInt(version) % 1000,
+ found: true }
+ case "mcs51":
+ case "avr":
+ case "stm8":
+ case "msp430":
+ return { major: parseInt(version / 100),
+ minor: parseInt(version % 100),
+ patch: 0,
+ found: true }
+ }
+}
+
+function cppLanguageOption(compilerFilePath) {
var baseName = FileInfo.baseName(compilerFilePath);
- if (baseName === "iccarm")
+ switch (baseName) {
+ case "iccarm":
return "--c++";
- if (baseName === "icc8051" || baseName === "iccavr")
+ case "icc8051":
+ case "iccavr":
+ case "iccstm8":
+ case "icc430":
return "--ec++";
+ }
throw "Unable to deduce C++ language option for unsupported compiler: '"
+ FileInfo.toNativeSeparators(compilerFilePath) + "'";
}
@@ -191,12 +340,48 @@ function collectLibraryDependencies(product) {
}
function compilerFlags(project, product, input, output, explicitlyDependsOn) {
- // Determine which C-language we"re compiling.
+ // Determine which C-language we're compiling.
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
var args = [];
+
+ // Input.
args.push(input.filePath);
+ // Output.
+ args.push("-o", output.filePath);
+
+ // Defines.
+ var allDefines = [];
+ var platformDefines = input.cpp.platformDefines;
+ if (platformDefines)
+ allDefines = allDefines.uniqueConcat(platformDefines);
+ var defines = input.cpp.defines;
+ if (defines)
+ allDefines = allDefines.uniqueConcat(defines);
+ args = args.concat(allDefines.map(function(define) { return "-D" + define }));
+
+ // Includes.
+ var allIncludePaths = [];
+ var includePaths = input.cpp.includePaths;
+ if (includePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
+ var systemIncludePaths = input.cpp.systemIncludePaths;
+ if (systemIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
+ var compilerIncludePaths = input.cpp.compilerIncludePaths;
+ if (compilerIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
+ args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
+
+ // Silent output generation flag.
+ args.push("--silent");
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("--debug");
+
+ // Optimization flags.
switch (input.cpp.optimization) {
case "small":
args.push("-Ohs");
@@ -209,73 +394,68 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
break;
}
- if (input.cpp.debugInformation)
- args.push("--debug");
-
- var warnings = input.cpp.warningLevel;
- if (warnings === "none") {
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
args.push("--no_warnings");
- } else if (warnings === "all") {
+ break;
+ case "all":
args.push("--deprecated_feature_warnings="
+"+attribute_syntax,"
+"+preprocessor_extensions,"
+"+segment_pragmas");
if (tag === "cpp")
args.push("--warn_about_c_style_casts");
+ break;
}
if (input.cpp.treatWarningsAsErrors)
args.push("--warnings_are_errors");
- // Choose byte order.
- var endianness = input.cpp.endianness;
- if (endianness) {
- if (input.qbs.architecture === "arm")
- args.push("--endian=" + endianness);
- }
-
+ // C language version flags.
if (tag === "c") {
- // Language version.
- if (input.cpp.cLanguageVersion === "c89")
+ var knownValues = ["c89"];
+ var cLanguageVersion = Cpp.languageVersion(
+ input.cpp.cLanguageVersion, knownValues, "C");
+ switch (cLanguageVersion) {
+ case "c89":
args.push("--c89");
- } else if (tag === "cpp") {
- if (input.qbs.architecture === "arm") {
+ break;
+ default:
+ // Default C language version is C11/C99 that
+ // depends on the IAR version.
+ break;
+ }
+ }
+
+ // Architecture specific flags.
+ switch (input.qbs.architecture) {
+ case "arm":
+ // Byte order flags.
+ var endianness = input.cpp.endianness;
+ if (endianness)
+ args.push("--endian=" + endianness);
+ if (tag === "cpp") {
+ // Enable C++ language flags.
args.push("--c++");
+ // Exceptions flags.
if (!input.cpp.enableExceptions)
args.push("--no_exceptions");
+ // RTTI flags.
if (!input.cpp.enableRtti)
args.push("--no_rtti");
- } else if (input.qbs.architecture === "mcs51") {
- args.push("--ec++");
- } else if (input.qbs.architecture === "avr") {
- args.push("--ec++");
}
+ break;
+ case "stm8":
+ case "mcs51":
+ case "avr":
+ case "msp430":
+ // Enable C++ language flags.
+ if (tag === "cpp")
+ args.push("--ec++");
+ break;
}
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
- args = args.concat(allDefines.map(function(define) { return "-D" + define }));
-
- var allIncludePaths = [];
- var includePaths = input.cpp.includePaths;
- if (includePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- var compilerIncludePaths = input.cpp.compilerIncludePaths;
- if (compilerIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
- args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
-
- args.push("-o", output.filePath);
-
- args.push("--silent"); // Silent operation.
-
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
ModUtils.moduleProperty(input, "flags"),
ModUtils.moduleProperty(input, "platformFlags", tag),
@@ -289,17 +469,14 @@ function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
var args = [];
- args.push(input.filePath);
- if (input.cpp.debugInformation)
- args.push("-r");
+ // Input.
+ args.push(input.filePath);
- var warnings = input.cpp.warningLevel;
- if (warnings === "none")
- args.push("-w-");
- else
- args.push("-w+");
+ // Output.
+ args.push("-o", output.filePath);
+ // Includes.
var allIncludePaths = [];
var systemIncludePaths = input.cpp.systemIncludePaths;
if (systemIncludePaths)
@@ -309,10 +486,29 @@ function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
- args.push("-o", output.filePath);
+ // Silent output generation flag.
+ args.push(input.qbs.architecture === "stm8" ? "--silent" : "-S");
- args.push("-S"); // Silent operation.
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("-r");
+
+ // Architecture specific flags.
+ switch (input.qbs.architecture) {
+ case "stm8":
+ // Warning level flags.
+ if (input.cpp.warningLevel === "none")
+ args.push("--no_warnings");
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("--warnings_are_errors");
+ break;
+ default:
+ // Warning level flags.
+ args.push("-w" + (input.cpp.warningLevel === "none" ? "-" : "+"));
+ break;
+ }
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
ModUtils.moduleProperty(input, "flags", tag),
ModUtils.moduleProperty(input, "driverFlags", tag));
@@ -320,23 +516,16 @@ function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
}
function linkerFlags(project, product, input, outputs) {
- var i;
var args = [];
+ // Inputs.
if (inputs.obj)
args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ // Output.
args.push("-o", outputs.application[0].filePath);
- if (product.cpp.generateMapFile) {
- if (product.qbs.architecture === "arm")
- args.push("--map", outputs.map_file[0].filePath);
- else if (product.qbs.architecture === "mcs51")
- args.push("-l", outputs.map_file[0].filePath);
- else if (product.qbs.architecture === "avr")
- args.push("-l", outputs.map_file[0].filePath);
- }
-
+ // Library paths.
var allLibraryPaths = [];
var libraryPaths = product.cpp.libraryPaths;
if (libraryPaths)
@@ -346,44 +535,50 @@ function linkerFlags(project, product, input, outputs) {
allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
args = args.concat(allLibraryPaths.map(function(path) { return '-L' + path }));
+ // Library dependencies.
var libraryDependencies = collectLibraryDependencies(product);
if (libraryDependencies)
args = args.concat(libraryDependencies.map(function(dep) { return dep.filePath }));
- if (product.cpp.debugInformation) {
- if (product.qbs.architecture === "mcs51")
- args.push("-rt");
- else if (product.qbs.architecture === "avr")
- args.push("-rt");
- }
-
+ // Linker scripts.
var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
- for (i in linkerScripts) {
- if (product.qbs.architecture === "arm")
- args.push("--config", linkerScripts[i]);
- else if (product.qbs.architecture === "mcs51")
- args.push("-f", linkerScripts[i]);
- else if (product.qbs.architecture === "avr")
- args.push("-f", linkerScripts[i]);
- }
-
- if (product.cpp.entryPoint) {
- if (product.qbs.architecture === "arm")
+ ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
+
+ // Architecture specific flags.
+ switch (product.qbs.architecture) {
+ case "arm":
+ case "stm8":
+ // Silent output generation flag.
+ args.push("--silent");
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
+ args.push("--map", outputs.map_file[0].filePath);
+ // Entry point flag.
+ if (product.cpp.entryPoint)
args.push("--entry", product.cpp.entryPoint);
- else if (product.qbs.architecture === "mcs51")
- args.push("-s", product.cpp.entryPoint);
- else if (product.qbs.architecture === "avr")
+ // Linker scripts flags.
+ linkerScripts.forEach(function(script) { args.push("--config", script); });
+ break;
+ case "mcs51":
+ case "avr":
+ case "msp430":
+ // Silent output generation flag.
+ args.push("-S");
+ // Debug information flag.
+ if (product.cpp.debugInformation)
+ args.push("-rt");
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
+ args.push("-l", outputs.map_file[0].filePath);
+ // Entry point flag.
+ if (product.cpp.entryPoint)
args.push("-s", product.cpp.entryPoint);
+ // Linker scripts flags.
+ linkerScripts.forEach(function(script) { args.push("-f", script); });
+ break;
}
- if (product.qbs.architecture === "arm")
- args.push("--silent"); // Silent operation.
- else if (product.qbs.architecture === "mcs51")
- args.push("-S"); // Silent operation.
- else if (product.qbs.architecture === "avr")
- args.push("-S"); // Silent operation.
-
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
return args;
}
@@ -391,9 +586,11 @@ function linkerFlags(project, product, input, outputs) {
function archiverFlags(project, product, input, outputs) {
var args = [];
+ // Inputs.
if (inputs.obj)
args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ // Output.
args.push("--create");
args.push("-o", outputs.staticlibrary[0].filePath);
@@ -403,7 +600,7 @@ function archiverFlags(project, product, input, outputs) {
function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var args = compilerFlags(project, product, input, output, explicitlyDependsOn);
var compilerPath = input.cpp.compilerPath;
- var cmd = new Command(compilerPath, args)
+ var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
return [cmd];
@@ -412,7 +609,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var args = assemblerFlags(project, product, input, output, explicitlyDependsOn);
var assemblerPath = input.cpp.assemblerPath;
- var cmd = new Command(assemblerPath, args)
+ var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
return [cmd];
@@ -422,7 +619,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var primaryOutput = outputs.application[0];
var args = linkerFlags(project, product, input, outputs);
var linkerPath = product.cpp.linkerPath;
- var cmd = new Command(linkerPath, args)
+ var cmd = new Command(linkerPath, args);
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
return [cmd];
@@ -431,7 +628,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
function prepareArchiver(project, product, inputs, outputs, input, output) {
var args = archiverFlags(project, product, input, outputs);
var archiverPath = product.cpp.archiverPath;
- var cmd = new Command(archiverPath, args)
+ var cmd = new Command(archiverPath, args);
cmd.description = "linking " + output.fileName;
cmd.highlight = "linker";
cmd.stdoutFilterFunction = function(output) {
diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs
index 6d15781a5..fef84fe1b 100644
--- a/share/qbs/modules/cpp/iar.qbs
+++ b/share/qbs/modules/cpp/iar.qbs
@@ -68,109 +68,30 @@ CppModule {
property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
- property bool generateMapFile: true
- PropertyOptions {
- name: "generateMapFile"
- description: "produce a linker list file (enabled by default)"
- }
-
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
- compilerName: {
- switch (qbs.architecture) {
- case "arm":
- return "iccarm" + compilerExtension;
- case "mcs51":
- return "icc8051" + compilerExtension;
- case "avr":
- return "iccavr" + compilerExtension;
- }
- }
+ compilerName: IAR.compilerName(qbs) + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: {
- switch (qbs.architecture) {
- case "arm":
- return "iasmarm" + compilerExtension;
- case "mcs51":
- return "a8051" + compilerExtension;
- case "avr":
- return "aavr" + compilerExtension;
- }
- }
+ assemblerName: IAR.assemblerName(qbs) + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: {
- switch (qbs.architecture) {
- case "arm":
- return "ilinkarm" + compilerExtension;
- case "mcs51":
- return "xlink" + compilerExtension;
- case "avr":
- return "xlink" + compilerExtension;
- }
- }
+ linkerName: IAR.linkerName(qbs) + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: {
- switch (qbs.architecture) {
- case "arm":
- return "iarchive" + compilerExtension;
- case "mcs51":
- return "xlib" + compilerExtension;
- case "avr":
- return "xlib" + compilerExtension;
- }
- }
+ property string archiverName: IAR.archiverName(qbs) + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
runtimeLibrary: "static"
- staticLibrarySuffix: {
- switch (qbs.architecture) {
- case "arm":
- return ".a";
- case "mcs51":
- return ".r51";
- case "avr":
- return ".r90";
- }
- }
+ staticLibrarySuffix: IAR.staticLibrarySuffix(qbs)
+ executableSuffix: IAR.executableSuffix(qbs)
- executableSuffix: {
- switch (qbs.architecture) {
- case "arm":
- return ".out";
- case "mcs51":
- return qbs.debugInformation ? ".d51" : ".a51";
- case "avr":
- return qbs.debugInformation ? ".d90" : ".a90";
- }
- }
+ property string objectSuffix: IAR.objectSuffix(qbs)
- property string objectSuffix: {
- switch (qbs.architecture) {
- case "arm":
- return ".o";
- case "mcs51":
- return ".r51";
- case "avr":
- return ".r90";
- }
- }
-
- imageFormat: {
- switch (qbs.architecture) {
- case "arm":
- return "elf";
- case "mcs51":
- return "ubrof";
- case "avr":
- return "ubrof";
- }
- }
+ imageFormat: IAR.imageFormat(qbs)
enableExceptions: false
enableRtti: false
@@ -185,18 +106,11 @@ CppModule {
+ input.fileName + input.cpp.objectSuffix
}
- prepare: IAR.prepareAssembler.apply(IAR, arguments);
- }
-
- FileTagger {
- condition: qbs.architecture === "arm";
- patterns: "*.s"
- fileTags: ["asm"]
+ prepare: IAR.prepareAssembler.apply(IAR, arguments)
}
FileTagger {
- condition: qbs.architecture === "mcs51";
- patterns: ["*.s51", "*.asm"]
+ patterns: ["*.s", "*.s43", "*.s51", "*.s90", "*.msa", "*.asm"]
fileTags: ["asm"]
}
@@ -211,7 +125,7 @@ CppModule {
+ input.fileName + input.cpp.objectSuffix
}
- prepare: IAR.prepareCompiler.apply(IAR, arguments);
+ prepare: IAR.prepareCompiler.apply(IAR, arguments)
}
Rule {
@@ -222,7 +136,7 @@ CppModule {
outputFileTags: {
var tags = ["application"];
- if (product.moduleProperty("cpp", "generateMapFile"))
+ if (product.moduleProperty("cpp", "generateLinkerMapFile"))
tags.push("map_file");
return tags;
}
@@ -234,7 +148,7 @@ CppModule {
PathTools.applicationFilePath(product))
};
var artifacts = [app];
- if (product.cpp.generateMapFile) {
+ if (product.cpp.generateLinkerMapFile) {
artifacts.push({
fileTags: ["map_file"],
filePath: FileInfo.joinPaths(
@@ -245,7 +159,7 @@ CppModule {
return artifacts;
}
- prepare:IAR.prepareLinker.apply(IAR, arguments);
+ prepare: IAR.prepareLinker.apply(IAR, arguments)
}
Rule {
@@ -261,6 +175,6 @@ CppModule {
PathTools.staticLibraryFilePath(product))
}
- prepare: IAR.prepareArchiver.apply(IAR, arguments);
+ prepare: IAR.prepareArchiver.apply(IAR, arguments)
}
}
diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js
index 82c4400c0..ceee3f0d2 100644
--- a/share/qbs/modules/cpp/keil.js
+++ b/share/qbs/modules/cpp/keil.js
@@ -37,19 +37,104 @@ var PathTools = require("qbs.PathTools");
var Process = require("qbs.Process");
var TemporaryDir = require("qbs.TemporaryDir");
var TextFile = require("qbs.TextFile");
-var Utilities = require("qbs.Utilities");
-var WindowsUtils = require("qbs.WindowsUtils");
-function guessArchitecture(macros)
-{
+function compilerName(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "c51";
+ case "arm":
+ return "armcc";
+ }
+ throw "Unable to deduce compiler name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function assemblerName(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "a51";
+ case "arm":
+ return "armasm";
+ }
+ throw "Unable to deduce assembler name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function linkerName(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "bl51";
+ case "arm":
+ return "armlink";
+ }
+ throw "Unable to deduce linker name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function archiverName(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "lib51";
+ case "arm":
+ return "armar";
+ }
+ throw "Unable to deduce archiver name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function staticLibrarySuffix(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ case "arm":
+ return ".lib";
+ }
+ throw "Unable to deduce static library suffix for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function executableSuffix(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return ".abs";
+ case "arm":
+ return ".axf";
+ }
+ throw "Unable to deduce executable suffix for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function objectSuffix(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return ".obj";
+ case "arm":
+ return ".o";
+ }
+ throw "Unable to deduce object file suffix for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function imageFormat(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ // Keil OMF51 or OMF2 Object Module Format (which is an
+ // extension of the original Intel OMF51).
+ return "omf";
+ case "arm":
+ return "elf";
+ }
+ throw "Unable to deduce image format for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function guessArchitecture(macros) {
if (macros["__C51__"])
return "mcs51";
else if (macros["__CC_ARM"] === 1)
return "arm";
}
-function guessEndianness(macros)
-{
+function guessEndianness(macros) {
if (macros["__C51__"]) {
// The 8051 processors are 8-bit. So, the data with an integer type
// represented by more than one byte is stored as big endian in the
@@ -62,19 +147,18 @@ function guessEndianness(macros)
}
}
-function guessVersion(macros)
-{
+function guessVersion(macros) {
if (macros["__C51__"]) {
- var version = macros["__C51__"];
- return { major: parseInt(version / 100),
- minor: parseInt(version % 100),
+ var mcsVersion = macros["__C51__"];
+ return { major: parseInt(mcsVersion / 100),
+ minor: parseInt(mcsVersion % 100),
patch: 0,
found: true }
} else if (macros["__CC_ARM"]) {
- var version = macros["__ARMCC_VERSION"];
- return { major: parseInt(version / 1000000),
- minor: parseInt(version / 10000) % 100,
- patch: parseInt(version) % 10000,
+ var armVersion = macros["__ARMCC_VERSION"];
+ return { major: parseInt(armVersion / 1000000),
+ minor: parseInt(armVersion / 10000) % 100,
+ patch: parseInt(armVersion) % 10000,
found: true }
}
}
@@ -133,26 +217,18 @@ function dumpMacros(compilerFilePath, tag, nullDevice) {
var map1 = dumpC51CompilerMacros(compilerFilePath, tag, nullDevice);
var map2 = dumpArmCompilerMacros(compilerFilePath, tag, nullDevice);
var map = {};
- for (var attrname in map1)
- map[attrname] = map1[attrname];
- for (var attrname in map2)
- map[attrname] = map2[attrname];
+ for (var key1 in map1)
+ map[key1] = map1[key1];
+ for (var key2 in map2)
+ map[key2] = map2[key2];
return map;
}
function dumpDefaultPaths(compilerFilePath, architecture) {
- var includePaths = [];
-
- if (architecture === "mcs51") {
- var path = compilerFilePath.replace(/bin[\\\/](.*)$/i, "inc");
- includePaths.push(path);
- } else if (architecture === "arm") {
- var path = compilerFilePath.replace(/bin[\\\/](.*)$/i, "include");
- includePaths.push(path);
- }
-
+ var incDir = (architecture === "arm") ? "include" : "inc";
+ var includePath = compilerFilePath.replace(/bin[\\\/](.*)$/i, incDir);
return {
- "includePaths": includePaths
+ "includePaths": [includePath]
};
}
@@ -270,7 +346,16 @@ function applicationLinkerOutputArtifacts(product) {
product.targetName
+ (product.cpp.architecture === "mcs51" ? ".m51" : ".map"))
};
- return [app, mem_map]
+ var artifacts = [app, mem_map];
+ if (product.cpp.generateLinkerMapFile) {
+ artifacts.push({
+ fileTags: ["map_file"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ product.targetName + ".map")
+ });
+ }
+ return artifacts;
}
function staticLibraryLinkerOutputArtifacts(product) {
@@ -284,9 +369,8 @@ function staticLibraryLinkerOutputArtifacts(product) {
}
function compilerFlags(project, product, input, output, explicitlyDependsOn) {
- // Determine which C-language we"re compiling.
+ // Determine which C-language we're compiling.
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
- var architecture = input.qbs.architecture;
var args = [];
var allDefines = [];
@@ -308,10 +392,29 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
if (compilerIncludePaths)
allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
+ var architecture = input.qbs.architecture;
if (architecture === "mcs51") {
+ // Input.
args.push(FileInfo.toWindowsSeparators(input.filePath));
+
+ // Output.
args.push("OBJECT (" + FileInfo.toWindowsSeparators(output.filePath) + ")");
+ // Defines.
+ if (allDefines.length > 0)
+ args = args.concat("DEFINE (" + allDefines.join(",") + ")");
+
+ // Includes.
+ if (allIncludePaths.length > 0) {
+ var adjusted = adjustPathsToWindowsSeparators(allIncludePaths);
+ args = args.concat("INCDIR (" + adjusted.join(";") + ")");
+ }
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("DEBUG");
+
+ // Optimization level flags.
switch (input.cpp.optimization) {
case "small":
args.push("OPTIMIZE (SIZE)");
@@ -324,28 +427,36 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
break;
}
- if (input.cpp.debugInformation)
- args.push("DEBUG");
-
- var warnings = input.cpp.warningLevel;
- if (warnings === "none") {
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
args.push("WARNINGLEVEL (0)");
- } else if (warnings === "all") {
+ break;
+ case "all":
args.push("WARNINGLEVEL (2)");
args.push("FARWARNING");
- }
-
- if (allDefines.length > 0)
- args = args.concat("DEFINE (" + allDefines.join(",") + ")");
-
- if (allIncludePaths.length > 0) {
- var adjusted = adjustPathsToWindowsSeparators(allIncludePaths);
- args = args.concat("INCDIR (" + adjusted.join(";") + ")");
+ break;
}
} else if (architecture === "arm") {
+ // Input.
args.push("-c", input.filePath);
+
+ // Output.
args.push("-o", output.filePath);
+ // Defines.
+ args = args.concat(allDefines.map(function(define) { return '-D' + define }));
+
+ // Includes.
+ args = args.concat(allIncludePaths.map(function(include) { return '-I' + include }));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation) {
+ args.push("--debug");
+ args.push("-g");
+ }
+
+ // Optimization level flags.
switch (input.cpp.optimization) {
case "small":
args.push("-Ospace")
@@ -358,43 +469,57 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
break;
}
- if (input.cpp.debugInformation) {
- args.push("--debug");
- args.push("-g");
- }
-
- var warnings = input.cpp.warningLevel;
- if (warnings === "none") {
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
args.push("-W");
- } else if (warnings === "all") {
+ break;
+ default:
// By default all warnings are enabled.
+ break;
}
if (tag === "c") {
- // Note: Here we use the '==' operator because the '==='
- // operator does not work!
- if (input.cpp.cLanguageVersion == "c99")
+ // C language version flags.
+ var knownCLanguageValues = ["c99", "c90"];
+ var cLanguageVersion = Cpp.languageVersion(
+ input.cpp.cLanguageVersion, knownCLanguageValues, "C");
+ switch (cLanguageVersion) {
+ case "c99":
args.push("--c99");
+ break;
+ case "c90":
+ args.push("--c90");
+ break;
+ }
} else if (tag === "cpp") {
- args.push("--cpp");
- // Note: Here we use the '==' operator because the '==='
- // operator does not work!
- if (input.cpp.cxxLanguageVersion == "c++11")
+ // C++ language version flags.
+ var knownCppLanguageValues = ["c++11", "c++03"];
+ var cppLanguageVersion = Cpp.languageVersion(
+ input.cpp.cxxLanguageVersion, knownCppLanguageValues, "C++");
+ switch (cppLanguageVersion) {
+ case "c++11":
args.push("--cpp11");
+ break;
+ default:
+ // Default C++ language is C++03.
+ args.push("--cpp");
+ break;
+ }
+ // Exceptions flags.
var enableExceptions = input.cpp.enableExceptions;
if (enableExceptions !== undefined)
args.push(enableExceptions ? "--exceptions" : "--no_exceptions");
+ // RTTI flags.
var enableRtti = input.cpp.enableRtti;
if (enableRtti !== undefined)
args.push(enableRtti ? "--rtti" : "--no_rtti");
}
-
- args = args.concat(allDefines.map(function(define) { return '-D' + define }));
- args = args.concat(allIncludePaths.map(function(include) { return '-I' + include }));
}
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
ModUtils.moduleProperty(input, "flags"),
ModUtils.moduleProperty(input, "platformFlags", tag),
@@ -404,9 +529,8 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
}
function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
- // Determine which C-language we"re compiling
+ // Determine which C-language we're compiling
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
- var architecture = input.qbs.architecture;
var args = [];
var allDefines = [];
@@ -428,37 +552,35 @@ function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
if (compilerIncludePaths)
allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
+ var architecture = input.qbs.architecture;
if (architecture === "mcs51") {
+ // Input.
args.push(FileInfo.toWindowsSeparators(input.filePath));
- args.push("OBJECT (" + FileInfo.toWindowsSeparators(output.filePath) + ")");
- if (input.cpp.debugInformation)
- args.push("DEBUG");
+ // Output.
+ args.push("OBJECT (" + FileInfo.toWindowsSeparators(output.filePath) + ")");
+ // Defines.
if (allDefines.length > 0)
args = args.concat("DEFINE (" + allDefines.join(",") + ")");
+ // Includes.
if (allIncludePaths.length > 0) {
var adjusted = adjustPathsToWindowsSeparators(allIncludePaths);
args = args.concat("INCDIR (" + adjusted.join(";") + ")");
}
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("DEBUG");
} else if (architecture === "arm") {
+ // Input.
args.push(input.filePath);
- args.push("-o", output.filePath);
- if (input.cpp.debugInformation) {
- args.push("--debug");
- args.push("-g");
- }
-
- var warnings = input.cpp.warningLevel;
- if (warnings === "none")
- args.push("--no_warn");
-
- var endianness = input.cpp.endianness;
- if (endianness)
- args.push((endianness === "little") ? "--littleend" : "--bigend");
+ // Output.
+ args.push("-o", output.filePath);
+ // Defines.
allDefines.forEach(function(define) {
var parts = define.split("=");
args.push("--pd");
@@ -470,9 +592,26 @@ function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
args.push(parts[0] + " SETA " + parts[1]);
});
+ // Includes.
args = args.concat(allIncludePaths.map(function(include) { return '-I' + include }));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation) {
+ args.push("--debug");
+ args.push("-g");
+ }
+
+ // Warning level flags.
+ if (input.cpp.warningLevel === "none")
+ args.push("--no_warn");
+
+ // Byte order flags.
+ var endianness = input.cpp.endianness;
+ if (endianness)
+ args.push((endianness === "little") ? "--littleend" : "--bigend");
}
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
ModUtils.moduleProperty(input, "flags", tag),
ModUtils.moduleProperty(input, "driverFlags", tag));
@@ -481,89 +620,119 @@ function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
function linkerFlags(project, product, input, outputs) {
var args = [];
- var architecture = product.qbs.architecture;
+ var architecture = product.qbs.architecture;
if (architecture === "mcs51") {
+ // Note: The C51 linker does not distinguish an object files and
+ // a libraries, it interpret all this stuff as an input objects,
+ // so, we need to pass it together in one string.
+
var allObjectPaths = [];
function addObjectPath(obj) {
allObjectPaths.push(obj.filePath);
}
+ // Inputs.
if (inputs.obj)
inputs.obj.map(function(obj) { addObjectPath(obj) });
- var libraryDependencies = collectLibraryDependencies(product);
- libraryDependencies.forEach(function(dep) { addObjectPath(dep); })
+ // Library dependencies.
+ var libraryObjects = collectLibraryDependencies(product);
+ libraryObjects.forEach(function(dep) { addObjectPath(dep); })
+ // Add all input objects as arguments (application and library object files).
var adjusted = adjustPathsToWindowsSeparators(allObjectPaths);
args = args.concat(adjusted.join(","));
- // We need to wrap an output file name with quotes. Otherwise
+ // Output.
+ // Note: We need to wrap an output file name with quotes. Otherwise
// the linker will ignore a specified file name.
args.push("TO", '"' + FileInfo.toWindowsSeparators(outputs.application[0].filePath) + '"');
- if (!product.cpp.generateMapFile)
+ // Map file generation flag.
+ if (!product.cpp.generateLinkerMapFile)
args.push("NOMAP");
} else if (architecture === "arm") {
+ // Inputs.
if (inputs.obj)
args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ // Output.
args.push("--output", outputs.application[0].filePath);
if (product.cpp.generateMapFile)
args.push("--list", outputs.mem_map[0].filePath);
+ // Library paths.
var libraryPaths = product.cpp.libraryPaths;
if (libraryPaths)
args.push("--userlibpath=" + libraryPaths.join(","));
+ // Library dependencies.
var libraryDependencies = collectLibraryDependencies(product);
args = args.concat(libraryDependencies.map(function(dep) { return dep.filePath; }));
- var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
- for (i in linkerScripts)
- args.push("--scatter", linkerScripts[i]);
+ // Debug information flag.
+ var debugInformation = product.cpp.debugInformation;
+ if (debugInformation !== undefined)
+ args.push(debugInformation ? "--debug" : "--no_debug");
+
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
+ args.push("--list", outputs.map_file[0].filePath);
+ // Entry point flag.
if (product.cpp.entryPoint)
args.push("--entry", product.cpp.entryPoint);
- var debugInformation = product.cpp.debugInformation;
- if (debugInformation !== undefined)
- args.push(debugInformation ? "--debug" : "--no_debug");
+ // Linker scripts flags.
+ var linkerScripts = inputs.linkerscript
+ ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
+ linkerScripts.forEach(function(script) { args.push("--scatter", script); });
}
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
return args;
}
function archiverFlags(project, product, input, outputs) {
var args = [];
- var architecture = product.qbs.architecture;
+ var architecture = product.qbs.architecture;
if (architecture === "mcs51") {
+ // Library creation command.
args.push("TRANSFER");
- var allObjectPaths = [];
+ var allObjectPaths = [];
function addObjectPath(obj) {
allObjectPaths.push(obj.filePath);
}
+ // Inputs.
if (inputs.obj)
inputs.obj.map(function(obj) { addObjectPath(obj) });
+ // Add all input objects as arguments.
var adjusted = adjustPathsToWindowsSeparators(allObjectPaths);
args = args.concat(adjusted.join(","));
- // We need to wrap a output file name with quotes. Otherwise
+ // Output.
+ // Note: We need to wrap a output file name with quotes. Otherwise
// the linker will ignore a specified file name.
args.push("TO", '"' + FileInfo.toWindowsSeparators(outputs.staticlibrary[0].filePath) + '"');
} else if (architecture === "arm") {
+ // Note: The ARM archiver command line expect the output file
+ // first, and then a set of input objects.
+
+ // Output.
args.push("--create", outputs.staticlibrary[0].filePath);
+ // Inputs.
if (inputs.obj)
args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ // Debug information flag.
if (product.cpp.debugInformation)
args.push("--debug_symbols");
}
@@ -575,7 +744,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var args = compilerFlags(project, product, input, output, explicitlyDependsOn);
var compilerPath = input.cpp.compilerPath;
var architecture = input.cpp.architecture;
- var cmd = new Command(compilerPath, args)
+ var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
cmd.maxExitCode = getMaxExitCode(architecture);
@@ -587,7 +756,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var args = assemblerFlags(project, product, input, output, explicitlyDependsOn);
var assemblerPath = input.cpp.assemblerPath;
- var cmd = new Command(assemblerPath, args)
+ var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
filterStdOutput(cmd);
@@ -598,7 +767,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var primaryOutput = outputs.application[0];
var args = linkerFlags(project, product, input, outputs);
var linkerPath = product.cpp.linkerPath;
- var cmd = new Command(linkerPath, args)
+ var cmd = new Command(linkerPath, args);
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
filterStdOutput(cmd);
@@ -608,7 +777,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
function prepareArchiver(project, product, inputs, outputs, input, output) {
var args = archiverFlags(project, product, input, outputs);
var archiverPath = product.cpp.archiverPath;
- var cmd = new Command(archiverPath, args)
+ var cmd = new Command(archiverPath, args);
cmd.description = "linking " + output.fileName;
cmd.highlight = "linker";
filterStdOutput(cmd);
diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs
index c87bf05f8..1a1792118 100644
--- a/share/qbs/modules/cpp/keil.qbs
+++ b/share/qbs/modules/cpp/keil.qbs
@@ -66,95 +66,30 @@ CppModule {
property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
- property bool generateMapFile: true
- PropertyOptions {
- name: "generateMapFile"
- description: "produce a linker list file (enabled by default)"
- }
-
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
- compilerName: {
- switch (qbs.architecture) {
- case "mcs51":
- return "c51" + compilerExtension;
- case "arm":
- return "armcc" + compilerExtension;
- }
- }
+ compilerName: KEIL.compilerName(qbs) + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: {
- switch (qbs.architecture) {
- case "mcs51":
- return "a51" + compilerExtension;
- case "arm":
- return "armasm" + compilerExtension;
- }
- }
+ assemblerName: KEIL.assemblerName(qbs) + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: {
- switch (qbs.architecture) {
- case "mcs51":
- return "bl51" + compilerExtension;
- case "arm":
- return "armlink" + compilerExtension;
- }
- }
+ linkerName: KEIL.linkerName(qbs) + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: {
- switch (qbs.architecture) {
- case "mcs51":
- return "lib51" + compilerExtension;
- case "arm":
- return "armar" + compilerExtension;
- }
- }
+ property string archiverName: KEIL.archiverName(qbs) + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
runtimeLibrary: "static"
- staticLibrarySuffix: {
- switch (qbs.architecture) {
- case "mcs51":
- return ".lib";
- case "arm":
- return ".lib";
- }
- }
-
- executableSuffix: {
- switch (qbs.architecture) {
- case "mcs51":
- return ".abs";
- case "arm":
- return ".axf";
- }
- }
+ staticLibrarySuffix: KEIL.staticLibrarySuffix(qbs)
+ executableSuffix: KEIL.executableSuffix(qbs)
- property string objectSuffix: {
- switch (qbs.architecture) {
- case "mcs51":
- return ".obj";
- case "arm":
- return ".o";
- }
- }
+ property string objectSuffix: KEIL.objectSuffix(qbs)
- imageFormat: {
- switch (qbs.architecture) {
- case "mcs51":
- // Keil OMF51 or OMF2 Object Module Format (which is an
- // extension of the original Intel OMF51).
- return "omf";
- case "arm":
- return "elf";
- }
- }
+ imageFormat: KEIL.imageFormat(qbs)
enableExceptions: false
enableRtti: false
@@ -175,7 +110,7 @@ CppModule {
FileTagger {
condition: qbs.architecture === "arm";
- patterns: "*.s"
+ patterns: ["*.s", ".asm"]
fileTags: ["asm"]
}
@@ -192,7 +127,12 @@ CppModule {
id: applicationLinker
multiplex: true
inputs: ["obj", "linkerscript"]
- outputFileTags: ["application", "mem_map"]
+ outputFileTags: {
+ var tags = ["application", "mem_map"];
+ if (product.moduleProperty("cpp", "generateLinkerMapFile"))
+ tags.push("map_file");
+ return tags;
+ }
outputArtifacts: KEIL.applicationLinkerOutputArtifacts(product)
prepare: KEIL.prepareLinker.apply(KEIL, arguments)
}
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index 9deffa064..02facf30a 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -542,3 +542,46 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
return commands;
}
+function createRcCommand(binary, input, output, logo) {
+ var platformDefines = input.cpp.platformDefines;
+ var defines = input.cpp.defines;
+ var includePaths = input.cpp.includePaths;
+ var systemIncludePaths = input.cpp.systemIncludePaths;
+
+ var args = [];
+ if (logo === "can-suppress-logo")
+ args.push("/nologo");
+ for (i in platformDefines) {
+ args.push("/d");
+ args.push(platformDefines[i]);
+ }
+ for (i in defines) {
+ args.push("/d");
+ args.push(defines[i]);
+ }
+ for (i in includePaths) {
+ args.push("/I");
+ args.push(includePaths[i]);
+ }
+ for (i in systemIncludePaths) {
+ args.push("/I");
+ args.push(systemIncludePaths[i]);
+ }
+ args = args.concat(["/FO", output.filePath, input.filePath]);
+ var cmd = new Command(binary, args);
+ cmd.description = 'compiling ' + input.fileName;
+ cmd.highlight = 'compiler';
+ cmd.jobPool = "compiler";
+
+ if (logo === "always-shows-logo") {
+ // Remove the first two lines of stdout. That's the logo.
+ cmd.stdoutFilterFunction = function(output) {
+ var idx = 0;
+ for (var i = 0; i < 3; ++i)
+ idx = output.indexOf('\n', idx + 1);
+ return output.substr(idx + 1);
+ }
+ }
+
+ return cmd;
+}
diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js
index f8c0d3b12..0d656ef17 100644
--- a/share/qbs/modules/cpp/sdcc.js
+++ b/share/qbs/modules/cpp/sdcc.js
@@ -40,23 +40,62 @@ var TextFile = require("qbs.TextFile");
var Utilities = require("qbs.Utilities");
var WindowsUtils = require("qbs.WindowsUtils");
+function compilerName(qbs) {
+ return "sdcc";
+}
+
+function assemblerName(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "sdas8051";
+ case "stm8":
+ return "sdasstm8";
+ }
+ throw "Unable to deduce assembler name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function linkerName(qbs) {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "sdld";
+ case "stm8":
+ return "sdldstm8";
+ }
+ throw "Unable to deduce linker name for unsupported architecture: '"
+ + qbs.architecture + "'";
+}
+
+function archiverName(qbs) {
+ return "sdcclib";
+}
+
function targetArchitectureFlag(architecture) {
if (architecture === "mcs51")
return "-mmcs51";
+ if (architecture === "stm8")
+ return "-mstm8";
}
-function guessArchitecture(macros)
-{
+function guessArchitecture(macros) {
if (macros["__SDCC_mcs51"] === "1")
return "mcs51";
+ if (macros["__SDCC_stm8"] === "1")
+ return "stm8";
}
-function guessEndianness(macros)
-{
+function guessEndianness(macros) {
// SDCC stores numbers in little-endian format.
return "little";
}
+function guessVersion(macros) {
+ return { major: parseInt(macros["__SDCC_VERSION_MAJOR"], 10),
+ minor: parseInt(macros["__SDCC_VERSION_MINOR"], 10),
+ patch: parseInt(macros["__SDCC_VERSION_PATCH"], 10),
+ found: macros["SDCC"] }
+}
+
function dumpMacros(compilerFilePath, architecture) {
var tempDir = new TemporaryDir();
var fakeIn = new TextFile(tempDir.path() + "/empty-source.c", TextFile.WriteOnly);
@@ -238,7 +277,16 @@ function applicationLinkerOutputArtifacts(product) {
product.destinationDirectory,
product.targetName + ".map")
};
- return [app, lk_cmd, mem_summary, mem_map]
+ var artifacts = [app, lk_cmd, mem_summary, mem_map];
+ if (product.cpp.generateLinkerMapFile) {
+ artifacts.push({
+ fileTags: ["map_file"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ product.targetName + ".map")
+ });
+ }
+ return artifacts;
}
function staticLibraryLinkerOutputArtifacts(product) {
@@ -257,39 +305,14 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
var args = [];
+ // Input.
args.push(input.filePath);
+
+ // Output.
args.push("-c");
args.push("-o", outputs.obj[0].filePath);
- switch (input.cpp.optimization) {
- case "small":
- args.push("--opt-code-size");
- break;
- case "fast":
- args.push("--opt-code-speed");
- break;
- case "none":
- // SDCC has not option to disable the optimization.
- break;
- }
-
- if (input.cpp.debugInformation)
- args.push("--debug");
-
- var warnings = input.cpp.warningLevel;
- if (warnings === "none")
- args.push("--less-pedantic");
-
- if (input.cpp.treatWarningsAsErrors)
- args.push("--Werror");
-
- if (tag === "c") {
- if (input.cpp.cLanguageVersion === "c89")
- args.push("--std-c89");
- else if (input.cpp.cLanguageVersion === "c11")
- args.push("--std-c11");
- }
-
+ // Defines.
var allDefines = [];
var platformDefines = input.cpp.platformDefines;
if (platformDefines)
@@ -299,6 +322,7 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
allDefines = allDefines.uniqueConcat(defines);
args = args.concat(allDefines.map(function(define) { return "-D" + define }));
+ // Includes.
var allIncludePaths = [];
var includePaths = input.cpp.includePaths;
if (includePaths)
@@ -311,6 +335,49 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
+ var targetFlag = targetArchitectureFlag(input.cpp.architecture);
+ if (targetFlag)
+ args.push(targetFlag);
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("--debug");
+
+ // Optimization level flags.
+ switch (input.cpp.optimization) {
+ case "small":
+ args.push("--opt-code-size");
+ break;
+ case "fast":
+ args.push("--opt-code-speed");
+ break;
+ case "none":
+ // SDCC has not option to disable the optimization.
+ break;
+ }
+
+ // Warning level flags.
+ if (input.cpp.warningLevel === "none")
+ args.push("--less-pedantic");
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("--Werror");
+
+ // C language version flags.
+ if (tag === "c") {
+ var knownValues = ["c11", "c89"];
+ var cLanguageVersion = Cpp.languageVersion(
+ input.cpp.cLanguageVersion, knownValues, "C");
+ switch (cLanguageVersion) {
+ case "c89":
+ args.push("--std-c89");
+ break;
+ case "c11":
+ args.push("--std-c11");
+ break;
+ }
+ }
+
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
ModUtils.moduleProperty(input, "flags"),
ModUtils.moduleProperty(input, "platformFlags", tag),
@@ -326,6 +393,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
var args = [];
+ // Includes.
var allIncludePaths = [];
var systemIncludePaths = input.cpp.systemIncludePaths;
if (systemIncludePaths)
@@ -335,6 +403,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
+ // Misc flags.
args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
ModUtils.moduleProperty(input, "flags", tag),
ModUtils.moduleProperty(input, "driverFlags", tag));
@@ -348,6 +417,11 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
function linkerFlags(project, product, input, outputs) {
var args = [];
+ // Target MCU flag.
+ var targetFlag = targetArchitectureFlag(product.cpp.architecture);
+ if (targetFlag)
+ args.push(targetFlag);
+
var allLibraryPaths = [];
var libraryPaths = product.cpp.libraryPaths;
if (libraryPaths)
@@ -360,7 +434,8 @@ function linkerFlags(project, product, input, outputs) {
var escapableLinkerFlags = [];
- if (product.cpp.generateMapFile)
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
escapableLinkerFlags.push("-m");
if (product.cpp.platformLinkerFlags)
@@ -370,38 +445,45 @@ function linkerFlags(project, product, input, outputs) {
var useCompilerDriver = useCompilerDriverLinker(product);
if (useCompilerDriver) {
+ // Output.
args.push("-o", outputs.application[0].filePath);
+ // Inputs.
if (inputs.obj)
args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ // Library paths.
args = args.concat(allLibraryPaths.map(function(path) { return "-L" + path }));
+ // Linker scripts.
var scripts = inputs.linkerscript
? inputs.linkerscript.map(function(scr) { return "-f" + scr.filePath; }) : [];
if (scripts)
Array.prototype.push.apply(escapableLinkerFlags, scripts);
} else {
+ // Output.
args.push(outputs.application[0].filePath);
+ // Inputs.
if (inputs.obj)
args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ // Library paths.
args = args.concat(allLibraryPaths.map(function(path) { return "-k" + path }));
- var scripts = inputs.linkerscript;
- if (scripts) {
- // Note: We need to split the '-f' and the file path to separate
- // lines; otherwise the linking fails.
- scripts.forEach(function(scr) {
- escapableLinkerFlags.push("-f", scr.filePath);
- });
- }
+ // Linker scripts.
+ // Note: We need to split the '-f' and the file path to separate
+ // lines; otherwise the linking fails.
+ inputs.linkerscript.forEach(function(scr) {
+ escapableLinkerFlags.push("-f", scr.filePath);
+ });
}
+ // Library dependencies.
if (libraryDependencies)
args = args.concat(libraryDependencies.map(function(dep) { return "-l" + dep.filePath }));
+ // Misc flags.
var escapedLinkerFlags = escapeLinkerFlags(product, escapableLinkerFlags);
if (escapedLinkerFlags)
Array.prototype.push.apply(args, escapedLinkerFlags);
@@ -422,7 +504,7 @@ function archiverFlags(project, product, input, outputs) {
function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
var compilerPath = input.cpp.compilerPath;
- var cmd = new Command(compilerPath, args)
+ var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
return [cmd];
@@ -431,7 +513,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn);
var assemblerPath = input.cpp.assemblerPath;
- var cmd = new Command(assemblerPath, args)
+ var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
return [cmd];
@@ -441,7 +523,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var primaryOutput = outputs.application[0];
var args = linkerFlags(project, product, input, outputs);
var linkerPath = effectiveLinkerPath(product);
- var cmd = new Command(linkerPath, args)
+ var cmd = new Command(linkerPath, args);
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
return [cmd];
@@ -450,7 +532,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
function prepareArchiver(project, product, inputs, outputs, input, output) {
var args = archiverFlags(project, product, input, outputs);
var archiverPath = product.cpp.archiverPath;
- var cmd = new Command(archiverPath, args)
+ var cmd = new Command(archiverPath, args);
cmd.description = "linking " + output.fileName;
cmd.highlight = "linker";
return [cmd];
diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs
index 7b65ec609..e4a040439 100644
--- a/share/qbs/modules/cpp/sdcc.qbs
+++ b/share/qbs/modules/cpp/sdcc.qbs
@@ -66,38 +66,22 @@ CppModule {
property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
- property bool generateMapFile: true
- PropertyOptions {
- name: "generateMapFile"
- description: "produce a linker list file (enabled by default)"
- }
-
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
property string linkerMode: "automatic"
- compilerName: "sdcc" + compilerExtension
+ compilerName: SDCC.compilerName(qbs) + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: {
- switch (qbs.architecture) {
- case "mcs51":
- return "sdas8051" + compilerExtension;
- }
- }
+ assemblerName: SDCC.assemblerName(qbs) + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: {
- switch (qbs.architecture) {
- case "mcs51":
- return "sdld" + compilerExtension;
- }
- }
+ linkerName: SDCC.linkerName(qbs) + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: "sdcclib" + compilerExtension
+ property string archiverName: SDCC.archiverName(qbs) + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
runtimeLibrary: "static"
@@ -146,7 +130,12 @@ CppModule {
multiplex: true
inputs: ["obj", "linkerscript"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["application", "lk_cmd", "mem_summary", "mem_map"]
+ outputFileTags: {
+ var tags = ["application", "lk_cmd", "mem_summary", "mem_map"];
+ if (product.moduleProperty("cpp", "generateLinkerMapFile"))
+ tags.push("map_file");
+ return tags;
+ }
outputArtifacts: SDCC.applicationLinkerOutputArtifacts(product)
prepare:SDCC.prepareLinker.apply(SDCC, arguments)
}
diff --git a/share/qbs/modules/cpp/windows-clang-mingw.qbs b/share/qbs/modules/cpp/windows-clang-mingw.qbs
new file mode 100644
index 000000000..8389dbf2e
--- /dev/null
+++ b/share/qbs/modules/cpp/windows-clang-mingw.qbs
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.File
+import qbs.FileInfo
+import qbs.ModUtils
+import qbs.Utilities
+import "msvc.js" as MSVC
+
+import "setuprunenv.js" as SetupRunEnv
+
+MingwBaseModule {
+ condition: qbs.targetOS.contains("windows") &&
+ qbs.toolchain && qbs.toolchain.contains("clang")
+ priority: 0
+
+ // llvm-as and llvm-objopy are not shipped with the official binaries on Windows at the
+ // moment (8.0). We fall back to using the mingw versions in that case.
+ assemblerName: "llvm-as" + compilerExtension
+ assemblerPath: {
+ if (File.exists(base))
+ return base;
+ if (qbs.sysroot)
+ return FileInfo.joinPaths(qbs.sysroot, "bin", "as" + compilerExtension);
+ }
+ objcopyName: "llvm-objcopy" + compilerExtension
+ objcopyPath: {
+ if (File.exists(base))
+ return base;
+ if (qbs.sysroot)
+ return FileInfo.joinPaths(qbs.sysroot, "bin", "objcopy" + compilerExtension);
+ }
+
+ archiverName: "llvm-ar" + compilerExtension
+
+ linkerVariant: "lld"
+ targetVendor: "pc"
+ targetSystem: "windows"
+ targetAbi: "gnu"
+ property string rcFilePath: FileInfo.joinPaths(toolchainInstallPath,
+ "llvm-rc" + compilerExtension)
+
+ setupBuildEnvironment: {
+ if (product.qbs.hostOS.contains("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ v.prepend(FileInfo.joinPaths(product.qbs.sysroot, "bin"));
+ v.set();
+ }
+ }
+
+ setupRunEnvironment: {
+ if (product.qbs.hostOS.contains("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ v.prepend(FileInfo.joinPaths(product.qbs.sysroot, "bin"));
+ v.set();
+ SetupRunEnv.setupRunEnvironment(product, config);
+ }
+ }
+
+ Rule {
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+
+ Artifact {
+ filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
+ fileTags: ["obj"]
+ }
+
+ prepare: MSVC.createRcCommand(product.cpp.rcFilePath, input, output);
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-mingw.qbs b/share/qbs/modules/cpp/windows-mingw.qbs
index 27382742f..fe9fd4bf8 100644
--- a/share/qbs/modules/cpp/windows-mingw.qbs
+++ b/share/qbs/modules/cpp/windows-mingw.qbs
@@ -28,39 +28,28 @@
**
****************************************************************************/
+import qbs.File
+import qbs.FileInfo
import qbs.ModUtils
-import qbs.TextFile
import qbs.Utilities
-import qbs.WindowsUtils
import "setuprunenv.js" as SetupRunEnv
-GenericGCC {
+MingwBaseModule {
condition: qbs.targetOS.contains("windows") &&
qbs.toolchain && qbs.toolchain.contains("mingw")
priority: 0
- staticLibraryPrefix: "lib"
- staticLibrarySuffix: ".a"
- dynamicLibrarySuffix: ".dll"
- executableSuffix: ".exe"
- debugInfoSuffix: ".debug"
- imageFormat: "pe"
- windowsApiCharacterSet: "unicode"
- platformDefines: base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
- .concat("WIN32")
+
probeEnv: buildEnv
- Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
- && qbs.buildVariants && qbs.buildVariants.length > 1
- && qbs.buildVariant !== "release"
- && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
- variantSuffix: "d"
+ property string windresName: "windres" + compilerExtension
+ property path windresPath: {
+ var filePath = toolchainPrefix + windresName;
+ if (!File.exists(filePath))
+ filePath = FileInfo.joinPaths(toolchainInstallPath, windresName);
+ return filePath;
}
- property string windresName: 'windres'
- property path windresPath: { return toolchainPathPrefix + windresName }
-
setupBuildEnvironment: {
var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
v.prepend(product.cpp.toolchainInstallPath);
@@ -74,63 +63,6 @@ GenericGCC {
SetupRunEnv.setupRunEnvironment(product, config);
}
- FileTagger {
- patterns: ["*.manifest"]
- fileTags: ["native.pe.manifest"]
- }
-
- Rule {
- inputs: ["native.pe.manifest"]
- multiplex: true
-
- outputFileTags: ["rc"]
- outputArtifacts: {
- if (product.type.containsAny(["application", "dynamiclibrary"])) {
- return [{
- filePath: input.completeBaseName + ".rc",
- fileTags: ["rc"]
- }];
- }
- return [];
- }
-
- prepare: {
- var inputList = inputs["native.pe.manifest"];
- // TODO: Emulate manifest merging like Microsoft's mt.exe tool does
- if (inputList.length !== 1) {
- throw("The MinGW toolchain does not support manifest merging; " +
- "you may only specify a single manifest file to embed into your assembly.");
- }
-
- var cmd = new JavaScriptCommand();
- cmd.silent = true;
- cmd.productType = product.type;
- cmd.inputFilePath = inputList[0].filePath;
- cmd.outputFilePath = output.filePath;
- cmd.sourceCode = function() {
- var tf;
- try {
- tf = new TextFile(outputFilePath, TextFile.WriteOnly);
- if (productType.contains("application"))
- tf.write("1 "); // CREATEPROCESS_MANIFEST_RESOURCE_ID
- else if (productType.contains("dynamiclibrary"))
- tf.write("2 "); // ISOLATIONAWARE_MANIFEST_RESOURCE_ID
- tf.write("24 "); // RT_MANIFEST
- tf.writeLine(Utilities.cStringQuote(inputFilePath));
- } finally {
- if (tf)
- tf.close();
- }
- };
- return [cmd];
- }
- }
-
- FileTagger {
- patterns: ["*.rc"]
- fileTags: ["rc"]
- }
-
Rule {
inputs: ["rc"]
auxiliaryInputs: ["hpp"]
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
index d36daa99f..ae105abe2 100644
--- a/share/qbs/modules/cpp/windows-msvc-base.qbs
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -291,50 +291,10 @@ CppModule {
}
prepare: {
- var platformDefines = input.cpp.platformDefines;
- var defines = input.cpp.defines;
- var includePaths = input.cpp.includePaths;
- var systemIncludePaths = input.cpp.systemIncludePaths;
- var args = [];
- var i;
- var hasNoLogo = product.cpp.compilerVersionMajor >= 16; // 2010
- if (hasNoLogo)
- args.push("/nologo");
-
- for (i in platformDefines) {
- args.push('/d');
- args.push(platformDefines[i]);
- }
- for (i in defines) {
- args.push('/d');
- args.push(defines[i]);
- }
- for (i in includePaths) {
- args.push('/i');
- args.push(includePaths[i]);
- }
- for (i in systemIncludePaths) {
- args.push('/i');
- args.push(systemIncludePaths[i]);
- }
-
- args = args.concat(['/fo', output.filePath, input.filePath]);
- var cmd = new Command('rc', args);
- cmd.description = 'compiling ' + input.fileName;
- cmd.highlight = 'compiler';
- cmd.jobPool = "compiler";
-
- if (!hasNoLogo) {
- // Remove the first two lines of stdout. That's the logo.
- cmd.stdoutFilterFunction = function(output) {
- var idx = 0;
- for (var i = 0; i < 3; ++i)
- idx = output.indexOf('\n', idx + 1);
- return output.substr(idx + 1);
- }
- }
-
- return cmd;
+ // From MSVC 2010 on, the logo can be suppressed.
+ var logo = product.cpp.compilerVersionMajor >= 16
+ ? "can-suppress-logo" : "always-shows-logo";
+ return MSVC.createRcCommand("rc", input, output, logo);
}
}