diff options
Diffstat (limited to 'share')
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); } } |