aboutsummaryrefslogtreecommitdiffstats
path: root/share/qbs/modules/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'share/qbs/modules/cpp')
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs59
-rw-r--r--share/qbs/modules/cpp/DarwinGCC.qbs52
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs236
-rw-r--r--share/qbs/modules/cpp/LinuxGCC.qbs7
-rw-r--r--share/qbs/modules/cpp/MingwBaseModule.qbs9
-rw-r--r--share/qbs/modules/cpp/UnixGCC.qbs6
-rw-r--r--share/qbs/modules/cpp/android-gcc.qbs110
-rw-r--r--share/qbs/modules/cpp/cosmic.js443
-rw-r--r--share/qbs/modules/cpp/cosmic.qbs147
-rw-r--r--share/qbs/modules/cpp/cpp.js431
-rw-r--r--share/qbs/modules/cpp/darwin.js33
-rw-r--r--share/qbs/modules/cpp/dmc.js506
-rw-r--r--share/qbs/modules/cpp/dmc.qbs194
-rw-r--r--share/qbs/modules/cpp/freebsd-gcc.qbs7
-rw-r--r--share/qbs/modules/cpp/gcc.js408
-rw-r--r--share/qbs/modules/cpp/iar.js892
-rw-r--r--share/qbs/modules/cpp/iar.qbs64
-rw-r--r--share/qbs/modules/cpp/ios-gcc.qbs21
-rw-r--r--share/qbs/modules/cpp/keil.js1137
-rw-r--r--share/qbs/modules/cpp/keil.qbs64
-rw-r--r--share/qbs/modules/cpp/macos-gcc.qbs4
-rw-r--r--share/qbs/modules/cpp/msvc.js384
-rw-r--r--share/qbs/modules/cpp/qnx-qcc.qbs6
-rw-r--r--share/qbs/modules/cpp/sdcc.js562
-rw-r--r--share/qbs/modules/cpp/sdcc.qbs66
-rw-r--r--share/qbs/modules/cpp/setuprunenv.js27
-rw-r--r--share/qbs/modules/cpp/tvos-gcc.qbs8
-rw-r--r--share/qbs/modules/cpp/watchos-gcc.qbs8
-rw-r--r--share/qbs/modules/cpp/watcom.js568
-rw-r--r--share/qbs/modules/cpp/watcom.qbs196
-rw-r--r--share/qbs/modules/cpp/windows-clang-cl.qbs33
-rw-r--r--share/qbs/modules/cpp/windows-clang-mingw.qbs18
-rw-r--r--share/qbs/modules/cpp/windows-mingw.qbs18
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs140
-rw-r--r--share/qbs/modules/cpp/windows-msvc.qbs13
35 files changed, 4908 insertions, 1969 deletions
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index bdd6d2750..bd1eaa242 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -29,10 +29,11 @@
****************************************************************************/
// base for Cpp modules
+import qbs.FileInfo
import qbs.ModUtils
import qbs.Utilities
import qbs.WindowsUtils
-
+import "cpp.js" as Cpp
import "setuprunenv.js" as SetupRunEnv
Module {
@@ -128,7 +129,7 @@ Module {
defaults will be used."
}
- property string minimumAndroidVersion
+ property string minimumAndroidVersion // not used, undocumented
PropertyOptions {
name: "minimumAndroidVersion"
description: "a version number in the format [major].[minor] indicating the earliest \
@@ -136,7 +137,7 @@ Module {
version which is then written to AndroidManifest.xml."
}
- property string maximumAndroidVersion
+ property string maximumAndroidVersion // not used, undocumented
PropertyOptions {
name: "maximumAndroidVersion"
description: "a version number in the format [major].[minor] indicating the latest \
@@ -145,6 +146,12 @@ Module {
be set."
}
+ property string toolchainInstallPath
+ PropertyOptions {
+ name: "toolchainInstallPath"
+ description: "a path to the directory where the toolchain executable files are located."
+ }
+
property pathList includePaths
property pathList systemIncludePaths
property pathList distributionIncludePaths
@@ -173,12 +180,19 @@ Module {
property string executablePrefix: ""
property string staticLibrarySuffix: ""
property string dynamicLibrarySuffix: ""
+ property string archSuffix: ""
property string loadableModuleSuffix: ""
property string executableSuffix: ""
property string debugInfoSuffix: ""
property string debugInfoBundleSuffix: ""
property string variantSuffix: ""
property string dynamicLibraryImportSuffix: ".lib"
+ property string objectSuffix: ".o"
+ property string linkerMapSuffix: ".map"
+ property string compilerListingSuffix: ".lst"
+ property string assemblerListingSuffix: ".lst"
+ property string resourceSuffix: ".res"
+ property string precompiledHeaderSuffix
property bool createSymlinks: true
property stringList dynamicLibraries // list of names, will be linked with -lname
property stringList staticLibraries // list of static library files
@@ -193,6 +207,33 @@ Module {
property bool discardUnusedData
property bool removeDuplicateLibraries: true
+ property string defineFlag
+ property string includeFlag
+ property string systemIncludeFlag
+ property string preincludeFlag
+ property string libraryDependencyFlag
+ property string libraryPathFlag
+ property string linkerScriptFlag
+
+ property stringList knownArchitectures: []
+ property var toolchainDetails
+ property string compilerExtension: FileInfo.executableSuffix()
+
+ property string linkerMode: "automatic"
+ PropertyOptions {
+ name: "linkerMode"
+ allowedValues: ["automatic", "manual"]
+ description: "Controls whether to automatically use an appropriate compiler frontend "
+ + "in place of the system linker when linking binaries. The default is \"automatic\", "
+ + "which chooses either the C++ compiler, C compiler, or system linker specified by "
+ + "the linkerName/linkerPath properties, depending on the type of object files "
+ + "present on the linker command line. \"manual\" allows you to explicitly specify "
+ + "the linker using the linkerName/linkerPath properties, and allows linker flags "
+ + "passed to the linkerFlags and platformLinkerFlags properties to be escaped "
+ + "manually (using -Wl or -Xlinker) instead of automatically based on the selected "
+ + "linker."
+ }
+
property stringList assemblerFlags
PropertyOptions {
name: "assemblerFlags"
@@ -299,14 +340,12 @@ Module {
property stringList cLanguageVersion
PropertyOptions {
name: "cLanguageVersion"
- allowedValues: ["c89", "c99", "c11"]
description: "The version of the C standard with which the code must comply."
}
property stringList cxxLanguageVersion
PropertyOptions {
name: "cxxLanguageVersion"
- allowedValues: ["c++98", "c++11", "c++14", "c++17"]
description: "The version of the C++ standard with which the code must comply."
}
@@ -369,13 +408,14 @@ Module {
property bool combineObjcSources: false
property bool combineObjcxxSources: false
+ // Those are set internally by different cpp module implementations
property stringList targetAssemblerFlags
property stringList targetDriverFlags
property stringList targetLinkerFlags
property bool _skipAllChecks: false // Internal
- property bool validateTargetTriple: true
+ property bool validateTargetTriple: true // undocumented
// TODO: The following four rules could use a convenience base item if rule properties
// were available in Artifact items and prepare scripts.
@@ -508,6 +548,13 @@ Module {
return '"' + a + '"'; }).join(", ")
+ ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version");
}
+
+ if (knownArchitectures && knownArchitectures.length > 0) {
+ var isSupported = Cpp.supportsArchitecture(qbs.architecture, knownArchitectures);
+ if (!isSupported) {
+ throw ModUtils.ModuleError("Unsupported architecture: '" + qbs.architecture + "'");
+ }
+ }
}
}
diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs
index 9332603ec..e20973acc 100644
--- a/share/qbs/modules/cpp/DarwinGCC.qbs
+++ b/share/qbs/modules/cpp/DarwinGCC.qbs
@@ -43,7 +43,7 @@ import "gcc.js" as Gcc
UnixGCC {
condition: false
- Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.contains("xcode") }
+ Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.includes("xcode") }
Probes.BinaryProbe {
id: lipoProbe
@@ -76,7 +76,7 @@ UnixGCC {
dynamicLibrarySuffix: ".dylib"
Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
+ condition: product.multiplexByQbsProperties.includes("buildVariants")
&& qbs.buildVariants && qbs.buildVariants.length > 1
&& (!product.aggregate || !!product.multiplexConfigurationId)
&& qbs.buildVariant !== "release"
@@ -98,7 +98,7 @@ UnixGCC {
setupBuildEnvironment: {
for (var key in product.cpp.buildEnv) {
- v = new ModUtils.EnvironmentVariable(key);
+ var v = new ModUtils.EnvironmentVariable(key);
v.value = product.cpp.buildEnv[key];
v.set();
}
@@ -107,32 +107,42 @@ UnixGCC {
property var defaultInfoPlist: {
var dict = {};
- if (qbs.targetOS.contains("macos")) {
+ if (qbs.targetOS.includes("macos")) {
dict["NSPrincipalClass"] = "NSApplication"; // needed for Retina display support
+ // QBS-1670: set this flag by default to avoid extensive GPU usage
+ dict["NSSupportsAutomaticGraphicsSwitching"] = true;
+
if (minimumMacosVersion)
dict["LSMinimumSystemVersion"] = minimumMacosVersion;
}
+ if (qbs.targetOS.includes("ios") && minimumIosVersion)
+ dict["MinimumOSVersion"] = minimumIosVersion;
+ else if (qbs.targetOS.includes("tvos") && minimumTvosVersion)
+ dict["MinimumOSVersion"] = minimumTvosVersion;
+ else if (qbs.targetOS.includes("watchos") && minimumWatchosVersion)
+ dict["MinimumOSVersion"] = minimumWatchosVersion;
+
if (qbs.targetOS.containsAny(["ios", "tvos"])) {
dict["LSRequiresIPhoneOS"] = true;
if (xcode.platformType === "device") {
- if (qbs.targetOS.contains("ios")) {
+ if (qbs.targetOS.includes("ios")) {
if (qbs.architecture === "arm64")
dict["UIRequiredDeviceCapabilities"] = ["arm64"];
else
dict["UIRequiredDeviceCapabilities"] = ["armv7"];
}
- if (qbs.targetOS.contains("tvos"))
+ if (qbs.targetOS.includes("tvos"))
dict["UIRequiredDeviceCapabilities"] = ["arm64"];
}
}
if (xcode.present) {
var targetDevices = DarwinTools.targetedDeviceFamily(xcode.targetDevices);
- if (qbs.targetOS.contains("ios"))
+ if (qbs.targetOS.includes("ios"))
dict["UIDeviceFamily"] = targetDevices;
if (qbs.targetOS.containsAny(["ios", "watchos"])) {
@@ -143,13 +153,13 @@ UnixGCC {
"UIInterfaceOrientationLandscapeRight"
];
- if (targetDevices.contains("ipad"))
+ if (targetDevices.includes("ipad"))
dict["UISupportedInterfaceOrientations~ipad"] = orientations;
- if (targetDevices.contains("watch"))
+ if (targetDevices.includes("watch"))
dict["UISupportedInterfaceOrientations"] = orientations.slice(0, 2);
- if (targetDevices.contains("iphone")) {
+ if (targetDevices.includes("iphone")) {
orientations.splice(1, 1);
dict["UISupportedInterfaceOrientations"] = orientations;
}
@@ -189,13 +199,13 @@ UnixGCC {
// Set the corresponding environment variable even if the minimum OS version is undefined,
// because this indicates the default deployment target for that OS
- if (qbs.targetOS.contains("ios") && minimumIosVersion)
+ if (qbs.targetOS.includes("ios") && minimumIosVersion)
env["IPHONEOS_DEPLOYMENT_TARGET"] = minimumIosVersion;
- if (qbs.targetOS.contains("macos") && minimumMacosVersion)
+ if (qbs.targetOS.includes("macos") && minimumMacosVersion)
env["MACOSX_DEPLOYMENT_TARGET"] = minimumMacosVersion;
- if (qbs.targetOS.contains("watchos") && minimumWatchosVersion)
+ if (qbs.targetOS.includes("watchos") && minimumWatchosVersion)
env["WATCHOS_DEPLOYMENT_TARGET"] = minimumWatchosVersion;
- if (qbs.targetOS.contains("tvos") && minimumTvosVersion)
+ if (qbs.targetOS.includes("tvos") && minimumTvosVersion)
env["TVOS_DEPLOYMENT_TARGET"] = minimumTvosVersion;
if (xcode.present)
@@ -208,7 +218,7 @@ UnixGCC {
property string minimumDarwinVersionCompilerFlag
property string minimumDarwinVersionLinkerFlag
- property bool libcxxAvailable: qbs.toolchain.contains("clang") && cxxLanguageVersion !== "c++98"
+ property bool libcxxAvailable: qbs.toolchain.includes("clang") && cxxLanguageVersion !== "c++98"
Rule {
condition: enableAggregationRules
@@ -216,7 +226,8 @@ UnixGCC {
multiplex: true
outputFileTags: ["bundle.input", "application", "primary", "debuginfo_app",
- "debuginfo_bundle", "bundle.variant_symlink", "debuginfo_plist"]
+ "debuginfo_bundle", "bundle.variant_symlink", "debuginfo_plist",
+ "codesign.signed_artifact"]
outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "application", "app")
prepare: Darwin.prepareLipo.apply(Darwin, arguments)
@@ -227,7 +238,8 @@ UnixGCC {
inputsFromDependencies: ["loadablemodule"]
multiplex: true
- outputFileTags: ["bundle.input", "loadablemodule", "primary", "debuginfo_loadablemodule"]
+ outputFileTags: ["bundle.input", "loadablemodule", "primary", "debuginfo_loadablemodule",
+ "debuginfo_bundle", "debuginfo_plist", "codesign.signed_artifact"]
outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "loadablemodule",
"loadablemodule")
@@ -241,7 +253,7 @@ UnixGCC {
outputFileTags: ["bundle.input", "dynamiclibrary", "dynamiclibrary_symbols", "primary",
"debuginfo_dll","debuginfo_bundle","bundle.variant_symlink",
- "debuginfo_plist"]
+ "debuginfo_plist", "codesign.signed_artifact"]
outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "dynamiclibrary", "dll")
prepare: Darwin.prepareLipo.apply(Darwin, arguments)
@@ -252,14 +264,14 @@ UnixGCC {
inputsFromDependencies: ["staticlibrary"]
multiplex: true
- outputFileTags: ["bundle.input", "staticlibrary", "primary"]
+ outputFileTags: ["bundle.input", "staticlibrary", "primary", "codesign.signed_artifact"]
outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "staticlibrary")
prepare: Darwin.prepareLipo.apply(Darwin, arguments)
}
Rule {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
multiplex: true
Artifact {
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index 63d5db7b8..f84028940 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -30,6 +30,7 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.PathTools
import qbs.Probes
@@ -38,12 +39,15 @@ import qbs.TextFile
import qbs.Utilities
import qbs.UnixUtils
import qbs.WindowsUtils
+import 'cpp.js' as Cpp
import 'gcc.js' as Gcc
CppModule {
- condition: qbs.toolchain && qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain && qbs.toolchain.includes("gcc")
priority: -100
+ Depends { name: "codesign" }
+
Probes.GccBinaryProbe {
id: compilerPathProbe
condition: !toolchainInstallPath && !_skipAllChecks
@@ -114,9 +118,14 @@ CppModule {
compilerFrameworkPaths: gccProbe.frameworkPaths
compilerLibraryPaths: gccProbe.libraryPaths
- property bool compilerHasTargetOption: qbs.toolchain.contains("clang")
+ staticLibraryPrefix: "lib"
+ staticLibrarySuffix: ".a"
+
+ precompiledHeaderSuffix: ".gch"
+
+ property bool compilerHasTargetOption: qbs.toolchain.includes("clang")
&& Utilities.versionCompare(compilerVersion, "3.1") >= 0
- property bool assemblerHasTargetOption: qbs.toolchain.contains("xcode")
+ property bool assemblerHasTargetOption: qbs.toolchain.includes("xcode")
&& Utilities.versionCompare(compilerVersion, "7") >= 0
property string target: targetArch
? [targetArch, targetVendor, targetSystem, targetAbi].join("-")
@@ -131,8 +140,7 @@ CppModule {
property string toolchainPrefix: compilerPathProbe.found
? compilerPathProbe.tcPrefix
: undefined
- property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path
- : undefined
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
property string binutilsPath: binutilsProbe.found ? binutilsProbe.path : toolchainInstallPath
assemblerName: 'as' + compilerExtension
@@ -148,21 +156,6 @@ CppModule {
property string syslibroot: sysroot
property stringList sysrootFlags: sysroot ? ["--sysroot=" + sysroot] : []
- property string linkerMode: "automatic"
- PropertyOptions {
- name: "linkerMode"
- allowedValues: ["automatic", "manual"]
- description: "Controls whether to automatically use an appropriate compiler frontend "
- + "in place of the system linker when linking binaries. The default is \"automatic\", "
- + "which chooses either the C++ compiler, C compiler, or system linker specified by "
- + "the linkerName/linkerPath properties, depending on the type of object files "
- + "present on the linker command line. \"manual\" allows you to explicitly specify "
- + "the linker using the linkerName/linkerPath properties, and allows linker flags "
- + "passed to the linkerFlags and platformLinkerFlags properties to be escaped "
- + "manually (using -Wl or -Xlinker) instead of automatically based on the selected "
- + "linker."
- }
-
property string exportedSymbolsCheckMode: "ignore-undefined"
PropertyOptions {
name: "exportedSymbolsCheckMode"
@@ -177,7 +170,7 @@ CppModule {
property string linkerVariant
PropertyOptions {
name: "linkerVariant"
- allowedValues: ["bfd", "gold", "lld"]
+ allowedValues: ["bfd", "gold", "lld", "mold"]
description: "Allows to specify the linker variant. Maps to gcc's and clang's -fuse-ld "
+ "option."
}
@@ -189,10 +182,9 @@ CppModule {
property string toolchainPathPrefix: Gcc.pathPrefix(toolchainInstallPath, toolchainPrefix)
property string binutilsPathPrefix: Gcc.pathPrefix(binutilsPath, toolchainPrefix)
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
- property string cCompilerName: (qbs.toolchain.contains("clang") ? "clang" : "gcc")
+ property string cCompilerName: (qbs.toolchain.includes("clang") ? "clang" : "gcc")
+ compilerExtension
- property string cxxCompilerName: (qbs.toolchain.contains("clang") ? "clang++" : "g++")
+ property string cxxCompilerName: (qbs.toolchain.includes("clang") ? "clang++" : "g++")
+ compilerExtension
compilerPathByLanguage: ({
@@ -216,13 +208,22 @@ CppModule {
property stringList dsymutilFlags
property bool alwaysUseLipo: false
- property string includeFlag: "-I"
- property string systemIncludeFlag: "-isystem"
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-isystem"
+ preincludeFlag: "-include"
+ libraryPathFlag: "-L"
+ linkerScriptFlag: "-T"
readonly property bool shouldCreateSymlinks: {
- return createSymlinks && internalVersion && ["macho", "elf"].contains(cpp.imageFormat);
+ return createSymlinks && internalVersion && ["macho", "elf"].includes(imageFormat);
}
+ readonly property bool shouldSignArtifacts: codesign._canSignArtifacts
+ && codesign.enableCodeSigning
+ // codesigning is done during the lipo step
+ && !product.multiplexed
+
property string internalVersion: {
if (product.version === undefined)
return undefined;
@@ -250,18 +251,18 @@ CppModule {
property var buildEnv: {
var env = {};
- if (qbs.toolchain.contains("mingw"))
- env.PATH = [toolchainInstallPath]; // For libwinpthread etc
+ if (qbs.toolchain.includes("mingw"))
+ env.PATH = toolchainInstallPath; // For libwinpthread etc
return env;
}
exceptionHandlingModel: {
- if (qbs.toolchain.contains("mingw")) {
+ if (qbs.toolchain.includes("mingw")) {
// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html claims
// __USING_SJLJ_EXCEPTIONS__ is defined as 1 when using SJLJ exceptions, but there don't
// seem to be defines for the other models, so use the presence of the DLLs for now.
var prefix = toolchainInstallPath;
- if (!qbs.hostOS.contains("windows"))
+ if (!Host.os().includes("windows"))
prefix = FileInfo.joinPaths(toolchainInstallPath, "..", "lib", "gcc",
toolchainPrefix,
[compilerVersionMajor, compilerVersionMinor].join("."));
@@ -313,7 +314,7 @@ CppModule {
if (gccProbe.targetPlatform) {
// Can't differentiate Darwin OSes at the compiler level alone
if (gccProbe.targetPlatform === "darwin"
- ? !qbs.targetOS.contains("darwin")
+ ? !qbs.targetOS.includes("darwin")
: qbs.targetPlatform !== gccProbe.targetPlatform)
isWrongTriple = true;
} else if (qbs.targetPlatform) {
@@ -350,7 +351,7 @@ CppModule {
var validateFlagsFunction = function (value) {
if (value) {
for (var i = 0; i < value.length; ++i) {
- if (["-target", "-triple", "-arch"].contains(value[i]))
+ if (["-target", "-triple", "-arch"].includes(value[i]))
return false;
}
}
@@ -400,28 +401,33 @@ CppModule {
condition: product.cpp.shouldLink
multiplex: true
inputs: {
- var tags = ["obj", "linkerscript", "versionscript"];
+ var tags = ["obj", "res", "linkerscript", "versionscript"];
if (product.bundle && product.bundle.embedInfoPlist
- && product.qbs.targetOS.contains("darwin")) {
+ && product.qbs.targetOS.includes("darwin")) {
tags.push("aggregate_infoplist");
}
return tags;
}
inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary", "dynamiclibrary_import"]
- outputFileTags: [
- "bundle.input",
- "dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll",
- "debuginfo_bundle","dynamiclibrary_import", "debuginfo_plist",
- ]
+ outputFileTags: {
+ var tags = ["bundle.input", "dynamiclibrary", "dynamiclibrary_symlink",
+ "dynamiclibrary_symbols", "debuginfo_dll", "debuginfo_bundle",
+ "dynamiclibrary_import", "debuginfo_plist"];
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ return tags;
+ }
outputArtifacts: {
var artifacts = [{
- filePath: product.destinationDirectory + "/"
- + PathTools.dynamicLibraryFilePath(product),
- fileTags: ["bundle.input", "dynamiclibrary"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.dynamicLibraryFilePath(product)),
+ fileTags: ["bundle.input", "dynamiclibrary"]
+ .concat(product.cpp.shouldSignArtifacts
+ ? ["codesign.signed_artifact"] : []),
bundle: {
- _bundleFilePath: product.destinationDirectory + "/"
- + PathTools.bundleExecutableFilePath(product)
+ _bundleFilePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.bundleExecutableFilePath(product))
}
}];
if (product.cpp.imageFormat === "pe") {
@@ -445,9 +451,9 @@ CppModule {
var maxVersionParts = product.cpp.internalVersion ? 3 : 1;
for (var i = 0; i < maxVersionParts; ++i) {
var symlink = {
- filePath: product.destinationDirectory + "/"
- + PathTools.dynamicLibraryFilePath(product, undefined, undefined,
- i),
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.dynamicLibraryFilePath(
+ product, undefined, undefined, i)),
fileTags: ["dynamiclibrary_symlink"]
};
if (i > 0 && artifacts[i-1].filePath == symlink.filePath)
@@ -460,16 +466,14 @@ CppModule {
return artifacts;
}
- prepare: {
- return Gcc.prepareLinker.apply(Gcc, arguments);
- }
+ prepare: Gcc.prepareLinker.apply(Gcc, arguments)
}
Rule {
name: "staticLibraryLinker"
condition: product.cpp.shouldLink
multiplex: true
- inputs: ["obj", "linkerscript"]
+ inputs: ["obj", "res", "linkerscript"]
inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
outputFileTags: ["bundle.input", "staticlibrary", "c_staticlibrary", "cpp_staticlibrary"]
@@ -479,9 +483,9 @@ CppModule {
var objCount = objs ? objs.length : 0;
for (var i = 0; i < objCount; ++i) {
var ft = objs[i].fileTags;
- if (ft.contains("c_obj"))
+ if (ft.includes("c_obj"))
tags.push("c_staticlibrary");
- if (ft.contains("cpp_obj"))
+ if (ft.includes("cpp_obj"))
tags.push("cpp_staticlibrary");
}
return [{
@@ -499,6 +503,8 @@ CppModule {
var args = ['rcs', output.filePath];
for (var i in inputs.obj)
args.push(inputs.obj[i].filePath);
+ for (var i in inputs.res)
+ args.push(inputs.res[i].filePath);
var cmd = new Command(product.cpp.archiverPath, args);
cmd.description = 'creating ' + output.fileName;
cmd.highlight = 'linker'
@@ -513,22 +519,29 @@ CppModule {
condition: product.cpp.shouldLink
multiplex: true
inputs: {
- var tags = ["obj", "linkerscript"];
+ var tags = ["obj", "res", "linkerscript"];
if (product.bundle && product.bundle.embedInfoPlist
- && product.qbs.targetOS.contains("darwin")) {
+ && product.qbs.targetOS.includes("darwin")) {
tags.push("aggregate_infoplist");
}
return tags;
}
inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
- outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule",
- "debuginfo_bundle","debuginfo_plist"]
+ outputFileTags: {
+ var tags = ["bundle.input", "loadablemodule", "debuginfo_loadablemodule",
+ "debuginfo_bundle", "debuginfo_plist"];
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ return tags;
+ }
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.loadableModuleFilePath(product)),
- fileTags: ["bundle.input", "loadablemodule"],
+ fileTags: ["bundle.input", "loadablemodule"]
+ .concat(product.cpp.shouldSignArtifacts
+ ? ["codesign.signed_artifact"] : []),
bundle: {
_bundleFilePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.bundleExecutableFilePath(product))
@@ -541,9 +554,7 @@ CppModule {
return artifacts;
}
- prepare: {
- return Gcc.prepareLinker.apply(Gcc, arguments);
- }
+ prepare: Gcc.prepareLinker.apply(Gcc, arguments)
}
Rule {
@@ -551,22 +562,30 @@ CppModule {
condition: product.cpp.shouldLink
multiplex: true
inputs: {
- var tags = ["obj", "linkerscript"];
+ var tags = ["obj", "res", "linkerscript"];
if (product.bundle && product.bundle.embedInfoPlist
- && product.qbs.targetOS.contains("darwin")) {
+ && product.qbs.targetOS.includes("darwin")) {
tags.push("aggregate_infoplist");
}
return tags;
}
inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
- outputFileTags: ["bundle.input", "application", "debuginfo_app","debuginfo_bundle",
- "debuginfo_plist", "mem_map"]
+ outputFileTags: {
+ var tags = ["bundle.input", "application", "debuginfo_app", "debuginfo_bundle",
+ "debuginfo_plist"];
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ if (generateLinkerMapFile)
+ tags.push("mem_map");
+ return tags;
+ }
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.applicationFilePath(product)),
- fileTags: ["bundle.input", "application"],
+ fileTags: ["bundle.input", "application"].concat(
+ product.cpp.shouldSignArtifacts ? ["codesign.signed_artifact"] : []),
bundle: {
_bundleFilePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.bundleExecutableFilePath(product))
@@ -578,16 +597,14 @@ CppModule {
if (product.cpp.generateLinkerMapFile) {
artifacts.push({
filePath: FileInfo.joinPaths(product.destinationDirectory,
- product.targetName + ".map"),
+ product.targetName + product.cpp.linkerMapSuffix),
fileTags: ["mem_map"]
});
}
return artifacts;
}
- prepare: {
- return Gcc.prepareLinker.apply(Gcc, arguments);
- }
+ prepare: Gcc.prepareLinker.apply(Gcc, arguments)
}
Rule {
@@ -595,94 +612,53 @@ CppModule {
inputs: ["cpp", "c", "objcpp", "objc", "asm_cpp"]
auxiliaryInputs: ["hpp"]
explicitlyDependsOn: ["c_pch", "cpp_pch", "objc_pch", "objcpp_pch"]
-
- outputFileTags: ["obj", "c_obj", "cpp_obj", "intermediate_obj"]
- outputArtifacts: {
- var tags;
- if (input.fileTags.contains("cpp_intermediate_object"))
- tags = ["intermediate_obj"];
- else
- tags = ["obj"];
- if (inputs.c || inputs.objc)
- tags.push("c_obj");
- if (inputs.cpp || inputs.objcpp)
- tags.push("cpp_obj");
- return [{
- fileTags: tags,
- filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
- input.fileName + ".o")
- }];
- }
-
- prepare: {
- return Gcc.prepareCompiler.apply(Gcc, arguments);
- }
+ outputFileTags: Cpp.compilerOutputTags(false).concat(["c_obj", "cpp_obj"])
+ outputArtifacts: Cpp.compilerOutputArtifacts(input, inputs)
+ prepare: Gcc.prepareCompiler.apply(Gcc, arguments)
}
Rule {
name: "assembler"
inputs: ["asm"]
-
- Artifact {
- fileTags: ["obj"]
- filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir), input.fileName + ".o")
- }
-
- prepare: {
- return Gcc.prepareAssembler.apply(Gcc, arguments);
- }
+ outputFileTags: Cpp.assemblerOutputTags(false)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
+ prepare: Gcc.prepareAssembler.apply(Gcc, arguments)
}
Rule {
condition: useCPrecompiledHeader
inputs: ["c_pch_src"]
auxiliaryInputs: ["hpp"]
- Artifact {
- filePath: product.name + "_c.gch"
- fileTags: ["c_pch"]
- }
- prepare: {
- return Gcc.prepareCompiler.apply(Gcc, arguments);
- }
+ outputFileTags: Cpp.precompiledHeaderOutputTags("c", false)
+ outputArtifacts: Cpp.precompiledHeaderOutputArtifacts(input, product, "c", false)
+ prepare: Gcc.prepareCompiler.apply(Gcc, arguments)
}
Rule {
condition: useCxxPrecompiledHeader
inputs: ["cpp_pch_src"]
auxiliaryInputs: ["hpp"]
- Artifact {
- filePath: product.name + "_cpp.gch"
- fileTags: ["cpp_pch"]
- }
- prepare: {
- return Gcc.prepareCompiler.apply(Gcc, arguments);
- }
+ outputFileTags: Cpp.precompiledHeaderOutputTags("cpp", false)
+ outputArtifacts: Cpp.precompiledHeaderOutputArtifacts(input, product, "cpp", false)
+ prepare: Gcc.prepareCompiler.apply(Gcc, arguments)
}
Rule {
condition: useObjcPrecompiledHeader
inputs: ["objc_pch_src"]
auxiliaryInputs: ["hpp"]
- Artifact {
- filePath: product.name + "_objc.gch"
- fileTags: ["objc_pch"]
- }
- prepare: {
- return Gcc.prepareCompiler.apply(Gcc, arguments);
- }
+ outputFileTags: Cpp.precompiledHeaderOutputTags("objc", false)
+ outputArtifacts: Cpp.precompiledHeaderOutputArtifacts(input, product, "objc", false)
+ prepare: Gcc.prepareCompiler.apply(Gcc, arguments)
}
Rule {
condition: useObjcxxPrecompiledHeader
inputs: ["objcpp_pch_src"]
auxiliaryInputs: ["hpp"]
- Artifact {
- filePath: product.name + "_objcpp.gch"
- fileTags: ["objcpp_pch"]
- }
- prepare: {
- return Gcc.prepareCompiler.apply(Gcc, arguments);
- }
+ outputFileTags: Cpp.precompiledHeaderOutputTags("objcpp", false)
+ outputArtifacts: Cpp.precompiledHeaderOutputArtifacts(input, product, "objcpp", false)
+ prepare: Gcc.prepareCompiler.apply(Gcc, arguments)
}
FileTagger {
diff --git a/share/qbs/modules/cpp/LinuxGCC.qbs b/share/qbs/modules/cpp/LinuxGCC.qbs
index 14fb0a7e9..4b594a0aa 100644
--- a/share/qbs/modules/cpp/LinuxGCC.qbs
+++ b/share/qbs/modules/cpp/LinuxGCC.qbs
@@ -28,11 +28,12 @@
**
****************************************************************************/
+import qbs.Host
import qbs.Process
UnixGCC {
- condition: qbs.targetOS.contains('linux') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('linux') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
priority: 1
targetVendor: "pc"
@@ -41,7 +42,7 @@ UnixGCC {
Probe {
id: runPathsProbe
- condition: !_skipAllChecks && qbs.targetPlatform === qbs.hostPlatform
+ condition: !_skipAllChecks && qbs.targetPlatform === Host.platform()
property stringList systemRunPaths: []
configure: {
var paths = [];
diff --git a/share/qbs/modules/cpp/MingwBaseModule.qbs b/share/qbs/modules/cpp/MingwBaseModule.qbs
index 60ad28b08..c9cfe9bd8 100644
--- a/share/qbs/modules/cpp/MingwBaseModule.qbs
+++ b/share/qbs/modules/cpp/MingwBaseModule.qbs
@@ -37,8 +37,6 @@ import "setuprunenv.js" as SetupRunEnv
GenericGCC {
condition: false
- staticLibraryPrefix: "lib"
- staticLibrarySuffix: ".a"
dynamicLibrarySuffix: ".dll"
executableSuffix: ".exe"
debugInfoSuffix: ".debug"
@@ -46,9 +44,10 @@ GenericGCC {
windowsApiCharacterSet: "unicode"
platformDefines: base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
.concat("WIN32")
+ runtimeLibrary: "dynamic"
Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
+ condition: product.multiplexByQbsProperties.includes("buildVariants")
&& qbs.buildVariants && qbs.buildVariants.length > 1
&& qbs.buildVariant !== "release"
&& product.type.containsAny(["staticlibrary", "dynamiclibrary"])
@@ -97,9 +96,9 @@ GenericGCC {
var tf;
try {
tf = new TextFile(outputFilePath, TextFile.WriteOnly);
- if (productType.contains("application"))
+ if (productType.includes("application"))
tf.write("1 "); // CREATEPROCESS_MANIFEST_RESOURCE_ID
- else if (productType.contains("dynamiclibrary"))
+ else if (productType.includes("dynamiclibrary"))
tf.write("2 "); // ISOLATIONAWARE_MANIFEST_RESOURCE_ID
tf.write("24 "); // RT_MANIFEST
tf.writeLine(Utilities.cStringQuote(inputFilePath));
diff --git a/share/qbs/modules/cpp/UnixGCC.qbs b/share/qbs/modules/cpp/UnixGCC.qbs
index e5b99cd98..6f377c5c8 100644
--- a/share/qbs/modules/cpp/UnixGCC.qbs
+++ b/share/qbs/modules/cpp/UnixGCC.qbs
@@ -31,14 +31,12 @@
import qbs.File
GenericGCC {
- condition: qbs.toolchain && qbs.toolchain.contains("gcc")
- && qbs.targetOS && qbs.targetOS.contains("unix")
+ condition: qbs.toolchain && qbs.toolchain.includes("gcc")
+ && qbs.targetOS.includes("unix")
priority: -50
- staticLibraryPrefix: "lib"
dynamicLibraryPrefix: "lib"
loadableModulePrefix: "lib"
- staticLibrarySuffix: ".a"
dynamicLibrarySuffix: ".so"
debugInfoSuffix: ".debug"
imageFormat: "elf"
diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs
index 3e44f4ff3..7c45d3c6b 100644
--- a/share/qbs/modules/cpp/android-gcc.qbs
+++ b/share/qbs/modules/cpp/android-gcc.qbs
@@ -39,25 +39,36 @@ import 'gcc.js' as Gcc
LinuxGCC {
Depends { name: "Android.ndk" }
- condition: qbs.targetOS.contains("android") && qbs.toolchain && qbs.toolchain.contains("llvm")
+ condition: qbs.targetOS.includes("android") && qbs.toolchain && qbs.toolchain.includes("llvm")
priority: 2
- rpaths: [rpathOrigin]
+ rpaths: []
+ // toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android
cxxLanguageVersion: "c++14"
- property string cxxStlBaseDir: FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "cxx-stl")
- property string stlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "llvm-libc++")
- property string stlLibsDir: {
- if (stlBaseDir)
- return FileInfo.joinPaths(stlBaseDir, "libs", Android.ndk.abi);
- return undefined;
+ property string archLibsDir: {
+ switch (qbs.architecture) {
+ case "arm64":
+ return "aarch64";
+ case "armv7a":
+ return "arm";
+ case "x86_64":
+ return qbs.architecture;
+ case "x86":
+ return "i686";
+ }
}
+ property string targetDir: "android" + (["armeabi", "armeabi-v7a"].includes(Android.ndk.abi) ? "eabi" : "")
+ property string triple: [archLibsDir, targetSystem, targetDir].join("-")
+ property string libsDir: FileInfo.joinPaths(sysroot, "usr", "lib", triple);
- property string sharedStlFilePath: (stlLibsDir && Android.ndk.appStl.endsWith("_shared"))
- ? FileInfo.joinPaths(stlLibsDir, dynamicLibraryPrefix + Android.ndk.appStl + dynamicLibrarySuffix)
+ property string sharedStlFilePath: (libsDir && Android.ndk.appStl.endsWith("_shared"))
+ ? FileInfo.joinPaths(libsDir, dynamicLibraryPrefix + Android.ndk.appStl + dynamicLibrarySuffix)
: undefined
- property string staticStlFilePath: (stlLibsDir && Android.ndk.appStl.endsWith("_static"))
- ? FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(staticLibraryPrefix, Android.ndk, staticLibrarySuffix))
+ property string staticStlFilePath: (libsDir && Android.ndk.appStl.endsWith("_static"))
+ ? FileInfo.joinPaths(libsDir, Android.ndk.platformVersion,
+ NdkUtils.stlFileName(staticLibraryPrefix, Android.ndk,
+ staticLibrarySuffix))
: undefined
Group {
@@ -67,15 +78,6 @@ LinuxGCC {
fileTags: "android.stl"
}
- Group {
- name: "gdbserver"
- condition: qbs.buildVariant !== "release" && product.cpp.shouldLink
- files: FileInfo.joinPaths(Android.ndk.ndkDir, "prebuilt",
- "android-" + NdkUtils.abiNameToDirName(Android.ndk.abi),
- "gdbserver", "gdbserver")
- fileTags: "android.gdbserver"
- }
-
toolchainInstallPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains",
"llvm", "prebuilt",
Android.ndk.hostArch, "bin")
@@ -83,11 +85,10 @@ LinuxGCC {
property string toolchainTriple: [targetAbi === "androideabi" ? "arm" : targetArch,
targetSystem, targetAbi].join("-")
+ internalVersion: undefined
toolchainPrefix: undefined
machineType: {
- if (Android.ndk.abi === "armeabi")
- return "armv5te";
if (Android.ndk.abi === "armeabi-v7a")
return "armv7-a";
}
@@ -99,59 +100,43 @@ LinuxGCC {
commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.toolchain, qbs.buildVariant, Android.ndk)
- linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi);
+ linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk);
driverLinkerFlags: {
- var flags = ["-fuse-ld=lld", "-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a", "-nostdlib++"];
- if (Android.ndk.appStl.startsWith("c++") && Android.ndk.abi === "armeabi-v7a")
- flags = flags.concat(["-Wl,--exclude-libs,libunwind.a"]);
+ var flags = ["-fuse-ld=lld", "-Wl,--exclude-libs,libgcc.a", "-nostdlib++"];
+ // See https://android.googlesource.com/platform/ndk/+/ndk-release-r21/docs/BuildSystemMaintainers.md#Unwinding
+ if (Android.ndk.abi === "armeabi-v7a") {
+ flags = flags.concat(["-Wl,--exclude-libs,libgcc_real.a"]);
+ if (Android.ndk.appStl.startsWith("c++"))
+ flags = flags.concat(["-Wl,--exclude-libs,libunwind.a"]);
+ }
return flags;
}
platformDriverFlags: ["-fdata-sections", "-ffunction-sections", "-funwind-tables",
"-fstack-protector-strong", "-no-canonical-prefixes"]
- libraryPaths: {
- var prefix = FileInfo.joinPaths(sysroot, "usr");
- var paths = [];
- if (Android.ndk.abi === "x86_64") // no lib64 for arm64-v8a
- paths.push(FileInfo.joinPaths(prefix, "lib64"));
- paths.push(FileInfo.joinPaths(prefix, "lib"));
- paths.push(stlLibsDir);
- return paths;
- }
-
dynamicLibraries: {
var libs = ["c", "m"];
if (sharedStlFilePath)
- libs.push(FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(dynamicLibraryPrefix, Android.ndk, dynamicLibrarySuffix)));
+ libs.push(FileInfo.joinPaths(libsDir, Android.ndk.platformVersion,
+ NdkUtils.stlFileName(dynamicLibraryPrefix, Android.ndk,
+ dynamicLibrarySuffix)));
return libs;
}
staticLibraries: staticStlFilePath
- systemIncludePaths: {
- var includes = [FileInfo.joinPaths(sysroot, "usr", "include", toolchainTriple)];
- if (Android.ndk.abi === "armeabi-v7a") {
- includes.push(FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "android",
- "support", "include"));
- }
- includes.push(FileInfo.joinPaths(stlBaseDir, "include"));
- includes.push(FileInfo.joinPaths(stlBaseDir + "abi", "include"));
- return includes;
- }
- defines: {
- var list = ["ANDROID"];
- // Might be superseded by an -mandroid-version or similar Clang compiler flag in future
- list.push("__ANDROID_API__=" + Android.ndk.platformVersion);
- return list;
- }
+ // When using ndk r19c, llvm doesn't add sysroot/usr/include/c++/v1 to the path
+ // But it works starting with ndk r20b
+ systemIncludePaths: (Utilities.versionCompare(Android.ndk.version, "20") < 0) ?
+ FileInfo.joinPaths(sysroot, "usr", "include", "c++", "v1") : []
+
+ defines: ["ANDROID", "__ANDROID__"]
binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", "llvm", "prebuilt",
Android.ndk.hostArch, "bin");
binutilsPathPrefix: FileInfo.joinPaths(binutilsPath, "llvm-")
- syslibroot: FileInfo.joinPaths(Android.ndk.ndkDir, "platforms",
- Android.ndk.platform, "arch-"
- + NdkUtils.abiNameToDirName(Android.ndk.abi))
- sysroot: FileInfo.joinPaths(Android.ndk.ndkDir, "sysroot")
+ sysroot: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", "llvm", "prebuilt",
+ Android.ndk.hostArch, "sysroot")
targetArch: {
switch (qbs.architecture) {
@@ -168,9 +153,10 @@ LinuxGCC {
}
}
- targetVendor: "none"
+ target: [targetArch, targetSystem, targetAbi].join("-")
targetSystem: "linux"
- targetAbi: "android" + (["armeabi", "armeabi-v7a"].contains(Android.ndk.abi) ? "eabi" : "")
+ targetAbi: "android" + (["armeabi", "armeabi-v7a"].includes(Android.ndk.abi) ? "eabi" : "") +
+ Android.ndk.platformVersion
endianness: "little"
@@ -182,9 +168,9 @@ LinuxGCC {
fileTags: "android.nativelibrary"
}
prepare: {
- var stripArgs = ["--strip-unneeded", "-o", output.filePath, input.filePath];
+ var stripArgs = ["--strip-all", "-o", output.filePath, input.filePath];
var stripCmd = new Command(product.cpp.stripPath, stripArgs);
- stripCmd.description = "Stripping unneeded symbols from " + input.fileName;
+ stripCmd.description = "stripping unneeded symbols from " + input.fileName;
return stripCmd;
}
}
diff --git a/share/qbs/modules/cpp/cosmic.js b/share/qbs/modules/cpp/cosmic.js
new file mode 100644
index 000000000..4979f33f7
--- /dev/null
+++ b/share/qbs/modules/cpp/cosmic.js
@@ -0,0 +1,443 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** 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.
+**
+****************************************************************************/
+
+var Cpp = require("cpp.js");
+var Environment = require("qbs.Environment");
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+var Process = require("qbs.Process");
+var TemporaryDir = require("qbs.TemporaryDir");
+var TextFile = require("qbs.TextFile");
+
+function toolchainDetails(qbs) {
+ var architecture = qbs.architecture;
+ if (architecture.startsWith("arm")) {
+ return {
+ "executableSuffix": ".cxm",
+ "staticLibrarySuffix": ".cxm",
+ "assemblerName": "cacorm",
+ "compilerName": "cxcorm"
+ };
+ } else if (architecture === "stm8") {
+ return {
+ "executableSuffix": ".sm8",
+ "staticLibrarySuffix": ".sm8",
+ "assemblerName": "castm8",
+ "compilerName": "cxstm8"
+ };
+ } else if (architecture === "hcs8") {
+ return {
+ "executableSuffix": ".h08",
+ "staticLibrarySuffix": ".h08",
+ "assemblerName": "ca6808",
+ "compilerName": "cx6808"
+ };
+ } else if (architecture === "hcs12") {
+ return {
+ "executableSuffix": ".h12",
+ "staticLibrarySuffix": ".h12",
+ "assemblerName": "ca6812",
+ "compilerName": "cx6812"
+ };
+ } else if (architecture === "m68k") {
+ return {
+ "executableSuffix": ".332",
+ "staticLibrarySuffix": ".332",
+ "assemblerName": "ca332",
+ "compilerName": "cx332"
+ };
+ }
+}
+
+function guessArchitecture(compilerFilePath) {
+ var baseName = FileInfo.baseName(compilerFilePath);
+ if (baseName === "cxcorm")
+ return "arm";
+ else if (baseName === "cxstm8")
+ return "stm8";
+ else if (baseName === "cx6808")
+ return "hcs8";
+ else if (baseName === "cx6812")
+ return "hcs12";
+ else if (baseName === "cx332")
+ return "m68k";
+}
+
+function dumpMacros(compilerFilePath) {
+ // Note: The COSMIC compiler does not support the predefined
+ // macros dumping. So, we do it with the following trick, where we try
+ // to create and compile a special temporary file and to parse the console
+ // output with the own magic pattern: (""|"key"|"value"|"").
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.fromNativeSeparators(FileInfo.joinPaths(outputDirectory.path(),
+ "dump-macros.c"));
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+ outputFile.writeLine("#define VALUE_TO_STRING(x) #x");
+ outputFile.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
+ outputFile.writeLine("#define VAR_NAME_VALUE(var) #var VALUE(var)");
+ // The COSMIC compiler defines only one pre-defined macro
+ // (at least nothing is said about other macros in the documentation).
+ var keys = ["__CSMC__"];
+ for (var i in keys) {
+ var key = keys[i];
+ outputFile.writeLine("#if defined (" + key + ")");
+ outputFile.writeLine("#pragma message (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("#endif");
+ }
+ outputFile.close();
+
+ var process = new Process();
+ process.exec(compilerFilePath, [outputFilePath], false);
+ File.remove(outputFilePath);
+
+ var map = {};
+ // COSMIC compiler use the errors output!
+ process.readStdErr().trim().split(/\r?\n/g).map(function(line) {
+ var match = line.match(/^#message \("(.+)" "(.+)"\)$/);
+ if (match)
+ map[match[1]] = match[2];
+ });
+ return map;
+}
+
+function dumpVersion(compilerFilePath) {
+ var p = new Process();
+ p.exec(compilerFilePath, ["-vers"]);
+ // COSMIC compiler use the errors output!
+ var output = p.readStdErr();
+ var match = output.match(/^COSMIC.+V(\d+)\.?(\d+)\.?(\*|\d+)?/);
+ if (match) {
+ var major = match[1] ? parseInt(match[1], 10) : 0;
+ var minor = match[2] ? parseInt(match[2], 10) : 0;
+ var patch = match[3] ? parseInt(match[3], 10) : 0;
+ return { major: major, minor: minor, patch: patch };
+ }
+}
+
+function guessEndianness(architecture) {
+ // There is no mention of supported endianness in the cosmic compiler.
+ return "big";
+}
+
+function dumpDefaultPaths(compilerFilePath, architecture) {
+ var rootPath = FileInfo.path(compilerFilePath);
+ var includePath;
+ var includePaths = [];
+ if (architecture.startsWith("arm")) {
+ includePath = FileInfo.joinPaths(rootPath, "hcorm");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "stm8") {
+ includePath = FileInfo.joinPaths(rootPath, "hstm8");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "hcs8") {
+ includePath = FileInfo.joinPaths(rootPath, "h6808");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "hcs12") {
+ includePath = FileInfo.joinPaths(rootPath, "h6812");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ } else if (architecture === "m68k") {
+ includePath = FileInfo.joinPaths(rootPath, "h332");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
+ }
+
+ var libraryPaths = [];
+ var libraryPath = FileInfo.joinPaths(rootPath, "lib");
+ if (File.exists(libraryPath))
+ libraryPaths.push(libraryPath);
+
+ return {
+ "includePaths": includePaths,
+ "libraryPaths": libraryPaths,
+ }
+}
+
+function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = [];
+
+ // Up to 128 include files.
+ args = args.concat(Cpp.collectPreincludePathsArguments(input));
+
+ // Defines.
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ // Up to 128 include paths.
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("+debug");
+
+ var architecture = input.qbs.architecture;
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
+ // Disabled by default.
+ break;
+ case "all":
+ // Highest warning level.
+ args.push("-pw7");
+ break;
+ }
+
+ // C language version flags.
+ if (tag === "c") {
+ var knownValues = ["c99"];
+ var cLanguageVersion = Cpp.languageVersion(
+ input.cpp.cLanguageVersion, knownValues, "C");
+ switch (cLanguageVersion) {
+ case "c99":
+ args.push("-p", "c99");
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Objects output directory.
+ args.push("-co", FileInfo.path(outputs.obj[0].filePath));
+
+ // Listing files generation flag.
+ if (input.cpp.generateCompilerListingFiles) {
+ // Enable listings.
+ args.push("-l");
+ // Listings output directory.
+ args.push("-cl", FileInfo.path(outputs.lst[0].filePath));
+ }
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(product));
+
+ // Input.
+ args.push(input.filePath);
+ return args;
+}
+
+function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = [];
+
+ // Up to 128 include paths.
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("-xx");
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+
+ // Listing files generation flag.
+ if (input.cpp.generateAssemblerListingFiles) {
+ args.push("-l");
+ args.push("+l", outputs.lst[0].filePath);
+ }
+
+ // Objects output file path.
+ args.push("-o", outputs.obj[0].filePath);
+
+ // Input.
+ args.push(input.filePath);
+ return args;
+}
+
+function linkerFlags(project, product, inputs, outputs) {
+ var args = [];
+
+ // Library paths.
+ args = args.concat(Cpp.collectLibraryPaths(product).map(function(path) {
+ // It is workaround to use the relative paths avoids a strange linking
+ // errors. Maybe it is related to the limitations on the length of the
+ // command arguments, or on the length of the paths.
+ return product.cpp.libraryPathFlag + Cpp.relativePath(product.buildDirectory, path);
+ }));
+
+ // Output.
+ args.push("-o", outputs.application[0].filePath);
+
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
+ args.push("-m", outputs.mem_map[0].filePath);
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+
+ // Linker scripts.
+ args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
+
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
+
+ // Library dependencies (order has matters).
+ args = args.concat(Cpp.collectLibraryDependencies(product).map(function(dep) {
+ // It is workaround to use the relative paths avoids a strange linking
+ // errors. Maybe it is related to the limitations on the length of the
+ // command arguments, or on the length of the paths.
+ return Cpp.relativePath(product.buildDirectory, dep.filePath);
+ }));
+
+ return args;
+}
+
+function archiverFlags(project, product, inputs, outputs) {
+ var args = ["-cl"];
+
+ // Output.
+ args.push(outputs.staticlibrary[0].filePath);
+
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
+ return args;
+}
+
+function createPath(fullPath) {
+ var cmd = new JavaScriptCommand();
+ cmd.fullPath = fullPath;
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ File.makePath(fullPath);
+ };
+ return cmd;
+}
+
+// It is a workaround to rename the generated object file to the desired name.
+// Reason is that the Cosmic compiler always generates the object files in the
+// format of 'module.o', but we expect it in flexible format, e.g. 'module.c.obj'
+// or 'module.c.o' depending on the cpp.objectSuffix property.
+function renameObjectFile(project, product, inputs, outputs, input, output) {
+ var object = outputs.obj[0];
+ var cmd = new JavaScriptCommand();
+ cmd.newObject = object.filePath;
+ cmd.oldObject = FileInfo.joinPaths(FileInfo.path(object.filePath),
+ object.baseName + ".o");
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.move(oldObject, newObject); };
+ return cmd;
+}
+
+// It is a workaround to rename the generated listing file to the desired name.
+// Reason is that the Cosmic compiler always generates the listing files in the
+// format of 'module.ls', but we expect it in flexible format, e.g. 'module.c.lst'
+// or 'module.c.ls' depending on the cpp.compilerListingSuffix property.
+function renameListingFile(project, product, inputs, outputs, input, output) {
+ var listing = outputs.lst[0];
+ var cmd = new JavaScriptCommand();
+ cmd.newListing = listing.filePath;
+ cmd.oldListing = FileInfo.joinPaths(FileInfo.path(listing.filePath),
+ listing.baseName + ".ls");
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.move(oldListing, newListing); };
+ return cmd;
+}
+
+function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+
+ // Create output objects path, because the Cosmic doesn't do it.
+ var cmd = createPath(FileInfo.path(outputs.obj[0].filePath));
+ cmds.push(cmd);
+
+ // Create output listing path, because the Cosmic doesn't do it.
+ if (input.cpp.generateCompilerListingFiles) {
+ cmd = createPath(FileInfo.path(outputs.lst[0].filePath));
+ cmds.push(cmd);
+ }
+
+ var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
+ cmd = new Command(input.cpp.compilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
+ cmds.push(cmd);
+
+ cmds.push(renameObjectFile(project, product, inputs, outputs, input, output));
+
+ if (input.cpp.generateCompilerListingFiles)
+ cmds.push(renameListingFile(project, product, inputs, outputs, input, output));
+
+ return cmds;
+}
+
+function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+
+ // Create output objects path, because the Cosmic doesn't do it.
+ var cmd = createPath(FileInfo.path(outputs.obj[0].filePath));
+ cmds.push(cmd);
+
+ // Create output listing path, because the Cosmic doesn't do it.
+ if (input.cpp.generateCompilerListingFiles) {
+ cmd = createPath(FileInfo.path(outputs.lst[0].filePath));
+ cmds.push(cmd);
+ }
+
+ var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn);
+ cmd = new Command(input.cpp.assemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "assembling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
+ cmds.push(cmd);
+ return cmds;
+}
+
+function prepareLinker(project, product, inputs, outputs, input, output) {
+ var primaryOutput = outputs.application[0];
+ var args = linkerFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.linkerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + primaryOutput.fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "linker";
+ return [cmd];
+}
+
+function prepareArchiver(project, product, inputs, outputs, input, output) {
+ var args = archiverFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.archiverPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "creating " + output.fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "linker";
+ return [cmd];
+}
diff --git a/share/qbs/modules/cpp/cosmic.qbs b/share/qbs/modules/cpp/cosmic.qbs
new file mode 100644
index 000000000..8bf0f22a3
--- /dev/null
+++ b/share/qbs/modules/cpp/cosmic.qbs
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** 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.PathTools
+import qbs.Probes
+import qbs.Utilities
+import "cosmic.js" as COSMIC
+import "cpp.js" as Cpp
+
+CppModule {
+ condition: qbs.toolchain && qbs.toolchain.includes("cosmic")
+
+ Probes.BinaryProbe {
+ id: compilerPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["cxcorm"]
+ }
+
+ Probes.CosmicProbe {
+ id: cosmicProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ }
+
+ qbs.architecture: cosmicProbe.found ? cosmicProbe.architecture : original
+ qbs.targetPlatform: "none"
+
+ compilerVersionMajor: cosmicProbe.versionMajor
+ compilerVersionMinor: cosmicProbe.versionMinor
+ compilerVersionPatch: cosmicProbe.versionPatch
+ endianness: cosmicProbe.endianness
+
+ compilerDefinesByLanguage: cosmicProbe.compilerDefinesByLanguage
+ compilerIncludePaths: cosmicProbe.includePaths
+
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
+
+ /* Work-around for QtCreator which expects these properties to exist. */
+ property string cCompilerName: compilerName
+ property string cxxCompilerName: compilerName
+
+ compilerName: toolchainDetails.compilerName + compilerExtension
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
+ assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
+
+ linkerName: "clnk" + compilerExtension
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ property string archiverName: "clib" + compilerExtension
+ property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
+
+ runtimeLibrary: "static"
+
+ staticLibrarySuffix: toolchainDetails.staticLibrarySuffix
+ executableSuffix: toolchainDetails.executableSuffix
+
+ imageFormat: "cosmic"
+
+ enableExceptions: false
+ enableRtti: false
+
+ defineFlag: "-d"
+ includeFlag: "-i"
+ systemIncludeFlag: "-i"
+ preincludeFlag: "-ph"
+ libraryDependencyFlag: ""
+ libraryPathFlag: "-l"
+ linkerScriptFlag: ""
+
+ toolchainDetails: COSMIC.toolchainDetails(qbs)
+
+ knownArchitectures: ["arm", "hcs12", "hcs8", "m68k", "stm8"]
+
+ Rule {
+ id: assembler
+ inputs: ["asm"]
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
+ prepare: COSMIC.prepareAssembler.apply(COSMIC, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.s"]
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ id: compiler
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
+ prepare: COSMIC.prepareCompiler.apply(COSMIC, arguments)
+ }
+
+ Rule {
+ id: applicationLinker
+ multiplex: true
+ inputs: ["obj", "linkerscript"]
+ inputsFromDependencies: ["staticlibrary"]
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
+ prepare: COSMIC.prepareLinker.apply(COSMIC, arguments)
+ }
+
+ Rule {
+ id: staticLibraryLinker
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary"]
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
+ prepare: COSMIC.prepareArchiver.apply(COSMIC, arguments)
+ }
+}
diff --git a/share/qbs/modules/cpp/cpp.js b/share/qbs/modules/cpp/cpp.js
index 0e440bdb0..9f907580a 100644
--- a/share/qbs/modules/cpp/cpp.js
+++ b/share/qbs/modules/cpp/cpp.js
@@ -28,6 +28,12 @@
**
****************************************************************************/
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+var PathTools = require("qbs.PathTools");
+var Utilities = require("qbs.Utilities");
+
function languageVersion(versionArray, knownValues, lang) {
if (!versionArray)
return undefined;
@@ -36,7 +42,7 @@ function languageVersion(versionArray, knownValues, lang) {
return versions[0];
for (var i = 0; i < knownValues.length; ++i) {
var candidate = knownValues[i];
- if (versions.contains(candidate))
+ if (versions.includes(candidate))
return candidate;
}
var version = versions[0];
@@ -44,3 +50,426 @@ function languageVersion(versionArray, knownValues, lang) {
+ "' from list of unknown " + lang + " version strings (" + versions + ")");
return version;
}
+
+function extractMacros(output, regexp) {
+ var m = {};
+ output.trim().split(/\r?\n/g).map(function(line) {
+ if (regexp) {
+ var match = regexp.exec(line);
+ if (!match)
+ return;
+ line = match[1];
+ }
+ var prefix = "#define ";
+ if (!line.startsWith(prefix))
+ return;
+ var index = line.indexOf(" ", prefix.length);
+ if (index !== -1)
+ m[line.substr(prefix.length, index - prefix.length)] = line.substr(index + 1);
+ });
+ return m;
+}
+
+function relativePath(baseDirectory, filePath) {
+ if (FileInfo.isAbsolutePath(filePath))
+ return FileInfo.relativePath(baseDirectory, filePath);
+ return filePath;
+}
+
+function assemblerOutputTags(needsListingFiles) {
+ var tags = ["obj"];
+ if (needsListingFiles)
+ tags.push("lst");
+ return tags;
+}
+
+function compilerOutputTags(needsListingFiles) {
+ var tags = ["obj", "intermediate_obj"];
+ if (needsListingFiles)
+ tags.push("lst");
+ return tags;
+}
+
+function applicationLinkerOutputTags(needsLinkerMapFile) {
+ var tags = ["application"];
+ if (needsLinkerMapFile)
+ tags.push("mem_map");
+ return tags;
+}
+
+function dynamicLibraryLinkerOutputTags() {
+ return ["dynamiclibrary", "dynamiclibrary_import"];
+}
+
+function staticLibraryLinkerOutputTags() {
+ return ["staticlibrary"];
+}
+
+function resourceCompilerOutputTags() {
+ return ["res"];
+}
+
+function precompiledHeaderOutputTags(lang, generateObjects) {
+ var tags = [lang + "_pch"];
+ if (generateObjects)
+ tags.push("obj");
+ return tags;
+};
+
+function assemblerOutputArtifacts(input) {
+ var artifacts = [];
+ artifacts.push({
+ fileTags: ["obj"],
+ filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
+ input.fileName + input.cpp.objectSuffix)
+ });
+ if (input.cpp.generateAssemblerListingFiles) {
+ artifacts.push({
+ fileTags: ["lst"],
+ filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
+ input.fileName + input.cpp.assemblerListingSuffix)
+ });
+ }
+ return artifacts;
+}
+
+function compilerOutputArtifacts(input, inputs) {
+ var objTags = input.fileTags.includes("cpp_intermediate_object")
+ ? ["intermediate_obj"]
+ : ["obj"];
+ if (inputs) {
+ if (inputs.c || inputs.objc)
+ objTags.push("c_obj");
+ if (inputs.cpp || inputs.objcpp)
+ objTags.push("cpp_obj");
+ }
+ var artifacts = [{
+ fileTags: objTags,
+ filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
+ input.fileName + input.cpp.objectSuffix)
+ }];
+ if (input.cpp.generateCompilerListingFiles) {
+ artifacts.push({
+ fileTags: ["lst"],
+ filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
+ input.fileName + input.cpp.compilerListingSuffix)
+ });
+ }
+ return artifacts;
+}
+
+function applicationLinkerOutputArtifacts(product) {
+ var artifacts = [{
+ fileTags: ["application"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.applicationFilePath(product))
+ }];
+ if (product.cpp.generateLinkerMapFile) {
+ artifacts.push({
+ fileTags: ["mem_map"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ product.targetName + product.cpp.linkerMapSuffix)
+ });
+ }
+ return artifacts;
+}
+
+function dynamicLibraryLinkerOutputArtifacts(product) {
+ return [{
+ fileTags: ["dynamiclibrary"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.dynamicLibraryFilePath(product))
+ }, {
+ fileTags: ["dynamiclibrary_import"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.importLibraryFilePath(product)),
+ alwaysUpdated: false
+ }];
+}
+
+function staticLibraryLinkerOutputArtifacts(product) {
+ return [{
+ fileTags: ["staticlibrary"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.staticLibraryFilePath(product))
+ }];
+}
+
+function resourceCompilerOutputArtifacts(input) {
+ return [{
+ fileTags: ["res"],
+ filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
+ input.completeBaseName + input.cpp.resourceSuffix)
+ }];
+}
+
+function precompiledHeaderOutputArtifacts(input, product, lang, generateObjects) {
+ var artifacts = [{
+ fileTags: [lang + "_pch"],
+ filePath: product.name + "_" + lang + product.cpp.precompiledHeaderSuffix
+ }];
+ if (generateObjects) {
+ artifacts.push({
+ fileTags: ["obj"],
+ filePath: Utilities.getHash(input.completeBaseName)
+ + "_" + lang + input.cpp.objectSuffix
+ });
+ }
+ return artifacts;
+}
+
+function collectLibraryDependencies(product) {
+ var seen = {};
+ var seenObjectFiles = [];
+ var result = [];
+
+ function addFilePath(filePath, wholeArchive, productName) {
+ result.push({ filePath: filePath, wholeArchive: wholeArchive, productName: productName });
+ }
+
+ function addArtifactFilePaths(dep, artifacts) {
+ if (!artifacts)
+ return;
+ var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
+ var wholeArchive = dep.parameters.cpp && dep.parameters.cpp.linkWholeArchive;
+ var artifactsAreImportLibs = artifacts.length > 0
+ && artifacts[0].fileTags.includes("dynamiclibrary_import");
+ for (var i = 0; i < artifactFilePaths.length; ++i) {
+ addFilePath(artifactFilePaths[i], wholeArchive,
+ artifactsAreImportLibs ? dep.name : undefined);
+ }
+ }
+
+ function addExternalLibs(obj) {
+ if (!obj.cpp)
+ return;
+ function ensureArray(a) {
+ return (a instanceof Array) ? a : [];
+ }
+ function sanitizedModuleListProperty(obj, moduleName, propertyName) {
+ return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
+ }
+ function handleExternalLibraries(tag, libSuffix, objSuffix) {
+ var externalLibs = sanitizedModuleListProperty(obj, "cpp", tag) || [];
+ externalLibs.forEach(function(libName) {
+ var isObjectFile = objSuffix && libName.endsWith(objSuffix);
+ if (isObjectFile) {
+ if (seenObjectFiles.includes(libName))
+ return;
+ seenObjectFiles.push(libName);
+ }
+ if (!libName.endsWith(libSuffix) && !isObjectFile && !libName.startsWith('@'))
+ libName += libSuffix;
+ addFilePath(libName, false);
+ });
+ }
+ handleExternalLibraries("staticLibraries",
+ obj.moduleProperty("cpp", "staticLibrarySuffix"),
+ obj.moduleProperty("cpp", "objectSuffix"));
+ handleExternalLibraries("dynamicLibraries",
+ obj.moduleProperty("cpp", "dynamicLibraryImportSuffix"));
+ }
+
+ function traverse(dep) {
+ if (seen.hasOwnProperty(dep.name))
+ return;
+ if (dep.parameters.cpp && dep.parameters.cpp.link === false)
+ return;
+
+ var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
+ var dynamicLibraryArtifacts = staticLibraryArtifacts
+ ? null : dep.artifacts["dynamiclibrary_import"];
+ if (staticLibraryArtifacts) {
+ seen[dep.name] = true;
+ dep.dependencies.forEach(traverse);
+ addArtifactFilePaths(dep, staticLibraryArtifacts);
+ addExternalLibs(dep);
+ } else if (dynamicLibraryArtifacts) {
+ seen[dep.name] = true;
+ addArtifactFilePaths(dep, dynamicLibraryArtifacts);
+ }
+ }
+
+ product.dependencies.forEach(traverse);
+ addExternalLibs(product);
+ return result;
+}
+
+function collectAbsoluteLibraryDependencyPaths(product) {
+ var paths = collectLibraryPaths(product);
+ var deps = collectLibraryDependencies(product);
+ return deps.map(function(dep) {
+ var filePath = dep.filePath;
+ if (FileInfo.isAbsolutePath(filePath))
+ return filePath;
+ for (var i = 0; i < paths.length; ++i) {
+ var fullPath = FileInfo.joinPaths(paths[i], filePath);
+ if (File.exists(fullPath))
+ return fullPath;
+ }
+ return filePath;
+ });
+}
+
+function collectDefines(input) {
+ var allDefines = [];
+ var platformDefines = input.cpp.platformDefines;
+ if (platformDefines)
+ allDefines = allDefines.uniqueConcat(platformDefines);
+ var defines = input.cpp.defines;
+ if (defines)
+ allDefines = allDefines.uniqueConcat(defines);
+ return allDefines;
+}
+
+function collectIncludePaths(input) {
+ var allIncludePaths = [];
+ var includePaths = input.cpp.includePaths;
+ if (includePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
+ var builtIns = input.cpp.compilerIncludePaths;
+ return allIncludePaths.filter(function(p) {
+ return !builtIns.includes(p);
+ });
+}
+
+function collectSystemIncludePaths(input) {
+ var allIncludePaths = [];
+ var systemIncludePaths = input.cpp.systemIncludePaths;
+ if (systemIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
+ var distributionIncludePaths = input.cpp.distributionIncludePaths;
+ if (distributionIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
+ var builtIns = input.cpp.compilerIncludePaths;
+ return allIncludePaths.filter(function(p) {
+ return !builtIns.includes(p);
+ });
+}
+
+function collectPreincludePaths(input) {
+ return input.cpp.prefixHeaders;
+}
+
+function collectLibraryPaths(product) {
+ var allLibraryPaths = [];
+ var libraryPaths = product.cpp.libraryPaths;
+ if (libraryPaths)
+ allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
+ var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
+ if (distributionLibraryPaths)
+ allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
+ return allLibraryPaths;
+}
+
+function collectLinkerScriptPaths(inputs) {
+ return inputs.linkerscript
+ ? inputs.linkerscript.map(function(script) { return script.filePath; })
+ : [];
+}
+
+function collectLinkerObjectPaths(inputs) {
+ return inputs.obj ? inputs.obj.map(function(obj) { return obj.filePath; }) : [];
+}
+
+function collectResourceObjectPaths(inputs) {
+ return inputs.res ? inputs.res.map(function(res) { return res.filePath; }) : [];
+}
+
+function collectLibraryDependenciesArguments(product) {
+ var deps = collectLibraryDependencies(product);
+ return deps.map(function(dep) { return product.cpp.libraryDependencyFlag + dep.filePath })
+}
+
+function collectDefinesArguments(input) {
+ var defines = collectDefines(input);
+ return defines.map(function(define) { return input.cpp.defineFlag + define });
+}
+
+function collectIncludePathsArguments(input) {
+ var paths = collectIncludePaths(input);
+ return paths.map(function(path) { return input.cpp.includeFlag + path });
+}
+
+function collectSystemIncludePathsArguments(input, flag) {
+ flag = (flag === undefined) ? input.cpp.systemIncludeFlag : flag;
+ var paths = collectSystemIncludePaths(input);
+ return paths.map(function(path) { return flag + path });
+}
+
+function collectPreincludePathsArguments(input, split) {
+ var paths = collectPreincludePaths(input);
+ if (split) {
+ var args = [];
+ for (var i = 0; i < paths.length; ++i)
+ args.push(input.cpp.preincludeFlag, paths[i]);
+ return args;
+ } else {
+ return paths.map(function(path) { return input.cpp.preincludeFlag + path });
+ }
+}
+
+function collectLibraryPathsArguments(product, flag) {
+ flag = (flag === undefined) ? product.cpp.libraryPathFlag : flag;
+ var paths = collectLibraryPaths(product);
+ return paths.map(function(path) { return flag + path });
+}
+
+function collectLinkerScriptPathsArguments(product, inputs, split, flag) {
+ flag = (flag === undefined) ? product.cpp.linkerScriptFlag : flag;
+ var paths = collectLinkerScriptPaths(inputs);
+ if (split) {
+ var args = [];
+ for (var i = 0; i < paths.length; ++i)
+ args.push(flag, paths[i]);
+ return args;
+ } else {
+ return paths.map(function(path) { return flag + path });
+ }
+}
+
+function collectLinkerObjectPathsArguments(product, inputs, flag) {
+ flag = (flag === undefined) ? "" : flag;
+ var paths = collectLinkerObjectPaths(product);
+ return paths.map(function(path) { return flag + path });
+}
+
+function collectMiscCompilerArguments(input, tag) {
+ return [].concat(ModUtils.moduleProperty(input, "platformFlags"),
+ ModUtils.moduleProperty(input, "flags"),
+ ModUtils.moduleProperty(input, "platformFlags", tag),
+ ModUtils.moduleProperty(input, "flags", tag));
+}
+
+function collectMiscAssemblerArguments(input, tag) {
+ return [].concat(ModUtils.moduleProperty(input, "platformFlags", tag),
+ ModUtils.moduleProperty(input, "flags", tag));
+}
+
+function collectMiscDriverArguments(config) {
+ return [].concat(ModUtils.moduleProperty(config, "platformDriverFlags"),
+ ModUtils.moduleProperty(config, "driverFlags"),
+ ModUtils.moduleProperty(config, "targetDriverFlags"));
+}
+
+function collectMiscLinkerArguments(product) {
+ return [].concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
+}
+
+function collectMiscEscapableLinkerArguments(product) {
+ return [].concat(ModUtils.moduleProperty(product, "platformLinkerFlags"),
+ ModUtils.moduleProperty(product, "linkerFlags"));
+}
+
+function supportsArchitecture(architecture, knownArchitectures) {
+ for (var i = 0; i < knownArchitectures.length; ++i) {
+ if (architecture.startsWith("arm")) {
+ if (architecture.startsWith(knownArchitectures[i]))
+ return true;
+ } else {
+ if (architecture === knownArchitectures[i])
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/share/qbs/modules/cpp/darwin.js b/share/qbs/modules/cpp/darwin.js
index 6373b57c4..0223c5ed3 100644
--- a/share/qbs/modules/cpp/darwin.js
+++ b/share/qbs/modules/cpp/darwin.js
@@ -28,6 +28,7 @@
**
****************************************************************************/
+var Codesign = require("../codesign/codesign.js");
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
var Gcc = require("./gcc.js");
@@ -72,7 +73,7 @@ function lipoOutputArtifacts(product, inputs, fileTag, debugSuffix) {
// approach for all bundle types.
var defaultVariant;
if (!buildVariants.some(function (x) { return x.name === "release"; })
- && product.multiplexByQbsProperties.contains("buildVariants")
+ && product.multiplexByQbsProperties.includes("buildVariants")
&& product.qbs.buildVariants && product.qbs.buildVariants.length > 1) {
var defaultBuildVariant = product.qbs.defaultBuildVariant;
buildVariants.map(function (variant) {
@@ -99,6 +100,9 @@ function lipoOutputArtifacts(product, inputs, fileTag, debugSuffix) {
else
tags.push(fileTag, "primary");
+ if (product.codesign.enableCodeSigning)
+ tags.push("codesign.signed_artifact");
+
return {
filePath: FileInfo.joinPaths(product.destinationDirectory,
PathTools.linkerOutputFilePath(fileTag, product,
@@ -133,7 +137,7 @@ function prepareLipo(project, product, inputs, outputs, input, output) {
for (var p in inputs)
inputs[p] = inputs[p].filter(function(inp) { return inp.product.name === product.name; });
var allInputs = [].concat.apply([], Object.keys(inputs).map(function (tag) {
- return ["application", "dynamiclibrary", "staticlibrary", "loadablemodule"].contains(tag)
+ return ["application", "dynamiclibrary", "staticlibrary", "loadablemodule"].includes(tag)
? inputs[tag] : [];
}));
@@ -168,26 +172,17 @@ function prepareLipo(project, product, inputs, outputs, input, output) {
commands.push(cmd);
}
- var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
- || outputs.debuginfo_loadablemodule;
- if (debugInfo) {
- var dsymPath = debugInfo[0].filePath;
- if (outputs.debuginfo_bundle && outputs.debuginfo_bundle[0])
- dsymPath = outputs.debuginfo_bundle[0].filePath;
- var flags = ModUtils.moduleProperty(product, "dsymutilFlags") || [];
- cmd = new Command(ModUtils.moduleProperty(product, "dsymutilPath"), flags.concat([
- "-o", dsymPath
- ]).concat(outputs.primary.map(function (f) { return f.filePath; })));
- cmd.description = "generating dSYM for " + product.name;
- commands.push(cmd);
- }
+ commands = commands.concat(
+ Gcc.separateDebugInfoCommandsDarwin(product, outputs, outputs.primary));
- cmd = new Command(ModUtils.moduleProperty(product, "stripPath"),
- ["-S", outputs.primary[0].filePath]);
- cmd.silent = true;
- commands.push(cmd);
if (outputs.dynamiclibrary_symbols)
Array.prototype.push.apply(commands, Gcc.createSymbolCheckingCommands(product, outputs));
+
+ if (product.codesign.enableCodeSigning) {
+ Array.prototype.push.apply(
+ commands, Codesign.prepareSign(project, product, inputs, outputs, input, output));
+ }
+
return commands;
}
diff --git a/share/qbs/modules/cpp/dmc.js b/share/qbs/modules/cpp/dmc.js
new file mode 100644
index 000000000..ea7cd7bb5
--- /dev/null
+++ b/share/qbs/modules/cpp/dmc.js
@@ -0,0 +1,506 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** 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.
+**
+****************************************************************************/
+
+var Cpp = require("cpp.js");
+var Environment = require("qbs.Environment");
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+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");
+
+function targetFlags(platform, architecture, extender, consoleApp, type) {
+ if (platform === "dos") {
+ if (architecture === "x86_16") {
+ if (extender === "dosz")
+ return ["-mz"];
+ else if (extender === "dosr")
+ return ["-mr"];
+ return ["-mc"];
+ } else if (architecture === "x86") {
+ if (extender === "dosx")
+ return ["-mx"];
+ else if (extender === "dosp")
+ return ["-mp"];
+ }
+ } else if (platform === "windows") {
+ var flags = [];
+ if (architecture === "x86_16") {
+ flags.push("-ml");
+ if (type.includes("application") && !consoleApp)
+ flags.push("-WA");
+ else if (type.includes("dynamiclibrary"))
+ flags.push("-WD");
+ } else if (architecture === "x86") {
+ flags.push("-mn");
+ if (type.includes("application"))
+ flags.push("-WA");
+ else if (type.includes("dynamiclibrary"))
+ flags.push("-WD");
+ }
+ return flags;
+ }
+ return [];
+}
+
+function languageFlags(tag) {
+ if (tag === "cpp")
+ return ["-cpp"];
+ return [];
+}
+
+function dumpMacros(compilerPath, platform, architecture, extender, tag) {
+ // Note: The DMC compiler does not support the predefined/ macros dumping. So, we do it
+ // with the following trick, where we try to create and compile a special temporary file
+ // and to parse the console output with the own magic pattern: #define <key> <value>.
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.joinPaths(outputDirectory.path(), "dump-macros.c");
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+ outputFile.writeLine("#define VALUE_TO_STRING(x) #x");
+ outputFile.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
+ outputFile.writeLine("#define VAR_NAME_VALUE(var) \"#define \" #var\" \"VALUE(var)");
+ // Declare all available pre-defined macros of DMC compiler.
+ var keys = [
+ // Prepare the DOS target macros.
+ "_MSDOS", "MSDOS",
+ // Prepare the OS/2 target macros.
+ "__OS2__",
+ // Prepare the Windows target macros.
+ "WIN32", "_WIN32", "__NT__",
+ // Prepare extended the 32 and 16 bit DOS target macros.
+ "DOS386", "DOS16RM",
+ // Prepare the memory model macros.
+ "M_I86", "_M_I86",
+ "_M_I86TM", "M_I86TM",
+ "_M_I86SM", "M_I86SM",
+ "_M_I86MM", "M_I86MM",
+ "_M_I86CM", "M_I86CM",
+ "_M_I86LM", "M_I86LM",
+ "_M_I86VM", "M_I86VM",
+ // Prepare 8086 macros.
+ "_M_I8086", "M_I8086",
+ // Prepare 286 macros.
+ "_M_I286", "M_I286",
+ // Prepare 32 bit macros.
+ "_M_IX86",
+ // Prepare compiler identification macros.
+ "__DMC__", "__DMC_VERSION_STRING__",
+ // Prepare common compiler macros.
+ "_CHAR_UNSIGNED", "_CHAR_EQ_UCHAR", "_DEBUG_TRACE", "_DLL",
+ "_ENABLE_ARRAYNEW", "_BOOL_DEFINED", "_WCHAR_T_DEFINED",
+ "_CPPRTTI", "_CPPUNWIND", "_MD", "_PUSHPOP_SUPPORTED",
+ "_STDCALL_SUPPORTED", "__INTSIZE", "__DEFALIGN", "_INTEGRAL_MAX_BITS",
+ "_WINDOWS", "_WINDLL", "__INLINE_8087", "__I86__", "__SMALL__",
+ "__MEDIUM__", "__COMPACT__", "__LARGE__", "__VCM__", "__FPCE__",
+ "__FPCE__IEEE__", "DEBUG",
+ // Prepare C99 and C++98 macros.
+ "__STDC__", "__STDC_HOSTED__", "__STDC_VERSION__", "__STDC_IEC_559__",
+ "__STDC_IEC_559_COMPLEX__", "__STDC_ISO_10646__", "__cplusplus"
+ ];
+ for (var i = 0; i < keys.length; ++i) {
+ var key = keys[i];
+ outputFile.writeLine("#if defined (" + key + ")");
+ outputFile.writeLine("#pragma message (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("#endif");
+ }
+ outputFile.close();
+
+ var process = new Process();
+ process.setWorkingDirectory(outputDirectory.path());
+ var lang = languageFlags(tag);
+ var target = targetFlags(platform, architecture, extender, false, ["application"]);
+ var args = ["-c"].concat(lang, target, FileInfo.toWindowsSeparators(outputFilePath));
+ process.exec(compilerPath, args, false);
+ File.remove(outputFilePath);
+ var out = process.readStdOut();
+ return Cpp.extractMacros(out);
+}
+
+function dumpDefaultPaths(compilerFilePath, tag) {
+ var binPath = FileInfo.path(compilerFilePath);
+ var rootPath = FileInfo.path(binPath);
+ var includePaths = [];
+ var cppIncludePath = FileInfo.joinPaths(rootPath, "stlport/stlport");
+ if (File.exists(cppIncludePath))
+ includePaths.push(cppIncludePath);
+ var cIncludePath = FileInfo.joinPaths(rootPath, "include");
+ if (File.exists(cIncludePath))
+ includePaths.push(cIncludePath);
+
+ var libraryPaths = [];
+ var libraryPath = FileInfo.joinPaths(rootPath, "lib");
+ if (File.exists(libraryPath))
+ libraryPaths.push(libraryPath);
+
+ return {
+ "includePaths": includePaths,
+ "libraryPaths": libraryPaths,
+ }
+}
+
+function guessVersion(macros) {
+ var version = macros["__DMC__"];
+ return { major: parseInt(version / 100),
+ minor: parseInt(version % 100),
+ patch: 0 };
+}
+
+function effectiveLinkerPath(product) {
+ if (product.cpp.linkerMode === "automatic") {
+ var compilerPath = product.cpp.compilerPath;
+ if (compilerPath)
+ return compilerPath;
+ console.log("Found no C-language objects, choosing system linker for " + product.name);
+ }
+ return product.cpp.linkerPath;
+}
+
+function useCompilerDriverLinker(product) {
+ var linker = effectiveLinkerPath(product);
+ var compilers = product.cpp.compilerPathByLanguage;
+ if (compilers)
+ return linker === compilers["cpp"] || linker === compilers["c"];
+ return linker === product.cpp.compilerPath;
+}
+
+function depsOutputTags() {
+ return ["dep"];
+}
+
+function depsOutputArtifacts(input, product) {
+ return [{
+ fileTags: depsOutputTags(),
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ input.baseName + ".dep")
+ }];
+}
+
+function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = ["-c"];
+
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+ args = args.concat(languageFlags(tag));
+ args = args.concat(targetFlags(product.qbs.targetPlatform, product.qbs.architecture,
+ product.cpp.extenderName, product.consoleApplication,
+ product.type));
+
+ // Input.
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
+ // Output.
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath));
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePaths(input).map(function(path) {
+ return input.cpp.preincludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Defines.
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ if (tag === "cpp") {
+ // We need to add the paths to the STL includes, because the DMC compiler does
+ // not handle it by default (because the STL libraries is a separate port).
+ var compilerIncludePaths = input.cpp.compilerIncludePaths || [];
+ args = args.concat(compilerIncludePaths.map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ }
+
+ // Other includes.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("-d");
+
+ // Optimization flags.
+ switch (input.cpp.optimization) {
+ case "small":
+ args.push("-o+space");
+ break;
+ case "fast":
+ args.push("-o+speed");
+ break;
+ case "none":
+ args.push("-o+none");
+ break;
+ }
+
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
+ args.push("-w");
+ break;
+ case "all":
+ args.push("-w-");
+ break;
+ }
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("-wx");
+
+ if (tag === "cpp") {
+ // Exceptions flag.
+ if (input.cpp.enableExceptions)
+ args.push("-Ae");
+
+ // RTTI flag.
+ var enableRtti = input.cpp.enableRtti;
+ if (input.cpp.enableRtti)
+ args.push("-Ar");
+ }
+
+ // Listing files generation flag.
+ if (input.cpp.generateCompilerListingFiles) {
+ // We need to use the relative path here, because the DMC compiler does not handle
+ // a long file path for this option.
+ var listingPath = Cpp.relativePath(product.buildDirectory, outputs.lst[0].filePath);
+ args.push("-l" + FileInfo.toWindowsSeparators(listingPath));
+ }
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(product));
+ return args;
+}
+
+function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = ["-c"];
+
+ // Input.
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
+ // Output.
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath));
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePaths(input).map(function(path) {
+ return input.cpp.preincludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Defines.
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ // Other includes.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+ return args;
+}
+
+function linkerFlags(project, product, inputs, outputs) {
+ var args = [];
+
+ var useCompilerDriver = useCompilerDriverLinker(product);
+ if (useCompilerDriver) {
+ args = args.concat(targetFlags(product.qbs.targetPlatform, product.qbs.architecture,
+ product.cpp.extenderName, product.consoleApplication,
+ product.type));
+
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Input resources.
+ args = args.concat(Cpp.collectResourceObjectPaths(inputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Input libraries.
+ args = args.concat(Cpp.collectAbsoluteLibraryDependencyPaths(product).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+
+ // Output.
+ if (product.type.includes("application")) {
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.application[0].filePath));
+ args.push("-L/" + (product.cpp.generateLinkerMapFile ? "MAP" : "NOMAP"));
+ if (product.qbs.targetPlatform === "windows" && product.qbs.architecture === "x86")
+ args.push("-L/SUBSYSTEM:" + (product.consoleApplication ? "CONSOLE" : "WINDOWS"));
+ } else if (product.type.includes("dynamiclibrary")) {
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.dynamiclibrary[0].filePath));
+ if (product.qbs.targetPlatform === "windows" && product.qbs.architecture === "x86") {
+ args.push("kernel32.lib");
+ args.push("-L/IMPLIB:" + FileInfo.toWindowsSeparators(
+ outputs.dynamiclibrary_import[0].filePath));
+ }
+ }
+
+ if (product.cpp.debugInformation)
+ args.push("-L/DEBUG");
+
+ args.push("-L/NOLOGO", "-L/SILENT");
+ }
+
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+ return args;
+}
+
+function archiverFlags(project, product, inputs, outputs) {
+ var args = ["-c"];
+ // Output.
+ args.push(FileInfo.toWindowsSeparators(outputs.staticlibrary[0].filePath));
+ // Input objects.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
+ return args;
+}
+
+function rccCompilerFlags(project, product, input, outputs) {
+ // Input.
+ var args = [FileInfo.toWindowsSeparators(input.filePath)];
+ // Output.
+ args.push("-o" + FileInfo.toWindowsSeparators(outputs.res[0].filePath));
+ // Bitness.
+ args.push("-32");
+
+ // Defines
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ // Other includes.
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+ return args;
+}
+
+function buildLinkerMapFilePath(target, suffix) {
+ return FileInfo.joinPaths(FileInfo.path(target.filePath),
+ FileInfo.completeBaseName(target.fileName) + suffix);
+}
+
+// It is a workaround which removes the generated linker map file if it is disabled
+// by cpp.generateLinkerMapFile property. Reason is that the DMC compiler always
+// generates this file, and does not have an option to disable generation for a linker
+// map file. So, we can to remove a listing files only after the linking completes.
+function removeLinkerMapFile(project, product, inputs, outputs, input, output) {
+ var target = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : outputs.application[0];
+ var cmd = new JavaScriptCommand();
+ cmd.mapFilePath = buildLinkerMapFilePath(target, ".map")
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.remove(mapFilePath); };
+ return cmd;
+}
+
+// It is a workaround to rename the extension of the output linker map file to the
+// specified one, since the linker generates only files with the '.map' extension.
+function renameLinkerMapFile(project, product, inputs, outputs, input, output) {
+ var target = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : outputs.application[0];
+ var cmd = new JavaScriptCommand();
+ cmd.newMapFilePath = buildLinkerMapFilePath(target, product.cpp.linkerMapSuffix);
+ cmd.oldMapFilePath = buildLinkerMapFilePath(target, ".map");
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ if (oldMapFilePath !== newMapFilePath)
+ File.move(oldMapFilePath, newMapFilePath);
+ };
+ return cmd;
+}
+
+function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
+ var cmd = new Command(input.cpp.compilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
+ return [cmd];
+}
+
+function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn);
+ var cmd = new Command(input.cpp.assemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
+ return [cmd];
+}
+
+function prepareLinker(project, product, inputs, outputs, input, output) {
+ var cmds = [];
+ var primaryOutput = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : outputs.application[0];
+ var args = linkerFlags(project, product, inputs, outputs);
+ var linkerPath = effectiveLinkerPath(product);
+ var cmd = new Command(linkerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + primaryOutput.fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "linker";
+ cmds.push(cmd);
+
+ if (product.cpp.generateLinkerMapFile)
+ cmds.push(renameLinkerMapFile(project, product, inputs, outputs, input, output));
+ else
+ cmds.push(removeLinkerMapFile(project, product, inputs, outputs, input, output));
+
+ return cmds;
+}
+
+function prepareArchiver(project, product, inputs, outputs, input, output) {
+ var args = archiverFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.archiverPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "creating " + output.fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "linker";
+ return [cmd];
+}
+
+function prepareRccCompiler(project, product, inputs, outputs, input, output) {
+ var args = rccCompilerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.rccCompilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
+ return [cmd];
+}
diff --git a/share/qbs/modules/cpp/dmc.qbs b/share/qbs/modules/cpp/dmc.qbs
new file mode 100644
index 000000000..ac89550e8
--- /dev/null
+++ b/share/qbs/modules/cpp/dmc.qbs
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 Denis Shienkov <denis.shienkov@gmail.com>
+** 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.Host
+import qbs.PathTools
+import qbs.Probes
+import qbs.Utilities
+import "dmc.js" as DMC
+import "cpp.js" as Cpp
+
+CppModule {
+ condition: Host.os().includes("windows") && qbs.toolchain && qbs.toolchain.includes("dmc")
+
+ Probes.BinaryProbe {
+ id: compilerPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["dmc"]
+ }
+
+ Probes.DmcProbe {
+ id: dmcProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ _targetPlatform: qbs.targetPlatform
+ _targetArchitecture: qbs.architecture
+ _targetExtender: extenderName
+ }
+
+ qbs.architecture: dmcProbe.found ? dmcProbe.architecture : original
+ qbs.targetPlatform: dmcProbe.found ? dmcProbe.targetPlatform : original
+
+ compilerVersionMajor: dmcProbe.versionMajor
+ compilerVersionMinor: dmcProbe.versionMinor
+ compilerVersionPatch: dmcProbe.versionPatch
+ endianness: "little"
+
+ compilerDefinesByLanguage: dmcProbe.compilerDefinesByLanguage
+ compilerIncludePaths: dmcProbe.includePaths
+
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
+
+ /* Work-around for QtCreator which expects these properties to exist. */
+ property string cCompilerName: compilerName
+ property string cxxCompilerName: compilerName
+
+ compilerName: "dmc.exe"
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+
+ assemblerName: "dmc.exe"
+ assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
+
+ linkerName: "link.exe"
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ property string archiverName: "lib.exe"
+ property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
+ property string rccCompilerName: "rcc.exe"
+ property string rccCompilerPath: FileInfo.joinPaths(toolchainInstallPath, rccCompilerName)
+
+ property string extenderName
+ PropertyOptions {
+ name: "extenderName"
+ allowedValues: [undefined, "dosz", "dosr", "dosx", "dosp"]
+ description: "Specifies the DOS memory extender to compile with:\n"
+ + " - \"dosz\" is the ZPM 16 bit DOS Extender\n"
+ + " - \"dosr\" is the Rational 16 bit DOS Extender\n"
+ + " - \"dosx\" is the DOSX 32 bit DOS Extender\n"
+ + " - \"dosp\" is the Pharlap 32 bit DOS Extender\n"
+ ;
+ }
+
+ runtimeLibrary: "dynamic"
+
+ staticLibrarySuffix: ".lib"
+ dynamicLibrarySuffix: ".dll"
+ executableSuffix: ".exe"
+ objectSuffix: ".obj"
+
+ imageFormat: {
+ if (qbs.targetPlatform === "dos")
+ return "mz";
+ else if (qbs.targetPlatform === "windows")
+ return "pe";
+ }
+
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: "-HI"
+ libraryPathFlag: "-L/packcode"
+
+ knownArchitectures: ["x86", "x86_16"]
+
+ Rule {
+ id: assembler
+ inputs: ["asm"]
+ outputFileTags: DMC.depsOutputTags().concat(
+ Cpp.assemblerOutputTags(generateAssemblerListingFiles))
+ outputArtifacts: DMC.depsOutputArtifacts(input, product).concat(
+ Cpp.assemblerOutputArtifacts(input))
+ prepare: DMC.prepareAssembler.apply(DMC, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.s", "*.asm"]
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ id: compiler
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: DMC.depsOutputTags().concat(
+ Cpp.compilerOutputTags(generateCompilerListingFiles))
+ outputArtifacts: DMC.depsOutputArtifacts(input, product).concat(
+ Cpp.compilerOutputArtifacts(input))
+ prepare: DMC.prepareCompiler.apply(DMC, arguments)
+ }
+
+
+ Rule {
+ id: rccCompiler
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.resourceCompilerOutputTags()
+ outputArtifacts: Cpp.resourceCompilerOutputArtifacts(input)
+ prepare: DMC.prepareRccCompiler.apply(DMC, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ id: applicationLinker
+ multiplex: true
+ inputs: ["obj", "res", "linkerscript"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
+ prepare: DMC.prepareLinker.apply(DMC, arguments)
+ }
+
+ Rule {
+ id: dynamicLibraryLinker
+ multiplex: true
+ inputs: ["obj", "res"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.dynamicLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.dynamicLibraryLinkerOutputArtifacts(product)
+ prepare: DMC.prepareLinker.apply(DMC, arguments)
+ }
+
+ Rule {
+ id: staticLibraryLinker
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
+ prepare: DMC.prepareArchiver.apply(DMC, arguments)
+ }
+}
diff --git a/share/qbs/modules/cpp/freebsd-gcc.qbs b/share/qbs/modules/cpp/freebsd-gcc.qbs
index b5a4b89f3..e04ed7f2b 100644
--- a/share/qbs/modules/cpp/freebsd-gcc.qbs
+++ b/share/qbs/modules/cpp/freebsd-gcc.qbs
@@ -29,13 +29,14 @@
****************************************************************************/
import "freebsd.js" as FreeBSD
+import qbs.Host
UnixGCC {
- condition: qbs.targetOS && qbs.targetOS.contains("freebsd") &&
- qbs.toolchain && qbs.toolchain.contains("gcc")
+ condition: qbs.targetOS.includes("freebsd") &&
+ qbs.toolchain && qbs.toolchain.includes("gcc")
priority: 1
- targetSystem: "freebsd" + (qbs.hostOS.contains("freebsd") ? FreeBSD.hostKernelRelease() : "")
+ targetSystem: "freebsd" + (Host.os().includes("freebsd") ? FreeBSD.hostKernelRelease() : "")
distributionIncludePaths: ["/usr/local/include"]
distributionLibraryPaths: ["/usr/local/lib"]
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 574fe769b..90f8fc933 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -28,9 +28,11 @@
**
****************************************************************************/
+var Codesign = require("../codesign/codesign.js");
var Cpp = require("cpp.js");
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
+var Host = require("qbs.Host");
var DarwinTools = require("qbs.DarwinTools");
var ModUtils = require("qbs.ModUtils");
var PathTools = require("qbs.PathTools");
@@ -76,6 +78,7 @@ function useCompilerDriverLinker(product, inputs) {
function collectLibraryDependencies(product, isDarwin) {
var publicDeps = {};
+ var privateDeps = {};
var objects = [];
var objectByFilePath = {};
var tagForLinkingAgainstSharedLib = product.cpp.imageFormat === "pe"
@@ -132,7 +135,7 @@ function collectLibraryDependencies(product, isDarwin) {
if (!obj.cpp)
return;
function ensureArray(a) {
- return Array.isArray(a) ? a : [];
+ return (a instanceof Array) ? a : [];
}
function sanitizedModuleListProperty(obj, moduleName, propertyName) {
return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
@@ -168,6 +171,8 @@ function collectLibraryDependencies(product, isDarwin) {
&& typeof dep.artifacts[tagForLinkingAgainstSharedLib] !== "undefined";
if (!isStaticLibrary && !isDynamicLibrary)
return;
+ if (isBelowIndirectDynamicLib && privateDeps[dep.name])
+ return;
var nextIsBelowIndirectDynamicLib = isBelowIndirectDynamicLib || isDynamicLibrary;
dep.dependencies.forEach(function(depdep) {
@@ -191,6 +196,7 @@ function collectLibraryDependencies(product, isDarwin) {
publicDeps[dep.name] = true;
} else {
addArtifactFilePaths(dep, tagForLinkingAgainstSharedLib, addPrivateFilePath);
+ privateDeps[dep.name] = true;
}
}
}
@@ -202,7 +208,6 @@ function collectLibraryDependencies(product, isDarwin) {
product.dependencies.forEach(traverseDirectDependency);
addExternalLibs(product);
- var seenRPathLinkDirs = {};
var result = { libraries: [], rpath_link: [] };
objects.forEach(
function (obj) {
@@ -213,10 +218,7 @@ function collectLibraryDependencies(product, isDarwin) {
framework: obj.framework });
} else {
var dirPath = FileInfo.path(obj.filePath);
- if (!seenRPathLinkDirs.hasOwnProperty(dirPath)) {
- seenRPathLinkDirs[dirPath] = true;
- result.rpath_link.push(dirPath);
- }
+ result.rpath_link.push(dirPath);
}
});
return result;
@@ -228,7 +230,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
if (useCompilerDriverLinker(product, inputs)) {
var sep = ",";
- var useXlinker = linkerFlags.some(function (f) { return f.contains(sep); });
+ var useXlinker = linkerFlags.some(function (f) { return f.includes(sep); });
if (useXlinker) {
// One or more linker arguments contain the separator character itself
// Use -Xlinker to handle these
@@ -245,7 +247,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
return xlinkerFlags;
}
- if (product.cpp.enableSuspiciousLinkerFlagWarnings && linkerFlags.contains("-Xlinker")) {
+ if (product.cpp.enableSuspiciousLinkerFlagWarnings && linkerFlags.includes("-Xlinker")) {
console.warn("Encountered -Xlinker linker flag escape sequence. This may cause the " +
"target to fail to link. Please do not escape these flags manually; " +
"qbs does that for you.");
@@ -260,9 +262,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
}
function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPath) {
- var libraryPaths = product.cpp.libraryPaths;
- var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
- var isDarwin = product.qbs.targetOS.contains("darwin");
+ var isDarwin = product.qbs.targetOS.includes("darwin");
var libraryDependencies = collectLibraryDependencies(product, isDarwin);
var frameworks = product.cpp.frameworks;
var weakFrameworks = product.cpp.weakFrameworks;
@@ -275,7 +275,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var escapableLinkerFlags = [];
- if (primaryOutput.fileTags.contains("dynamiclibrary")) {
+ if (primaryOutput.fileTags.includes("dynamiclibrary")) {
if (isDarwin) {
args.push((function () {
var tags = ["c", "cpp", "objc", "objcpp", "asm_cpp"];
@@ -300,7 +300,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
}
}
- if (primaryOutput.fileTags.contains("loadablemodule"))
+ if (primaryOutput.fileTags.includes("loadablemodule"))
args.push(isDarwin ? "-bundle" : "-shared");
if (primaryOutput.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) {
@@ -323,7 +323,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var sysroot = product.cpp.syslibroot;
if (sysroot) {
- if (product.qbs.toolchain.contains("qcc"))
+ if (product.qbs.toolchain.includes("qcc"))
escapableLinkerFlags.push("--sysroot=" + sysroot);
else if (isDarwin)
escapableLinkerFlags.push("-syslibroot", sysroot);
@@ -340,7 +340,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
function fixupRPath(rpath) {
// iOS, tvOS, watchOS, and others, are fine
- if (!product.qbs.targetOS.contains("macos"))
+ if (!product.qbs.targetOS.includes("macos"))
return rpath;
// ...as are newer versions of macOS
@@ -355,11 +355,12 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
return rpath;
}
- if (!product.qbs.targetOS.contains("windows")) {
- function isNotSystemRunPath(p) {
- return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
- && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
- };
+ function isNotSystemRunPath(p) {
+ return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.includes(p)
+ && !canonicalSystemRunPaths.includes(File.canonicalFilePath(p)));
+ };
+
+ if (!product.qbs.targetOS.includes("windows")) {
for (i in rpaths) {
if (isNotSystemRunPath(rpaths[i]))
escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i]));
@@ -369,13 +370,16 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
if (product.cpp.entryPoint)
escapableLinkerFlags.push("-e", product.cpp.entryPoint);
- if (product.qbs.toolchain.contains("mingw")) {
+ if (product.qbs.toolchain.includes("mingw")) {
if (product.consoleApplication !== undefined)
escapableLinkerFlags.push("-subsystem",
product.consoleApplication ? "console" : "windows");
var minimumWindowsVersion = product.cpp.minimumWindowsVersion;
if (minimumWindowsVersion) {
+ // workaround for QBS-1724, mingw seems to be broken
+ if (Utilities.versionCompare(minimumWindowsVersion, "6.2") > 0)
+ minimumWindowsVersion = "6.2";
var subsystemVersion = WindowsUtils.getWindowsVersionInFormat(minimumWindowsVersion, 'subsystem');
if (subsystemVersion) {
var major = subsystemVersion.split('.')[0];
@@ -397,23 +401,16 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var stdlib = isLinkingCppObjects
? product.cpp.cxxStandardLibrary
: undefined;
- if (stdlib && product.qbs.toolchain.contains("clang"))
+ if (stdlib && product.qbs.toolchain.includes("clang"))
args.push("-stdlib=" + stdlib);
// Flags for library search paths
- var allLibraryPaths = [];
- if (libraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
- if (distributionLibraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
- if (systemRunPaths.length > 0)
- allLibraryPaths = allLibraryPaths.filter(isNotSystemRunPath);
- args = args.concat(allLibraryPaths.map(function(path) { return '-L' + path }));
-
- var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
- Array.prototype.push.apply(escapableLinkerFlags, [].uniqueConcat(linkerScripts)
- .map(function(path) { return '-T' + path }));
+ var allLibraryPaths = Cpp.collectLibraryPaths(product);
+ var builtIns = product.cpp.compilerLibraryPaths
+ allLibraryPaths = allLibraryPaths.filter(function(p) { return !builtIns.includes(p); });
+ args = args.concat(allLibraryPaths.map(function(path) { return product.cpp.libraryPathFlag + path }));
+
+ escapableLinkerFlags = escapableLinkerFlags.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
var versionScripts = inputs.versionscript
? inputs.versionscript.map(function(a) { return a.filePath; }) : [];
@@ -425,16 +422,15 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var useCompilerDriver = useCompilerDriverLinker(product, inputs);
args = args.concat(configFlags(product, useCompilerDriver));
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.platformLinkerFlags);
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.linkerFlags);
+ escapableLinkerFlags = escapableLinkerFlags.concat(Cpp.collectMiscEscapableLinkerArguments(product));
// Note: due to the QCC response files hack in prepareLinker(), at least one object file or
// library file must follow the output file path so that QCC has something to process before
// sending the rest of the arguments through the response file.
args.push("-o", primaryOutput.filePath);
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function (obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
+ args = args.concat(Cpp.collectResourceObjectPaths(inputs));
for (i in frameworks) {
frameworkExecutablePath = PathTools.frameworkExecutablePath(frameworks[i]);
@@ -479,9 +475,12 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var symbolLinkMode = dep.symbolLinkMode;
if (isDarwin && symbolLinkMode) {
- if (!["lazy", "reexport", "upward", "weak"].contains(symbolLinkMode))
+ if (!["lazy", "reexport", "upward", "weak"].includes(symbolLinkMode))
throw new Error("unknown value '" + symbolLinkMode + "' for cpp.symbolLinkMode");
+ }
+ var supportsLazyMode = Utilities.versionCompare(product.cpp.compilerVersion, "15.0.0") < 0;
+ if (isDarwin && symbolLinkMode && (symbolLinkMode !== "lazy" || supportsLazyMode)) {
if (FileInfo.isAbsolutePath(lib) || lib.startsWith('@'))
escapableLinkerFlags.push("-" + symbolLinkMode + "_library", lib);
else if (dep.framework)
@@ -535,9 +534,10 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var escapedLinkerFlags = escapeLinkerFlags(product, inputs, escapableLinkerFlags);
Array.prototype.push.apply(escapedLinkerFlags, args);
- var driverLinkerFlags = useCompilerDriver ? product.cpp.driverLinkerFlags : undefined;
- if (driverLinkerFlags)
- Array.prototype.push.apply(escapedLinkerFlags, driverLinkerFlags);
+ if (useCompilerDriver)
+ escapedLinkerFlags = escapedLinkerFlags.concat(Cpp.collectMiscLinkerArguments(product));
+ if (product.qbs.toolchain.includes("mingw") && product.cpp.runtimeLibrary === "static")
+ escapedLinkerFlags = ['-static-libgcc', '-static-libstdc++'].concat(escapedLinkerFlags);
return escapedLinkerFlags;
}
@@ -545,15 +545,12 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
function configFlags(config, isDriver) {
var args = [];
- if (isDriver !== false) {
- args = args.concat(config.cpp.platformDriverFlags);
- args = args.concat(config.cpp.driverFlags);
- args = args.concat(config.cpp.targetDriverFlags);
- }
+ if (isDriver !== false)
+ args = args.concat(Cpp.collectMiscDriverArguments(config));
var frameworkPaths = config.cpp.frameworkPaths;
if (frameworkPaths)
- args = args.concat(frameworkPaths.map(function(path) { return '-F' + path }));
+ args = args.uniqueConcat(frameworkPaths.map(function(path) { return '-F' + path }));
var allSystemFrameworkPaths = [];
@@ -586,7 +583,7 @@ function languageTagFromFileExtension(toolchain, fileName) {
"s" : "asm",
"S" : "asm_cpp"
};
- if (!toolchain.contains("clang"))
+ if (!toolchain.includes("clang"))
m["sx"] = "asm_cpp"; // clang does NOT recognize .sx
return m[fileName.substring(i + 1)];
}
@@ -594,7 +591,7 @@ function languageTagFromFileExtension(toolchain, fileName) {
// Older versions of the QNX SDK have C and C++ compilers whose filenames differ only by case,
// which won't work in case insensitive environments like Win32+NTFS, HFS+ and APFS
function isLegacyQnxSdk(config) {
- return config.qbs.toolchain.contains("qcc") && config.qnx && !config.qnx.qnx7;
+ return config.qbs.toolchain.includes("qcc") && config.qnx && !config.qnx.qnx7;
}
function effectiveCompilerInfo(toolchain, input, output) {
@@ -602,7 +599,7 @@ function effectiveCompilerInfo(toolchain, input, output) {
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
// Whether we're compiling a precompiled header or normal source file
- var pchOutput = output.fileTags.contains(tag + "_pch");
+ var pchOutput = output.fileTags.includes(tag + "_pch");
var compilerPathByLanguage = input.cpp.compilerPathByLanguage;
if (compilerPathByLanguage)
@@ -610,7 +607,7 @@ function effectiveCompilerInfo(toolchain, input, output) {
if (!compilerPath
|| tag !== languageTagFromFileExtension(toolchain, input.fileName)
|| isLegacyQnxSdk(input)) {
- if (input.qbs.toolchain.contains("qcc"))
+ if (input.qbs.toolchain.includes("qcc"))
language = qnxLangArgs(input, tag);
else
language = ["-x", languageName(tag) + (pchOutput ? '-header' : '')];
@@ -704,6 +701,22 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
{"name": "gcc", "version": "4.7"}
]
},
+ "c17": {
+ "fallback": "c11",
+ "toolchains": [
+ {"name": "xcode", "version": "10.2"},
+ {"name": "clang", "version": "7.0"},
+ {"name": "gcc", "version": "8.1"}
+ ]
+ },
+ "c2x": {
+ "fallback": "c17",
+ "toolchains": [
+ {"name": "xcode", "version": "11.4"},
+ {"name": "clang", "version": "9.0"},
+ {"name": "gcc", "version": "9.0"}
+ ]
+ },
"c++14": {
"fallback": "c++1y",
"toolchains": [
@@ -723,9 +736,17 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
"c++20": {
"fallback": "c++2a",
"toolchains": [
- {"name": "xcode"}, // not yet implemented
- {"name": "clang"}, // not yet implemented
- {"name": "gcc"} // not yet implemented
+ {"name": "xcode", "version": "12.5"},
+ {"name": "clang", "version": "11.0"},
+ {"name": "gcc", "version": "10.1"}
+ ]
+ },
+ "c++23": {
+ "fallback": "c++2b",
+ "toolchains": [
+ {"name": "xcode"},
+ {"name": "clang"},
+ {"name": "gcc"}
]
}
};
@@ -734,7 +755,7 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
if (m) {
for (var idx = 0; idx < m.toolchains.length; ++idx) {
var tc = m.toolchains[idx];
- if (toolchain.contains(tc.name)) {
+ if (toolchain.includes(tc.name)) {
// If we found our toolchain and it doesn't yet support the language standard
// we're requesting, or we're using an older version that only supports the
// preliminary flag, use that.
@@ -754,16 +775,9 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
function compilerFlags(project, product, input, output, explicitlyDependsOn) {
var i;
- var includePaths = input.cpp.includePaths;
- var systemIncludePaths = input.cpp.systemIncludePaths;
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
-
- var platformDefines = input.cpp.platformDefines;
- var defines = input.cpp.defines;
-
// Determine which C-language we're compiling
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
- if (!["c", "cpp", "objc", "objcpp", "asm_cpp"].contains(tag))
+ if (!["c", "cpp", "objc", "objcpp", "asm_cpp"].includes(tag))
throw ("unsupported source language: " + tag);
var compilerInfo = effectiveCompilerInfo(product.qbs.toolchain,
@@ -796,12 +810,12 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
args = args.concat(configFlags(input));
- if (!input.qbs.toolchain.contains("qcc"))
+ if (!input.qbs.toolchain.includes("qcc"))
args.push('-pipe');
if (input.cpp.enableReproducibleBuilds) {
var toolchain = product.qbs.toolchain;
- if (!toolchain.contains("clang")) {
+ if (!toolchain.includes("clang")) {
var hashString = FileInfo.relativePath(project.sourceDirectory, input.filePath);
var hash = Utilities.getHash(hashString);
args.push("-frandom-seed=0x" + hash.substring(0, 8));
@@ -809,8 +823,8 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
var major = product.cpp.compilerVersionMajor;
var minor = product.cpp.compilerVersionMinor;
- if ((toolchain.contains("clang") && (major > 3 || (major === 3 && minor >= 5))) ||
- (toolchain.contains("gcc") && (major > 4 || (major === 4 && minor >= 9)))) {
+ if ((toolchain.includes("clang") && (major > 3 || (major === 3 && minor >= 5))) ||
+ (toolchain.includes("gcc") && (major > 4 || (major === 4 && minor >= 9)))) {
args.push("-Wdate-time");
}
}
@@ -838,7 +852,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
}
var visibility = input.cpp.visibility;
- if (!product.qbs.toolchain.contains("mingw")) {
+ if (!product.qbs.toolchain.includes("mingw")) {
if (visibility === 'hidden' || visibility === 'minimal')
args.push('-fvisibility=hidden');
if ((visibility === 'hiddenInlines' || visibility === 'minimal') && tag === 'cpp')
@@ -851,62 +865,40 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
// Only push language arguments if we have to.
Array.prototype.push.apply(args, compilerInfo.language);
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags'),
- ModUtils.moduleProperty(input, 'flags'),
- ModUtils.moduleProperty(input, 'platformFlags', tag),
- ModUtils.moduleProperty(input, 'flags', tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag));
var pchTag = compilerInfo.tag + "_pch";
- var pchOutput = output.fileTags.contains(pchTag);
+ var pchOutput = output.fileTags.includes(pchTag);
var pchInputs = explicitlyDependsOn[pchTag];
if (!pchOutput && pchInputs && pchInputs.length === 1
&& ModUtils.moduleProperty(input, 'usePrecompiledHeader', tag)) {
var pchInput = pchInputs[0];
var pchFilePath = FileInfo.joinPaths(FileInfo.path(pchInput.filePath),
pchInput.completeBaseName);
- args.push('-include', pchFilePath);
+ args.push(input.cpp.preincludeFlag, pchFilePath);
}
- var prefixHeaders = input.cpp.prefixHeaders;
- for (i in prefixHeaders) {
- args.push('-include');
- args.push(prefixHeaders[i]);
- }
+ args = args.concat(Cpp.collectPreincludePathsArguments(input));
var positionIndependentCode = input.cpp.positionIndependentCode;
- if (positionIndependentCode && !product.qbs.targetOS.contains("windows"))
+ if (positionIndependentCode && !product.qbs.targetOS.includes("windows"))
args.push('-fPIC');
var cppFlags = input.cpp.cppFlags;
for (i in cppFlags)
args.push('-Wp,' + cppFlags[i])
- var allDefines = [];
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
- args = args.concat(allDefines.map(function(define) { return '-D' + define }));
- if (includePaths) {
- args = args.concat([].uniqueConcat(includePaths).map(function(path) {
- return input.cpp.includeFlag + path;
- }));
- }
-
- var allSystemIncludePaths = [];
- if (systemIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(systemIncludePaths);
- if (distributionIncludePaths)
- allSystemIncludePaths = allSystemIncludePaths.uniqueConcat(distributionIncludePaths);
- allSystemIncludePaths.forEach(function(v) { args.push(input.cpp.systemIncludeFlag, v); });
+ args = args.concat(Cpp.collectDefinesArguments(input));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
var minimumWindowsVersion = input.cpp.minimumWindowsVersion;
- if (minimumWindowsVersion && product.qbs.targetOS.contains("windows")) {
+ if (minimumWindowsVersion && product.qbs.targetOS.includes("windows")) {
var hexVersion = WindowsUtils.getWindowsVersionInFormat(minimumWindowsVersion, 'hex');
if (hexVersion) {
var versionDefs = [ 'WINVER', '_WIN32_WINNT', '_WIN32_WINDOWS' ];
for (i in versionDefs)
- args.push('-D' + versionDefs[i] + '=' + hexVersion);
+ args.push(input.cpp.defineFlag + versionDefs[i] + '=' + hexVersion);
}
}
@@ -914,11 +906,11 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
switch (tag) {
case "c":
case "objc":
- var knownValues = ["c11", "c99", "c90", "c89"];
+ var knownValues = ["c2x", "c17", "c11", "c99", "c90", "c89"];
return Cpp.languageVersion(input.cpp.cLanguageVersion, knownValues, "C");
case "cpp":
case "objcpp":
- knownValues = ["c++20", "c++2a", "c++17", "c++1z",
+ knownValues = ["c++23", "c++2b", "c++20", "c++2a", "c++17", "c++1z",
"c++14", "c++1y", "c++11", "c++0x",
"c++03", "c++98"];
return Cpp.languageVersion(input.cpp.cxxLanguageVersion, knownValues, "C++");
@@ -935,7 +927,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
if (tag === "cpp" || tag === "objcpp") {
var cxxStandardLibrary = product.cpp.cxxStandardLibrary;
- if (cxxStandardLibrary && product.qbs.toolchain.contains("clang")) {
+ if (cxxStandardLibrary && product.qbs.toolchain.includes("clang")) {
args.push("-stdlib=" + cxxStandardLibrary);
}
}
@@ -950,7 +942,7 @@ function additionalCompilerAndLinkerFlags(product) {
var args = []
var requireAppExtensionSafeApi = product.cpp.requireAppExtensionSafeApi;
- if (requireAppExtensionSafeApi !== undefined && product.qbs.targetOS.contains("darwin")) {
+ if (requireAppExtensionSafeApi !== undefined && product.qbs.targetOS.includes("darwin")) {
args.push(requireAppExtensionSafeApi ? "-fapplication-extension" : "-fno-application-extension");
}
@@ -976,10 +968,6 @@ function languageName(fileTag) {
function prepareAssembler(project, product, inputs, outputs, input, output) {
var assemblerPath = product.cpp.assemblerPath;
- var includePaths = input.cpp.includePaths;
- var systemIncludePaths = input.cpp.systemIncludePaths;
- var distributionIncludePaths = input.cpp.distributionIncludePaths;
-
var args = product.cpp.targetAssemblerFlags;
if (input.cpp.debugInformation)
@@ -989,18 +977,9 @@ function prepareAssembler(project, product, inputs, outputs, input, output) {
if (warnings === 'none')
args.push('-W');
- var tag = "asm";
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', tag),
- ModUtils.moduleProperty(input, 'flags', tag));
-
- var allIncludePaths = [];
- if (includePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- if (distributionIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
- args = args.concat(allIncludePaths.map(function(path) { return input.cpp.includeFlag + path }));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input, input.cpp.includeFlag));
args.push("-o", output.filePath);
args.push(input.filePath);
@@ -1014,7 +993,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output) {
function compilerEnvVars(config, compilerInfo)
{
- if (config.qbs.toolchain.contains("qcc"))
+ if (config.qbs.toolchain.includes("qcc"))
return ["QCC_CONF_PATH"];
var list = ["CPATH", "TMPDIR"];
@@ -1026,15 +1005,15 @@ function compilerEnvVars(config, compilerInfo)
list.push("OBJC_INCLUDE_PATH");
else if (compilerInfo.tag === "objccpp")
list.push("OBJCPLUS_INCLUDE_PATH");
- if (config.qbs.targetOS.contains("macos"))
+ if (config.qbs.targetOS.includes("macos"))
list.push("MACOSX_DEPLOYMENT_TARGET");
- else if (config.qbs.targetOS.contains("ios"))
+ else if (config.qbs.targetOS.includes("ios"))
list.push("IPHONEOS_DEPLOYMENT_TARGET");
- else if (config.qbs.targetOS.contains("tvos"))
+ else if (config.qbs.targetOS.includes("tvos"))
list.push("TVOS_DEPLOYMENT_TARGET");
- else if (config.qbs.targetOS.contains("watchos"))
+ else if (config.qbs.targetOS.includes("watchos"))
list.push("WATCHOS_DEPLOYMENT_TARGET");
- if (config.qbs.toolchain.contains("clang")) {
+ if (config.qbs.toolchain.includes("clang")) {
list.push("TEMP", "TMP");
} else {
list.push("LANG", "LC_CTYPE", "LC_MESSAGES", "LC_ALL", "GCC_COMPARE_DEBUG",
@@ -1045,7 +1024,7 @@ function compilerEnvVars(config, compilerInfo)
function linkerEnvVars(config, inputs)
{
- if (config.qbs.toolchain.contains("clang") || config.qbs.toolchain.contains("qcc"))
+ if (config.qbs.toolchain.includes("clang") || config.qbs.toolchain.includes("qcc"))
return [];
var list = ["GNUTARGET", "LDEMULATION", "COLLECT_NO_DEMANGLE"];
if (useCompilerDriverLinker(config, inputs))
@@ -1055,7 +1034,7 @@ function linkerEnvVars(config, inputs)
function setResponseFileThreshold(command, product)
{
- if (product.qbs.targetOS.contains("windows") && product.qbs.hostOS.contains("windows"))
+ if (product.qbs.targetOS.includes("windows") && Host.os().includes("windows"))
command.responseFileThreshold = 10000;
}
@@ -1063,7 +1042,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var compilerInfo = effectiveCompilerInfo(product.qbs.toolchain,
input, output);
var compilerPath = compilerInfo.path;
- var pchOutput = output.fileTags.contains(compilerInfo.tag + "_pch");
+ var pchOutput = output.fileTags.includes(compilerInfo.tag + "_pch");
var args = compilerFlags(project, product, input, output, explicitlyDependsOn);
var wrapperArgsLength = 0;
@@ -1153,7 +1132,7 @@ function getSymbolInfo(product, inputFile)
// construct the list of defined symbols by subtracting.
var undefinedGlobalSymbols = collectStdoutLines(command, args.concat(["-u", inputFile]));
result.definedGlobalSymbols = result.allGlobalSymbols.filter(function(line) {
- return !undefinedGlobalSymbols.contains(line); });
+ return !undefinedGlobalSymbols.includes(line); });
result.success = true;
} catch (e) {
console.debug("Failed to collect symbols for shared library: nm command '"
@@ -1253,8 +1232,13 @@ function createSymbolCheckingCommands(product, outputs) {
oldSymbols = oldNmResult.allGlobalSymbols;
newSymbols = newNmResult.allGlobalSymbols;
} else {
- oldSymbols = oldNmResult.definedGlobalSymbols;
- newSymbols = newNmResult.definedGlobalSymbols;
+ var weakFilter = function(line) {
+ var symbolType = line.split(/\s+/)[1];
+ return symbolType != "v" && symbolType != "V"
+ && symbolType != "w" && symbolType != "W";
+ };
+ oldSymbols = oldNmResult.definedGlobalSymbols.filter(weakFilter);
+ newSymbols = newNmResult.definedGlobalSymbols.filter(weakFilter);
}
if (oldSymbols.length !== newSymbols.length) {
console.debug("List of relevant symbols differs for '" + libFilePath + "'.");
@@ -1281,6 +1265,59 @@ function createSymbolCheckingCommands(product, outputs) {
return commands;
}
+function separateDebugInfoCommands(product, outputs, primaryOutput) {
+ var commands = [];
+
+ var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
+ || outputs.debuginfo_loadablemodule;
+
+ if (debugInfo) {
+ var objcopy = product.cpp.objcopyPath;
+
+ var cmd = new Command(objcopy, ["--only-keep-debug", primaryOutput.filePath,
+ debugInfo[0].filePath]);
+ cmd.silent = true;
+ commands.push(cmd);
+
+ cmd = new Command(objcopy, ["--strip-debug", primaryOutput.filePath]);
+ cmd.silent = true;
+ commands.push(cmd);
+
+ cmd = new Command(objcopy, ["--add-gnu-debuglink=" + debugInfo[0].filePath,
+ primaryOutput.filePath]);
+ cmd.silent = true;
+ commands.push(cmd);
+ }
+
+ return commands;
+}
+
+function separateDebugInfoCommandsDarwin(product, outputs, primaryOutputs) {
+ var commands = [];
+
+ var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
+ || outputs.debuginfo_loadablemodule;
+ if (debugInfo) {
+ var dsymPath = debugInfo[0].filePath;
+ if (outputs.debuginfo_bundle && outputs.debuginfo_bundle[0])
+ dsymPath = outputs.debuginfo_bundle[0].filePath;
+
+ var flags = product.cpp.dsymutilFlags || [];
+ var files = primaryOutputs.map(function (f) { return f.filePath; });
+ var cmd = new Command(product.cpp.dsymutilPath,
+ flags.concat(["-o", dsymPath].concat(files)));
+ cmd.description = "generating dSYM for " + product.name;
+ commands.push(cmd);
+
+ // strip debug info
+ cmd = new Command(product.cpp.stripPath, ["-S"].concat(files));
+ cmd.silent = true;
+ commands.push(cmd);
+ }
+
+ return commands;
+}
+
function prepareLinker(project, product, inputs, outputs, input, output) {
var i, primaryOutput, cmd, commands = [];
@@ -1307,7 +1344,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var responseFileArgumentIndex = wrapperArgsLength;
// qcc doesn't properly handle response files, so we have to do it manually
- var useQnxResponseFileHack = product.qbs.toolchain.contains("qcc")
+ var useQnxResponseFileHack = product.qbs.toolchain.includes("qcc")
&& useCompilerDriverLinker(product, inputs);
if (useQnxResponseFileHack) {
// qcc needs to see at least one object/library file to think it has something to do,
@@ -1327,43 +1364,13 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
setResponseFileThreshold(cmd, product);
commands.push(cmd);
- var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll
- || outputs.debuginfo_loadablemodule;
- if (debugInfo) {
- if (product.qbs.targetOS.contains("darwin")) {
- if (!product.aggregate) {
- var dsymPath = debugInfo[0].filePath;
- if (outputs.debuginfo_bundle && outputs.debuginfo_bundle[0])
- dsymPath = outputs.debuginfo_bundle[0].filePath;
- var flags = product.cpp.dsymutilFlags || [];
- cmd = new Command(product.cpp.dsymutilPath, flags.concat([
- "-o", dsymPath, primaryOutput.filePath
- ]));
- cmd.description = "generating dSYM for " + product.name;
- commands.push(cmd);
-
- cmd = new Command(product.cpp.stripPath,
- ["-S", primaryOutput.filePath]);
- cmd.silent = true;
- commands.push(cmd);
- }
- } else {
- var objcopy = product.cpp.objcopyPath;
-
- cmd = new Command(objcopy, ["--only-keep-debug", primaryOutput.filePath,
- debugInfo[0].filePath]);
- cmd.silent = true;
- commands.push(cmd);
-
- cmd = new Command(objcopy, ["--strip-debug", primaryOutput.filePath]);
- cmd.silent = true;
- commands.push(cmd);
-
- cmd = new Command(objcopy, ["--add-gnu-debuglink=" + debugInfo[0].filePath,
- primaryOutput.filePath]);
- cmd.silent = true;
- commands.push(cmd);
+ if (product.qbs.targetOS.includes("darwin")) {
+ if (!product.aggregate) {
+ commands = commands.concat(separateDebugInfoCommandsDarwin(
+ product, outputs, [primaryOutput]));
}
+ } else {
+ commands = commands.concat(separateDebugInfoCommands(product, outputs, primaryOutput));
}
if (outputs.dynamiclibrary) {
@@ -1383,27 +1390,9 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
}
}
- if (product.xcode && product.bundle) {
- var actualSigningIdentity = product.xcode.actualSigningIdentity;
- var codesignDisplayName = product.xcode.actualSigningIdentityDisplayName;
- if (actualSigningIdentity && !product.bundle.isBundle) {
- args = product.xcode.codesignFlags || [];
- args.push("--force");
- args.push("--sign", actualSigningIdentity);
- args = args.concat(DarwinTools._codeSignTimestampFlags(product));
-
- for (var j in inputs.xcent) {
- args.push("--entitlements", inputs.xcent[j].filePath);
- break; // there should only be one
- }
- args.push(primaryOutput.filePath);
- cmd = new Command(product.xcode.codesignPath, args);
- cmd.description = "codesign "
- + primaryOutput.fileName
- + " using " + codesignDisplayName
- + " (" + actualSigningIdentity + ")";
- commands.push(cmd);
- }
+ if (product.cpp.shouldSignArtifacts) {
+ Array.prototype.push.apply(
+ commands, Codesign.prepareSign(project, product, inputs, outputs, input, output));
}
return commands;
@@ -1462,12 +1451,7 @@ function dumpMacros(env, compilerFilePath, args, nullDevice, tag) {
p.exec(compilerFilePath,
(args || []).concat(["-Wp,-dM", "-E", "-x", languageName(tag || "c") , nullDevice]),
true);
- var map = {};
- p.readStdOut().trim().split(/\r?\n/g).map(function (line) {
- var parts = line.split(" ", 3);
- map[parts[1]] = parts[2];
- });
- return map;
+ return Cpp.extractMacros(p.readStdOut());
} finally {
p.close();
}
@@ -1514,7 +1498,7 @@ function dumpDefaultPaths(env, compilerFilePath, args, nullDevice, pathListSepar
if (libraryPaths.length === 0)
libraryPaths.push(sysroot + "/lib", sysroot + "/usr/lib");
- if (frameworkPaths.length === 0 && targetOS.contains("darwin"))
+ if (frameworkPaths.length === 0 && targetOS.includes("darwin"))
frameworkPaths.push(sysroot + "/System/Library/Frameworks");
return {
@@ -1527,6 +1511,28 @@ function dumpDefaultPaths(env, compilerFilePath, args, nullDevice, pathListSepar
}
}
+function targetLinkerFlags(targetArch, targetOS) {
+ var linkerFlags = {
+ "windows": {
+ "i386": "i386pe",
+ "x86_64": "i386pep",
+ },
+ "freebsd": {
+ "i386": "elf_i386_fbsd",
+ "x86_64": "elf_x86_64_fbsd",
+ },
+ "other": {
+ "i386": "elf_i386",
+ "x86_64": "elf_x86_64",
+ }
+ };
+ if (targetOS.includes("windows"))
+ return linkerFlags["windows"][targetArch];
+ else if (targetOS.includes("freebsd"))
+ return linkerFlags["freebsd"][targetArch];
+ return linkerFlags["other"][targetArch];
+}
+
function targetFlags(tool, hasTargetOption, target, targetArch, machineType, targetOS) {
var args = [];
if (hasTargetOption) {
@@ -1539,8 +1545,8 @@ function targetFlags(tool, hasTargetOption, target, targetArch, machineType, tar
"x86_64": ["-m64"],
},
"linker": {
- "i386": ["-m", targetOS.contains("windows") ? "i386pe" : "elf_i386"],
- "x86_64": ["-m", targetOS.contains("windows") ? "i386pep" : "elf_x86_64"],
+ "i386": ["-m", targetLinkerFlags("i386", targetOS)],
+ "x86_64": ["-m", targetLinkerFlags("x86_64", targetOS)],
},
"assembler": {
"i386": ["--32"],
diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js
index d51668095..ed58ac262 100644
--- a/share/qbs/modules/cpp/iar.js
+++ b/share/qbs/modules/cpp/iar.js
@@ -37,155 +37,342 @@ var Process = require("qbs.Process");
var TemporaryDir = require("qbs.TemporaryDir");
var TextFile = require("qbs.TextFile");
-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";
- case "rl78":
- return "iccrl78";
- }
- throw "Unable to deduce compiler name for unsupported architecture: '"
- + qbs.architecture + "'";
+function supportXLinker(architecture) {
+ return architecture === "78k"
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs12"
+ || architecture === "hcs8"
+ || architecture === "m16c"
+ || architecture === "m32c"
+ || architecture === "m68k"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "r32c"
+ || architecture === "v850";
}
-function assemblerName(qbs) {
- switch (qbs.architecture) {
- case "arm":
- return "iasmarm";
- case "rl78":
- return "iasmrl78";
- 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 supportILinker(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8";
}
-function linkerName(qbs) {
- switch (qbs.architecture) {
- case "arm":
- return "ilinkarm";
- case "stm8":
- return "ilinkstm8";
- case "rl78":
- return "ilinkrl78";
- case "mcs51":
- case "avr":
- case "msp430":
- return "xlink";
- }
- throw "Unable to deduce linker name for unsupported architecture: '"
- + qbs.architecture + "'";
+function supportXArchiver(architecture) {
+ return architecture === "78k"
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs12"
+ || architecture === "hcs8"
+ || architecture === "m16c"
+ || architecture === "m32c"
+ || architecture === "m68k"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "r32c"
+ || architecture === "v850";
}
-function archiverName(qbs) {
- switch (qbs.architecture) {
- case "arm":
- case "stm8":
- case "rl78":
- return "iarchive";
- case "mcs51":
- case "avr":
- case "msp430":
- return "xlib";
- }
- throw "Unable to deduce archiver name for unsupported architecture: '"
- + qbs.architecture + "'";
+function supportIArchiver(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8";
}
-function staticLibrarySuffix(qbs) {
- switch (qbs.architecture) {
- case "arm":
- case "stm8":
- case "rl78":
- 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 supportXAssembler(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "78k"
+ || architecture === "avr"
+ || architecture === "hcs12"
+ || architecture === "m16c"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "m32c"
+ || architecture === "v850";
}
-function executableSuffix(qbs) {
- switch (qbs.architecture) {
- case "arm":
- case "stm8":
- case "rl78":
- 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 supportIAssembler(architecture) {
+ return architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs8"
+ || architecture === "r32c"
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8"
+ || architecture === "m68k";
}
-function objectSuffix(qbs) {
- switch (qbs.architecture) {
- case "arm":
- case "stm8":
- case "rl78":
- return ".o";
- case "mcs51":
- return ".r51";
+function supportEndianness(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rx";
+}
+
+function supportCppExceptions(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx";
+}
+
+function supportCppRtti(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx";
+}
+
+function supportCppWarningAboutCStyleCast(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "rh850"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "stm8"
+ || architecture === "v850";
+}
+
+function supportDeprecatedFeatureWarnings(architecture) {
+ return architecture.startsWith("arm")
+ || architecture === "avr"
+ || architecture === "cr16"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "rh850"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "stm8"
+ || architecture === "v850";
+}
+
+function supportCLanguageVersion(architecture) {
+ return architecture !== "78k";
+}
+
+function supportCppLanguage(compilerFilePath) {
+ var baseName = FileInfo.baseName(compilerFilePath);
+ return baseName !== "iccs08";
+}
+
+// It is a 'magic' IAR-specific target architecture code.
+function architectureCode(architecture) {
+ switch (architecture) {
+ case "78k":
+ return "26";
case "avr":
- return ".r90";
+ return "90";
+ case "avr32":
+ return "82";
+ case "mcs51":
+ return "51";
case "msp430":
- return ".r43";
+ return "43";
+ case "v850":
+ return "85";
+ case "m68k":
+ return "68";
+ case "m32c":
+ return "48";
+ case "r32c":
+ return "53";
+ case "m16c":
+ return "34";
+ case "cr16":
+ return "45";
+ case "hcs12":
+ return "12";
+ case "hcs8":
+ return "78";
+ case "rh850": case "riscv": case "rl78": case "rx": case "sh": case "stm8":
+ return "";
+ default:
+ if (architecture.startsWith("arm"))
+ return "";
+ break;
}
- throw "Unable to deduce object file suffix for unsupported architecture: '"
- + qbs.architecture + "'";
}
-function imageFormat(qbs) {
- switch (qbs.architecture) {
- case "arm":
- case "stm8":
- case "rl78":
- return "elf";
- case "mcs51":
- case "avr":
- case "msp430":
- return "ubrof";
+function toolchainDetails(qbs) {
+ var architecture = qbs.architecture;
+ var code = architectureCode(architecture);
+ var details = {};
+
+ if (supportXLinker(architecture)) {
+ details.libraryPathFlag = "-I";
+ details.linkerScriptFlag = "-f";
+ details.linkerName = "xlink";
+ details.linkerSilentFlag = "-S";
+ details.linkerMapFileFlag = "-l";
+ details.linkerEntryPointFlag = "-s";
+ } else if (supportILinker(architecture)) {
+ details.libraryPathFlag = "-L";
+ details.linkerScriptFlag = "--config";
+ details.linkerSilentFlag = "--silent";
+ details.linkerMapFileFlag = "--map";
+ details.linkerEntryPointFlag = "--entry";
+ details.linkerName = architecture.startsWith("arm")
+ ? "ilinkarm" : ("ilink" + architecture);
+ }
+
+ if (supportXArchiver(architecture))
+ details.archiverName = "xar";
+ else if (supportIArchiver(architecture))
+ details.archiverName = "iarchive";
+
+ var hasCode = (code !== "");
+ details.staticLibrarySuffix = hasCode ? (".r" + code) : ".a";
+ details.executableSuffix = hasCode
+ ? ((qbs.debugInformation) ? (".d" + code) : (".a" + code)) : ".out";
+ details.objectSuffix = hasCode ? (".r" + code) : ".o";
+ details.imageFormat = hasCode ? "ubrof" : "elf";
+
+ if (architecture.startsWith("arm")) {
+ details.compilerName = "iccarm";
+ details.assemblerName = "iasmarm";
+ } else if (architecture === "78k") {
+ details.compilerName = "icc78k";
+ details.assemblerName = "a78k";
+ } else if (architecture === "avr") {
+ details.compilerName = "iccavr";
+ details.assemblerName = "aavr";
+ } else if (architecture === "avr32") {
+ details.compilerName = "iccavr32";
+ details.assemblerName = "aavr32";
+ } else if (architecture === "cr16") {
+ details.compilerName = "icccr16c";
+ details.assemblerName = "acr16c";
+ } else if (architecture === "hcs12") {
+ details.compilerName = "icchcs12";
+ details.assemblerName = "ahcs12";
+ } else if (architecture === "hcs8") {
+ details.compilerName = "iccs08";
+ details.assemblerName = "as08";
+ } else if (architecture === "m16c") {
+ details.compilerName = "iccm16c";
+ details.assemblerName = "am16c";
+ } else if (architecture === "m32c") {
+ details.compilerName = "iccm32c";
+ details.assemblerName = "am32c";
+ } else if (architecture === "m68k") {
+ details.compilerName = "icccf";
+ details.assemblerName = "acf";
+ } else if (architecture === "mcs51") {
+ details.compilerName = "icc8051";
+ details.assemblerName = "a8051";
+ } else if (architecture === "msp430") {
+ details.compilerName = "icc430";
+ details.assemblerName = "a430";
+ } else if (architecture === "r32c") {
+ details.compilerName = "iccr32c";
+ details.assemblerName = "ar32c";
+ } else if (architecture === "rh850") {
+ details.compilerName = "iccrh850";
+ details.assemblerName = "iasmrh850";
+ } else if (architecture === "riscv") {
+ details.compilerName = "iccriscv";
+ details.assemblerName = "iasmriscv";
+ } else if (architecture === "rl78") {
+ details.compilerName = "iccrl78";
+ details.assemblerName = "iasmrl78";
+ } else if (architecture === "rx") {
+ details.compilerName = "iccrx";
+ details.assemblerName = "iasmrx";
+ } else if (architecture === "sh") {
+ details.compilerName = "iccsh";
+ details.assemblerName = "iasmsh";
+ } else if (architecture === "stm8") {
+ details.compilerName = "iccstm8";
+ details.assemblerName = "iasmstm8";
+ } else if (architecture === "v850") {
+ details.compilerName = "iccv850";
+ details.assemblerName = "av850";
}
- throw "Unable to deduce image format for unsupported architecture: '"
- + qbs.architecture + "'";
+
+ return details;
+}
+
+function guessArmArchitecture(core) {
+ var arch = "arm";
+ if (core === "__ARM4M__")
+ arch += "v4m";
+ else if (core === "__ARM4TM__")
+ arch += "v4tm";
+ else if (core === "__ARM5E__")
+ arch += "v5e";
+ else if (core === "__ARM5__")
+ arch += "v5";
+ else if (core === "__ARM6M__")
+ arch += "v6m";
+ else if (core === "__ARM6SM__")
+ arch += "v6sm";
+ else if (core === "__ARM6__")
+ arch += "v6";
+ else if (core === "__ARM7M__")
+ arch += "v7m";
+ else if (core === "__ARM7R__")
+ arch += "v7r";
+ return arch;
}
function guessArchitecture(macros) {
- if (macros["__ICCARM__"] === "1")
- return "arm";
+ if (macros["__ICC430__"] === "1")
+ return "msp430";
+ else if (macros["__ICC78K__"] === "1")
+ return "78k";
else if (macros["__ICC8051__"] === "1")
return "mcs51";
+ else if (macros["__ICCARM__"] === "1")
+ return guessArmArchitecture(macros["__CORE__"]);
+ else if (macros["__ICCAVR32__"] === "1")
+ return "avr32";
else if (macros["__ICCAVR__"] === "1")
return "avr";
- else if (macros["__ICCSTM8__"] === "1")
- return "stm8";
- else if (macros["__ICC430__"] === "1")
- return "msp430";
+ else if (macros["__ICCCF__"] === "1")
+ return "m68k";
+ else if (macros["__ICCCR16C__"] === "1")
+ return "cr16";
+ else if (macros["__ICCHCS12__"] === "1")
+ return "hcs12";
+ else if (macros["__ICCM16C__"] === "1")
+ return "m16c";
+ else if (macros["__ICCM32C__"] === "1")
+ return "m32c";
+ else if (macros["__ICCR32C__"] === "1")
+ return "r32c";
+ else if (macros["__ICCRH850__"] === "1")
+ return "rh850";
+ else if (macros["__ICCRISCV__"] === "1")
+ return "riscv";
else if (macros["__ICCRL78__"] === "1")
return "rl78";
+ else if (macros["__ICCRX__"] === "1")
+ return "rx";
+ else if (macros["__ICCS08__"] === "1")
+ return "hcs8";
+ else if (macros["__ICCSH__"] === "1")
+ return "sh";
+ else if (macros["__ICCSTM8__"] === "1")
+ return "stm8";
+ else if (macros["__ICCV850__"] === "1")
+ return "v850";
}
function guessEndianness(macros) {
@@ -194,24 +381,34 @@ function guessEndianness(macros) {
return "big"
}
-function guessVersion(macros, architecture)
-{
+function guessVersion(macros, architecture) {
var version = parseInt(macros["__VER__"], 10);
- switch (architecture) {
- case "arm":
+ if (architecture.startsWith("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":
- case "rl78":
+ patch: parseInt(version) % 1000 }
+ } else if (architecture === "78k"
+ || architecture === "avr"
+ || architecture === "avr32"
+ || architecture === "cr16"
+ || architecture === "hcs12"
+ || architecture === "hcs8"
+ || architecture === "m16c"
+ || architecture === "m32c"
+ || architecture === "m68k"
+ || architecture === "mcs51"
+ || architecture === "msp430"
+ || architecture === "r32c"
+ || architecture === "rh850"
+ || architecture === "riscv"
+ || architecture === "rl78"
+ || architecture === "rx"
+ || architecture === "sh"
+ || architecture === "stm8"
+ || architecture === "v850") {
return { major: parseInt(version / 100),
minor: parseInt(version % 100),
- patch: 0,
- found: true }
+ patch: 0 }
}
}
@@ -219,16 +416,27 @@ function cppLanguageOption(compilerFilePath) {
var baseName = FileInfo.baseName(compilerFilePath);
switch (baseName) {
case "iccarm":
- case "rl78":
+ case "iccrh850":
+ case "iccriscv":
+ case "iccrl78":
+ case "iccrx":
return "--c++";
+ case "icc430":
+ case "icc78k":
case "icc8051":
case "iccavr":
+ case "iccavr32":
+ case "icccf":
+ case "icccr16c":
+ case "icchcs12":
+ case "iccm16c":
+ case "iccm32c":
+ case "iccr32c":
+ case "iccsh":
case "iccstm8":
- case "icc430":
+ case "iccv850":
return "--ec++";
}
- throw "Unable to deduce C++ language option for unsupported compiler: '"
- + FileInfo.toNativeSeparators(compilerFilePath) + "'";
}
function dumpMacros(compilerFilePath, tag) {
@@ -238,169 +446,65 @@ function dumpMacros(compilerFilePath, tag) {
var outFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/iar-macros.predef");
var args = [ inFilePath, "--predef_macros", outFilePath ];
- if (tag && tag === "cpp")
+ if (tag === "cpp" && supportCppLanguage(compilerFilePath))
args.push(cppLanguageOption(compilerFilePath));
var p = new Process();
+ p.setWorkingDirectory(tempDir.path());
p.exec(compilerFilePath, args, true);
var outFile = new TextFile(outFilePath, TextFile.ReadOnly);
- var map = {};
- outFile.readAll().trim().split(/\r?\n/g).map(function (line) {
- var parts = line.split(" ", 3);
- map[parts[1]] = parts[2];
- });
- return map;
+ return Cpp.extractMacros(outFile.readAll());
}
-function dumpDefaultPaths(compilerFilePath, tag) {
+function dumpCompilerIncludePaths(compilerFilePath, tag) {
+ // We can dump the compiler include paths using the undocumented `--IDE3` flag,
+ // e.g. which also is used in the IAR extension for the VSCode. In this case the
+ // compiler procuces the console output in the following format:
+ // `$$TOOL_BEGIN $$VERSION "3" $$INC_BEGIN $$FILEPATH "<path\\to\\directory>" $$TOOL_END`
+
var tempDir = new TemporaryDir();
var inFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/empty-source.c");
var inFile = new TextFile(inFilePath, TextFile.WriteOnly);
- var args = [ inFilePath, "--preinclude", "." ];
- if (tag === "cpp")
+ var args = ["--IDE3", inFilePath];
+ if (tag === "cpp" && supportCppLanguage(compilerFilePath))
args.push(cppLanguageOption(compilerFilePath));
+ var includePaths = [];
var p = new Process();
- // This process should return an error, don't throw
- // an error in this case.
+ p.setWorkingDirectory(tempDir.path());
+ // It is possible that the process can return an error code in case the
+ // compiler does not support the `--IDE3` flag. So, don't throw an error in this case.
p.exec(compilerFilePath, args, false);
- var output = p.readStdErr();
-
- var includePaths = [];
- var pass = 0;
- for (var pos = 0; pos < output.length; ++pos) {
- var searchIndex = output.indexOf("searched:", pos);
- if (searchIndex === -1)
- break;
- var startQuoteIndex = output.indexOf('"', searchIndex + 1);
- if (startQuoteIndex === -1)
- break;
- var endQuoteIndex = output.indexOf('"', startQuoteIndex + 1);
- if (endQuoteIndex === -1)
- break;
- pos = endQuoteIndex + 1;
-
- // Ignore the first path as it is not a compiler include path.
- ++pass;
- if (pass === 1)
- continue;
-
- var parts = output.substring(startQuoteIndex + 1, endQuoteIndex).split("\n");
- var includePath = "";
- for (var i in parts)
- includePath += parts[i].trim();
-
- includePaths.push(includePath);
- }
-
- return {
- "includePaths": includePaths
- };
-}
-
-function collectLibraryDependencies(product) {
- var seen = {};
- var result = [];
-
- function addFilePath(filePath) {
- result.push({ filePath: filePath });
- }
-
- function addArtifactFilePaths(dep, artifacts) {
- if (!artifacts)
- return;
- var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
- artifactFilePaths.forEach(addFilePath);
- }
-
- function addExternalStaticLibs(obj) {
- if (!obj.cpp)
- return;
- function ensureArray(a) {
- return Array.isArray(a) ? a : [];
- }
- function sanitizedModuleListProperty(obj, moduleName, propertyName) {
- return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
- }
- var externalLibs = [].concat(
- sanitizedModuleListProperty(obj, "cpp", "staticLibraries"));
- var staticLibrarySuffix = obj.moduleProperty("cpp", "staticLibrarySuffix");
- externalLibs.forEach(function(staticLibraryName) {
- if (!staticLibraryName.endsWith(staticLibrarySuffix))
- staticLibraryName += staticLibrarySuffix;
- addFilePath(staticLibraryName);
- });
- }
-
- function traverse(dep) {
- if (seen.hasOwnProperty(dep.name))
- return;
- seen[dep.name] = true;
-
- if (dep.parameters.cpp && dep.parameters.cpp.link === false)
- return;
-
- var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
- if (staticLibraryArtifacts) {
- dep.dependencies.forEach(traverse);
- addArtifactFilePaths(dep, staticLibraryArtifacts);
- addExternalStaticLibs(dep);
+ p.readStdOut().trim().split(/\r?\n/g).map(function(line) {
+ var m = line.match(/\$\$INC_BEGIN\s\$\$FILEPATH\s\"([^"]*)/);
+ if (m) {
+ var includePath = m[1].replace(/\\\\/g, '/');
+ if (includePath && File.exists(includePath))
+ includePaths.push(includePath);
}
- }
-
- product.dependencies.forEach(traverse);
- addExternalStaticLibs(product);
- return result;
-}
-
-function compilerOutputArtifacts(input, useListing) {
- var artifacts = [];
- artifacts.push({
- fileTags: ["obj"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + input.cpp.objectSuffix
});
- if (useListing) {
- artifacts.push({
- fileTags: ["lst"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".lst"
- });
+
+ if (includePaths.length === 0) {
+ // This can happen if the compiler does not support the `--IDE3` flag,
+ // e.g. IAR for S08 architecture. In this case we use fallback to the
+ // detection of the `inc` directory.
+ var includePath = FileInfo.joinPaths(FileInfo.path(compilerFilePath), "../inc/");
+ if (File.exists(includePath))
+ includePaths.push(includePath);
}
- return artifacts;
-}
-function applicationLinkerOutputArtifacts(product) {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var mem_map = {
- fileTags: ["mem_map"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + ".map")
- };
- return [app, mem_map]
+ return includePaths;
}
-function staticLibraryLinkerOutputArtifacts(product) {
- var staticLib = {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
+function dumpDefaultPaths(compilerFilePath, tag) {
+ var includePaths = dumpCompilerIncludePaths(compilerFilePath, tag);
+ return {
+ "includePaths": includePaths
};
- return [staticLib]
}
function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
- // Determine which C-language we're compiling.
- var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
-
var args = [];
// Input.
@@ -409,28 +513,15 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Output.
args.push("-o", outputs.obj[0].filePath);
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePathsArguments(input, true));
+
// 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 }));
+ args = args.concat(Cpp.collectDefinesArguments(input));
// 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 }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
// Silent output generation flag.
args.push("--silent");
@@ -442,35 +533,40 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Optimization flags.
switch (input.cpp.optimization) {
case "small":
- args.push("-Ohs");
+ args.push("-Ohz");
break;
case "fast":
- args.push("-Ohz");
+ args.push("-Ohs");
break;
case "none":
args.push("-On");
break;
}
+ var architecture = input.qbs.architecture;
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+
// Warning level flags.
switch (input.cpp.warningLevel) {
case "none":
args.push("--no_warnings");
break;
case "all":
- args.push("--deprecated_feature_warnings="
- +"+attribute_syntax,"
- +"+preprocessor_extensions,"
- +"+segment_pragmas");
- if (tag === "cpp")
- args.push("--warn_about_c_style_casts");
+ if (supportDeprecatedFeatureWarnings(architecture)) {
+ args.push("--deprecated_feature_warnings="
+ +"+attribute_syntax,"
+ +"+preprocessor_extensions,"
+ +"+segment_pragmas");
+ }
+ if (tag === "cpp" && supportCppWarningAboutCStyleCast(architecture))
+ args.push("--warn_about_c_style_casts");
break;
}
if (input.cpp.treatWarningsAsErrors)
args.push("--warnings_are_errors");
// C language version flags.
- if (tag === "c") {
+ if (tag === "c" && supportCLanguageVersion(architecture)) {
var knownValues = ["c89"];
var cLanguageVersion = Cpp.languageVersion(
input.cpp.cLanguageVersion, knownValues, "C");
@@ -479,58 +575,46 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("--c89");
break;
default:
- // Default C language version is C11/C99 that
+ // Default C language version is C18/C11/C99 that
// depends on the IAR version.
break;
}
}
- // Architecture specific flags.
- switch (input.qbs.architecture) {
- case "arm":
- case "rl78":
- // Byte order flags.
- var endianness = input.cpp.endianness;
- if (endianness && input.qbs.architecture === "arm")
- 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");
- }
- break;
- case "stm8":
- case "mcs51":
- case "avr":
- case "msp430":
- // Enable C++ language flags.
- if (tag === "cpp")
- args.push("--ec++");
- break;
+ // C++ language version flags.
+ var compilerFilePath = input.cpp.compilerPath;
+ if (tag === "cpp" && supportCppLanguage(compilerFilePath)) {
+ // C++ language flag.
+ var cppOption = cppLanguageOption(compilerFilePath);
+ args.push(cppOption);
+
+ // Exceptions flag.
+ var enableExceptions = input.cpp.enableExceptions;
+ if (!enableExceptions && supportCppExceptions(architecture))
+ args.push("--no_exceptions");
+
+ // RTTI flag.
+ var enableRtti = input.cpp.enableRtti;
+ if (!enableRtti && supportCppRtti(architecture))
+ args.push("--no_rtti");
}
+ // Byte order flags.
+ var endianness = input.cpp.endianness;
+ if (endianness && supportEndianness(architecture))
+ args.push("--endian=" + endianness);
+
// Listing files generation flag.
- if (product.cpp.generateCompilerListingFiles)
+ if (input.cpp.generateCompilerListingFiles)
args.push("-l", outputs.lst[0].filePath);
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
- ModUtils.moduleProperty(input, "flags"),
- ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(product));
return args;
}
function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
- // Determine which C-language we"re compiling
- var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
-
var args = [];
// Input.
@@ -539,24 +623,23 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Output.
args.push("-o", outputs.obj[0].filePath);
+ var architecture = input.qbs.architecture;
+
+ // The `--preinclude` flag is only supported for a certain
+ // set of assemblers, not for all.
+ if (supportIAssembler(architecture))
+ args = args.concat(Cpp.collectPreincludePathsArguments(input));
+
// Includes.
- var allIncludePaths = [];
- 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 = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
// Debug information flags.
if (input.cpp.debugInformation)
args.push("-r");
// Architecture specific flags.
- switch (input.qbs.architecture) {
- case "stm8":
- case "rl78":
+ if (supportIAssembler(architecture)) {
// Silent output generation flag.
args.push("--silent");
// Warning level flags.
@@ -564,104 +647,79 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("--no_warnings");
if (input.cpp.treatWarningsAsErrors)
args.push("--warnings_are_errors");
- break;
- default:
+ } else if (supportXAssembler(architecture)){
// Silent output generation flag.
args.push("-S");
// Warning level flags.
args.push("-w" + (input.cpp.warningLevel === "none" ? "-" : "+"));
- break;
}
+ // Byte order flags.
+ var endianness = input.cpp.endianness;
+ if (endianness && supportEndianness(architecture))
+ args.push("--endian", endianness);
+
// Listing files generation flag.
- if (product.cpp.generateAssemblerListingFiles)
+ if (input.cpp.generateAssemblerListingFiles)
args.push("-l", outputs.lst[0].filePath);
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
return args;
}
-function linkerFlags(project, product, input, outputs) {
+function linkerFlags(project, product, inputs, outputs) {
var args = [];
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
// Output.
args.push("-o", outputs.application[0].filePath);
// Library paths.
- var allLibraryPaths = [];
- var libraryPaths = product.cpp.libraryPaths;
- if (libraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
- var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
- if (distributionLibraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
- args = args.concat(allLibraryPaths.map(function(path) { return '-L' + path }));
+ args = args.concat(Cpp.collectLibraryPathsArguments(product));
// Library dependencies.
- var libraryDependencies = collectLibraryDependencies(product);
- if (libraryDependencies)
- args = args.concat(libraryDependencies.map(function(dep) { return dep.filePath }));
+ args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
// Linker scripts.
- var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
+ args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs, true));
- // Architecture specific flags.
- switch (product.qbs.architecture) {
- case "arm":
- case "stm8":
- case "rl78":
- // Silent output generation flag.
- args.push("--silent");
- // Map file generation flag.
- if (product.cpp.generateLinkerMapFile)
- args.push("--map", outputs.mem_map[0].filePath);
- // Entry point flag.
- if (product.cpp.entryPoint)
- args.push("--entry", product.cpp.entryPoint);
- // 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.
+ // Silent output generation flag.
+ args.push(product.cpp.linkerSilentFlag);
+
+ // Map file generation flag.
+ if (product.cpp.generateLinkerMapFile)
+ args.push(product.cpp.linkerMapFileFlag, outputs.mem_map[0].filePath);
+
+ // Entry point flag.
+ if (product.cpp.entryPoint)
+ args.push(product.cpp.linkerEntryPointFlag, product.cpp.entryPoint);
+
+ // Debug information flag.
+ if (supportXLinker(product.qbs.architecture)) {
if (product.cpp.debugInformation)
args.push("-rt");
- // Map file generation flag.
- if (product.cpp.generateLinkerMapFile)
- args.push("-l", outputs.mem_map[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;
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
return args;
}
-function archiverFlags(project, product, input, outputs) {
+function archiverFlags(project, product, inputs, outputs) {
var args = [];
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
// Output.
- args.push("--create");
+ var architecture = product.qbs.architecture;
+ if (supportIArchiver(architecture))
+ args.push("--create");
args.push("-o", outputs.staticlibrary[0].filePath);
return args;
@@ -673,6 +731,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
return [cmd];
}
@@ -682,25 +741,28 @@ function prepareAssembler(project, product, inputs, outputs, input, output, expl
var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
return [cmd];
}
function prepareLinker(project, product, inputs, outputs, input, output) {
var primaryOutput = outputs.application[0];
- var args = linkerFlags(project, product, input, outputs);
+ var args = linkerFlags(project, product, inputs, outputs);
var linkerPath = product.cpp.linkerPath;
var cmd = new Command(linkerPath, args);
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
return [cmd];
}
function prepareArchiver(project, product, inputs, outputs, input, output) {
- var args = archiverFlags(project, product, input, outputs);
+ var args = archiverFlags(project, product, inputs, outputs);
var archiverPath = product.cpp.archiverPath;
var cmd = new Command(archiverPath, args);
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
cmd.stdoutFilterFunction = function(output) {
return "";
};
diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs
index bc226389b..558635ef5 100644
--- a/share/qbs/modules/cpp/iar.qbs
+++ b/share/qbs/modules/cpp/iar.qbs
@@ -28,17 +28,16 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.File
import qbs.FileInfo
-import qbs.ModUtils
import qbs.PathTools
import qbs.Probes
import qbs.Utilities
+import "cpp.js" as Cpp
import "iar.js" as IAR
CppModule {
- condition: qbs.toolchain && qbs.toolchain.contains("iar")
+ condition: qbs.toolchain && qbs.toolchain.includes("iar")
Probes.BinaryProbe {
id: compilerPathProbe
@@ -54,6 +53,7 @@ CppModule {
}
qbs.architecture: iarProbe.found ? iarProbe.architecture : original
+ qbs.targetPlatform: "none"
compilerVersionMajor: iarProbe.versionMajor
compilerVersionMinor: iarProbe.versionMinor
@@ -63,45 +63,58 @@ CppModule {
compilerDefinesByLanguage: iarProbe.compilerDefinesByLanguage
compilerIncludePaths: iarProbe.includePaths
- property string toolchainInstallPath: compilerPathProbe.found
- ? compilerPathProbe.path : undefined
-
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
- compilerName: IAR.compilerName(qbs) + compilerExtension
+ compilerName: toolchainDetails.compilerName + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: IAR.assemblerName(qbs) + compilerExtension
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: IAR.linkerName(qbs) + compilerExtension
+ linkerName: toolchainDetails.linkerName + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: IAR.archiverName(qbs) + compilerExtension
+ property string archiverName: toolchainDetails.archiverName + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
runtimeLibrary: "static"
- staticLibrarySuffix: IAR.staticLibrarySuffix(qbs)
- executableSuffix: IAR.executableSuffix(qbs)
-
- property string objectSuffix: IAR.objectSuffix(qbs)
+ staticLibrarySuffix: toolchainDetails.staticLibrarySuffix
+ executableSuffix: toolchainDetails.executableSuffix
+ objectSuffix: toolchainDetails.objectSuffix
- imageFormat: IAR.imageFormat(qbs)
+ imageFormat: toolchainDetails.imageFormat
enableExceptions: false
enableRtti: false
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: "--preinclude"
+ libraryDependencyFlag: ""
+ libraryPathFlag: toolchainDetails.libraryPathFlag
+ linkerScriptFlag: toolchainDetails.linkerScriptFlag
+
+ property string linkerSilentFlag: toolchainDetails.linkerSilentFlag
+ property string linkerMapFileFlag: toolchainDetails.linkerMapFileFlag
+ property string linkerEntryPointFlag: toolchainDetails.linkerEntryPointFlag
+
+ toolchainDetails: IAR.toolchainDetails(qbs)
+
+ knownArchitectures: ["78k", "arm", "avr", "avr32", "cr16",
+ "hcs12", "hcs8", "m16c", "m32c", "m68k", "mcs51", "msp430",
+ "r32c", "rh850", "riscv", "rl78", "rx", "sh", "stm8", "v850"]
+
Rule {
id: assembler
inputs: ["asm"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: IAR.compilerOutputArtifacts(
- input, input.cpp.generateAssemblerListingFiles)
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
prepare: IAR.prepareAssembler.apply(IAR, arguments)
}
@@ -114,9 +127,8 @@ CppModule {
id: compiler
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: IAR.compilerOutputArtifacts(
- input, input.cpp.generateCompilerListingFiles)
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
prepare: IAR.prepareCompiler.apply(IAR, arguments)
}
@@ -125,8 +137,8 @@ CppModule {
multiplex: true
inputs: ["obj", "linkerscript"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["application", "mem_map"]
- outputArtifacts: IAR.applicationLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
prepare: IAR.prepareLinker.apply(IAR, arguments)
}
@@ -135,8 +147,8 @@ CppModule {
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["staticlibrary"]
- outputArtifacts: IAR.staticLibraryLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
prepare: IAR.prepareArchiver.apply(IAR, arguments)
}
}
diff --git a/share/qbs/modules/cpp/ios-gcc.qbs b/share/qbs/modules/cpp/ios-gcc.qbs
index 0ff99679f..968b873da 100644
--- a/share/qbs/modules/cpp/ios-gcc.qbs
+++ b/share/qbs/modules/cpp/ios-gcc.qbs
@@ -31,21 +31,30 @@
import qbs.DarwinTools
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Utilities
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('ios') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('ios') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
+ minimumIosVersion: {
+ if (Host.architecture() == "armv7a")
+ return "6.0";
+ // XCode 12 requres version (at least 8.0) to be present in the -target triplet
+ // when compiling for ios-simulator
+ if (xcode.present && Utilities.versionCompare(xcode.version, "12.0") >= 0)
+ return "8.0";
+ }
targetSystem: "ios" + (minimumIosVersion || "")
minimumDarwinVersion: minimumIosVersion
- minimumDarwinVersionCompilerFlag: qbs.targetOS.contains("ios-simulator")
+ minimumDarwinVersionCompilerFlag: qbs.targetOS.includes("ios-simulator")
? "-mios-simulator-version-min"
: "-miphoneos-version-min"
- minimumDarwinVersionLinkerFlag: qbs.targetOS.contains("ios-simulator")
+ minimumDarwinVersionLinkerFlag: qbs.targetOS.includes("ios-simulator")
? "-ios_simulator_version_min"
: "-iphoneos_version_min"
@@ -60,13 +69,13 @@ DarwinGCC {
readonly property stringList simulatorObjcFlags: {
// default in Xcode and also required for building 32-bit Simulator binaries with ARC
// since the default ABI version is 0 for 32-bit targets
- return qbs.targetOS.contains("ios-simulator")
+ return qbs.targetOS.includes("ios-simulator")
? ["-fobjc-abi-version=2", "-fobjc-legacy-dispatch"]
: [];
}
Rule {
- condition: !product.qbs.targetOS.contains("ios-simulator")
+ condition: !product.qbs.targetOS.includes("ios-simulator")
inputsFromDependencies: ["bundle.content"]
Artifact {
diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js
index befcc5a33..8f3297aa2 100644
--- a/share/qbs/modules/cpp/keil.js
+++ b/share/qbs/modules/cpp/keil.js
@@ -39,382 +39,456 @@ var TemporaryDir = require("qbs.TemporaryDir");
var TextFile = require("qbs.TextFile");
var Utilities = require("qbs.Utilities");
-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 isMcs51Architecture(architecture) {
+ return architecture === "mcs51";
}
-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 isMcs251Architecture(architecture) {
+ return architecture === "mcs251";
}
-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 isMcsArchitecture(architecture) {
+ return isMcs51Architecture(architecture)
+ || isMcs251Architecture(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 isC166Architecture(architecture) {
+ return architecture === "c166";
}
-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 isArmArchitecture(architecture) {
+ return architecture.startsWith("arm");
}
-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 isMcsCompiler(compilerPath) {
+ var base = FileInfo.baseName(compilerPath).toLowerCase();
+ return base === "c51" || base === "cx51" || base === "c251";
}
-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";
+function isC166Compiler(compilerPath) {
+ return FileInfo.baseName(compilerPath).toLowerCase() === "c166";
+}
+
+function isArmCCCompiler(compilerPath) {
+ return FileInfo.baseName(compilerPath).toLowerCase() === "armcc";
+}
+
+function isArmClangCompiler(compilerPath) {
+ return FileInfo.baseName(compilerPath).toLowerCase() === "armclang";
+}
+
+function preincludeFlag(compilerPath) {
+ if (isArmCCCompiler(compilerPath))
+ return "--preinclude";
+ else if (isArmClangCompiler(compilerPath))
+ return "-include";
+}
+
+function toolchainDetails(qbs) {
+ var architecture = qbs.architecture;
+ if (isMcs51Architecture(architecture)) {
+ return {
+ "imageFormat": "omf",
+ "linkerMapSuffix":".m51",
+ "objectSuffix": ".obj",
+ "executableSuffix": ".abs",
+ "compilerName": "c51",
+ "assemblerName": "a51",
+ "linkerName": "bl51",
+ "archiverName": "lib51"
+ };
+ } else if (isMcs251Architecture(architecture)) {
+ return {
+ "imageFormat": "omf",
+ "linkerMapSuffix":".m51",
+ "objectSuffix": ".obj",
+ "executableSuffix": ".abs",
+ "compilerName": "c251",
+ "assemblerName": "a251",
+ "linkerName": "l251",
+ "archiverName": "lib251"
+ };
+ } else if (isC166Architecture(architecture)) {
+ return {
+ "imageFormat": "omf",
+ "linkerMapSuffix":".m66",
+ "objectSuffix": ".obj",
+ "executableSuffix": ".abs",
+ "compilerName": "c166",
+ "assemblerName": "a166",
+ "linkerName": "l166",
+ "archiverName": "lib166"
+ };
+ } else if (isArmArchitecture(architecture)) {
+ return {
+ "imageFormat": "elf",
+ "linkerMapSuffix":".map",
+ "objectSuffix": ".o",
+ "executableSuffix": ".axf",
+ "disassemblerName": "fromelf",
+ "compilerName": "armcc",
+ "assemblerName": "armasm",
+ "linkerName": "armlink",
+ "archiverName": "armar"
+ };
}
- throw "Unable to deduce image format for unsupported architecture: '"
- + qbs.architecture + "'";
+}
+
+function guessArmCCArchitecture(targetArchArm, targetArchThumb) {
+ var arch = "arm";
+ if (targetArchArm === "4" && targetArchThumb === "0")
+ arch += "v4";
+ else if (targetArchArm === "4" && targetArchThumb === "1")
+ arch += "v4t";
+ else if (targetArchArm === "5" && targetArchThumb === "2")
+ arch += "v5t";
+ else if (targetArchArm === "6" && targetArchThumb === "3")
+ arch += "v6";
+ else if (targetArchArm === "6" && targetArchThumb === "4")
+ arch += "v6t2";
+ else if (targetArchArm === "0" && targetArchThumb === "3")
+ arch += "v6m";
+ else if (targetArchArm === "7" && targetArchThumb === "4")
+ arch += "v7r";
+ else if (targetArchArm === "0" && targetArchThumb === "4")
+ arch += "v7m";
+ return arch;
+}
+
+function guessArmClangArchitecture(targetArchArm, targetArchProfile) {
+ targetArchProfile = targetArchProfile.replace(/'/g, "");
+ var arch = "arm";
+ if (targetArchArm !== "" && targetArchProfile !== "")
+ arch += "v" + targetArchArm + targetArchProfile.toLowerCase();
+ return arch;
}
function guessArchitecture(macros) {
if (macros["__C51__"])
return "mcs51";
- else if (macros["__CC_ARM"] === 1)
- return "arm";
+ else if (macros["__C251__"])
+ return "mcs251";
+ else if (macros["__C166__"])
+ return "c166";
+ else if (macros["__CC_ARM"] === "1")
+ return guessArmCCArchitecture(macros["__TARGET_ARCH_ARM"], macros["__TARGET_ARCH_THUMB"]);
+ else if (macros["__clang__"] === "1" && macros["__arm__"] === "1")
+ return guessArmClangArchitecture(macros["__ARM_ARCH"], macros["__ARM_ARCH_PROFILE"]);
}
function guessEndianness(macros) {
- if (macros["__C51__"]) {
+ if (macros["__C51__"] || macros["__C251__"]) {
// 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
// Keil toolchain. See for more info:
// * http://www.keil.com/support/man/docs/c51/c51_ap_2bytescalar.htm
// * http://www.keil.com/support/man/docs/c51/c51_ap_4bytescalar.htm
+ // * http://www.keil.com/support/man/docs/c251/c251_ap_2bytescalar.htm
+ // * http://www.keil.com/support/man/docs/c251/c251_ap_4bytescalar.htm
return "big";
- } else if (macros["__ARMCC_VERSION"]) {
+ } else if (macros["__C166__"]) {
+ // The C166 processors are 16-bit. So, the data with an integer type
+ // represented by more than one byte is stored as little endian in the
+ // Keil toolchain. See for more info:
+ // * http://www.keil.com/support/man/docs/c166/c166_ap_ints.htm
+ // * http://www.keil.com/support/man/docs/c166/c166_ap_longs.htm
+ return "little";
+ } else if (macros["__CC_ARM"]) {
return macros["__BIG_ENDIAN"] ? "big" : "little";
+ } else if (macros["__clang__"] && macros["__arm__"]) {
+ switch (macros["__BYTE_ORDER__"]) {
+ case "__ORDER_BIG_ENDIAN__":
+ return "big";
+ case "__ORDER_LITTLE_ENDIAN__":
+ return "little";
+ }
}
}
function guessVersion(macros) {
- if (macros["__C51__"]) {
- var mcsVersion = macros["__C51__"];
+ if (macros["__C51__"] || macros["__C251__"]) {
+ var mcsVersion = macros["__C51__"] || macros["__C251__"];
return { major: parseInt(mcsVersion / 100),
minor: parseInt(mcsVersion % 100),
- patch: 0,
- found: true }
- } else if (macros["__CC_ARM"]) {
+ patch: 0 }
+ } else if (macros["__C166__"]) {
+ var xcVersion = macros["__C166__"];
+ return { major: parseInt(xcVersion / 100),
+ minor: parseInt(xcVersion % 100),
+ patch: 0 }
+ } else if (macros["__CC_ARM"] || macros["__clang__"]) {
var armVersion = macros["__ARMCC_VERSION"];
return { major: parseInt(armVersion / 1000000),
minor: parseInt(armVersion / 10000) % 100,
- patch: parseInt(armVersion) % 10000,
- found: true }
+ patch: parseInt(armVersion) % 10000 }
}
}
-// Note: The KEIL 8051 compiler does not support the predefined
-// macros dumping. So, we do it with following trick where we try
-// to compile a temporary file and to parse the console output.
-function dumpC51CompilerMacros(compilerFilePath, tag) {
- // C51 compiler support only C language.
+function dumpMcsCompilerMacros(compilerFilePath, tag) {
+ // C51 or C251 compiler support only C language.
if (tag === "cpp")
return {};
- function createDumpMacrosFile() {
- var td = new TemporaryDir();
- var fn = FileInfo.fromNativeSeparators(td.path() + "/dump-macros.c");
- var tf = new TextFile(fn, TextFile.WriteOnly);
- tf.writeLine("#define VALUE_TO_STRING(x) #x");
- tf.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
- tf.writeLine("#define VAR_NAME_VALUE(var) \"\"\"|\"#var\"|\"VALUE(var)");
- tf.writeLine("#ifdef __C51__");
- tf.writeLine("#pragma message(VAR_NAME_VALUE(__C51__))");
- tf.writeLine("#endif");
- tf.close();
- return fn;
+ // Note: The C51 or C251 compiler does not support the predefined
+ // macros dumping. So, we do it with the following trick, where we try
+ // to create and compile a special temporary file and to parse the console
+ // output with the own magic pattern: (""|"key"|"value"|"").
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.fromNativeSeparators(FileInfo.joinPaths(outputDirectory.path(),
+ "dump-macros.c"));
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+
+ outputFile.writeLine("#define VALUE_TO_STRING(x) #x");
+ outputFile.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
+
+ // Predefined keys for C51 and C251 compilers, see details:
+ // * https://www.keil.com/support/man/docs/c51/c51_pp_predefmacroconst.htm
+ // * https://www.keil.com/support/man/docs/c251/c251_pp_predefmacroconst.htm
+ var keys = ["__C51__", "__CX51__", "__C251__", "__MODEL__",
+ "__STDC__", "__FLOAT64__", "__MODSRC__"];
+
+ // For C51 compiler.
+ outputFile.writeLine("#if defined(__C51__) || defined(__CX51__)");
+ outputFile.writeLine("# define VAR_NAME_VALUE(var) \"(\"\"\"\"|\"#var\"|\"VALUE(var)\"|\"\"\"\")\"");
+ for (var i in keys) {
+ var key = keys[i];
+ outputFile.writeLine("# if defined (" + key + ")");
+ outputFile.writeLine("# pragma message (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("# endif");
+ }
+ outputFile.writeLine("#endif");
+
+ // For C251 compiler.
+ outputFile.writeLine("#if defined(__C251__)");
+ outputFile.writeLine("# define VAR_NAME_VALUE(var) \"\"|#var|VALUE(var)|\"\"");
+ for (var i in keys) {
+ var key = keys[i];
+ outputFile.writeLine("# if defined (" + key + ")");
+ outputFile.writeLine("# warning (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("# endif");
}
+ outputFile.writeLine("#endif");
- var fn = createDumpMacrosFile();
- var p = new Process();
- p.exec(compilerFilePath, [ fn ], false);
+ outputFile.close();
+
+ var process = new Process();
+ process.exec(compilerFilePath, [outputFilePath], false);
+ File.remove(outputFilePath);
var map = {};
- p.readStdOut().trim().split(/\r?\n/g).map(function(line) {
- var parts = line.split("\"|\"", 3);
- map[parts[1]] = parts[2];
+ process.readStdOut().trim().split(/\r?\n/g).map(function(line) {
+ var parts = line.split("\"|\"", 4);
+ if (parts.length === 4)
+ map[parts[1]] = parts[2];
});
return map;
}
-function dumpArmCompilerMacros(compilerFilePath, tag, nullDevice) {
- var args = [ "-E", "--list-macros", nullDevice ];
+function dumpC166CompilerMacros(compilerFilePath, tag) {
+ // C166 compiler support only C language.
if (tag === "cpp")
- args.push("--cpp");
+ return {};
- var p = new Process();
- p.exec(compilerFilePath, args, false);
- var map = {};
- p.readStdOut().trim().split(/\r?\n/g).map(function (line) {
- if (!line.startsWith("#define"))
- return;
- var parts = line.split(" ", 3);
- map[parts[1]] = parts[2];
- });
- return map;
-}
+ // Note: The C166 compiler does not support the predefined
+ // macros dumping. Also, it does not support the '#pragma' and
+ // '#message|warning|error' directives properly (it is impossible
+ // to print to console the value of macro).
+ // So, we do it with the following trick, where we try
+ // to create and compile a special temporary file and to parse the console
+ // output with the own magic pattern, e.g:
+ //
+ // *** WARNING C320 IN LINE 41 OF c51.c: __C166__
+ // *** WARNING C2 IN LINE 42 OF c51.c: '757': unknown #pragma/control, line ignored
+ //
+ // where the '__C166__' is a key, and the '757' is a value.
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.fromNativeSeparators(outputDirectory.path() + "/dump-macros.c");
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+
+ // Predefined keys for C166 compiler, see details:
+ // * https://www.keil.com/support/man/docs/c166/c166_pp_predefmacroconst.htm
+ var keys = ["__C166__", "__DUS__", "__MAC__", "__MOD167__",
+ "__MODEL__", "__MODV2__", "__SAVEMAC__", "__STDC__"];
+
+ // For C166 compiler.
+ outputFile.writeLine("#if defined(__C166__)");
+ for (var i in keys) {
+ var key = keys[i];
+ outputFile.writeLine("# if defined (" + key + ")");
+ outputFile.writeLine("# warning " + key);
+ outputFile.writeLine("# pragma " + key);
+ outputFile.writeLine("# endif");
+ }
+ outputFile.writeLine("#endif");
-function dumpMacros(compilerFilePath, tag, nullDevice) {
- var map1 = dumpC51CompilerMacros(compilerFilePath, tag, nullDevice);
- var map2 = dumpArmCompilerMacros(compilerFilePath, tag, nullDevice);
- var map = {};
- for (var key1 in map1)
- map[key1] = map1[key1];
- for (var key2 in map2)
- map[key2] = map2[key2];
- return map;
-}
+ outputFile.close();
-function dumpDefaultPaths(compilerFilePath, architecture) {
- var incDir = (architecture === "arm") ? "include" : "inc";
- var includePath = compilerFilePath.replace(/bin[\\\/](.*)$/i, incDir);
- return {
- "includePaths": [includePath]
+ function extractKey(line, knownKeys) {
+ for (var i in keys) {
+ var key = knownKeys[i];
+ var regexp = new RegExp("^\\*\\*\\* WARNING C320 IN LINE .+: (" + key + ")$");
+ var match = regexp.exec(line);
+ if (match)
+ return key;
+ }
};
-}
-
-function adjustPathsToWindowsSeparators(sourcePaths) {
- var resulingPaths = [];
- sourcePaths.forEach(function(path) {
- resulingPaths.push(FileInfo.toWindowsSeparators(path));
- });
- return resulingPaths;
-}
-function getMaxExitCode(architecture) {
- if (architecture === "mcs51")
- return 1;
- else if (architecture === "arm")
- return 0;
-}
+ function extractValue(line) {
+ var regexp = new RegExp("^\\*\\*\\* WARNING C2 IN LINE .+'(.+)':.+$");
+ var match = regexp.exec(line);
+ if (match)
+ return match[1];
+ };
-function collectLibraryDependencies(product) {
- var seen = {};
- var result = [];
+ var process = new Process();
+ process.exec(compilerFilePath, [outputFilePath], false);
+ File.remove(outputFilePath);
+ var lines = process.readStdOut().trim().split(/\r?\n/g);
+ var map = {};
+ for (var i = 0; i < lines.length; ++i) {
+ // First line should contains the macro key.
+ var keyLine = lines[i];
+ var key = extractKey(keyLine, keys);
+ if (!key)
+ continue;
+
+ i += 1;
+ if (i >= lines.length)
+ break;
- function addFilePath(filePath) {
- result.push({ filePath: filePath });
+ // Second line should contains the macro value.
+ var valueLine = lines[i];
+ var value = extractValue(valueLine);
+ if (!value)
+ continue;
+ map[key] = value;
}
+ return map;
+}
- function addArtifactFilePaths(dep, artifacts) {
- if (!artifacts)
- return;
- var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
- artifactFilePaths.forEach(addFilePath);
- }
+function dumpArmCCCompilerMacros(compilerFilePath, tag, nullDevice) {
+ var args = [ "-E", "--list-macros", "--cpu=cortex-m0", nullDevice ];
+ if (tag === "cpp")
+ args.push("--cpp");
- function addExternalStaticLibs(obj) {
- if (!obj.cpp)
- return;
- function ensureArray(a) {
- return Array.isArray(a) ? a : [];
- }
- function sanitizedModuleListProperty(obj, moduleName, propertyName) {
- return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
- }
- var externalLibs = [].concat(
- sanitizedModuleListProperty(obj, "cpp", "staticLibraries"));
- var staticLibrarySuffix = obj.moduleProperty("cpp", "staticLibrarySuffix");
- externalLibs.forEach(function(staticLibraryName) {
- if (!staticLibraryName.endsWith(staticLibrarySuffix))
- staticLibraryName += staticLibrarySuffix;
- addFilePath(staticLibraryName);
- });
- }
+ var p = new Process();
+ p.exec(compilerFilePath, args, false);
+ return Cpp.extractMacros(p.readStdOut());
+}
- function traverse(dep) {
- if (seen.hasOwnProperty(dep.name))
- return;
- seen[dep.name] = true;
+function dumpArmClangCompilerMacros(compilerFilePath, tag, nullDevice) {
+ var args = [ "--target=arm-arm-none-eabi", "-mcpu=cortex-m0", "-dM", "-E",
+ "-x", ((tag === "cpp") ? "c++" : "c"), nullDevice ];
+ var p = new Process();
+ p.exec(compilerFilePath, args, false);
+ return Cpp.extractMacros(p.readStdOut());
+}
- if (dep.parameters.cpp && dep.parameters.cpp.link === false)
- return;
+function dumpMacros(compilerFilePath, tag, nullDevice) {
+ if (isMcsCompiler(compilerFilePath))
+ return dumpMcsCompilerMacros(compilerFilePath, tag, nullDevice);
+ else if (isC166Compiler(compilerFilePath))
+ return dumpC166CompilerMacros(compilerFilePath, tag, nullDevice);
+ else if (isArmCCCompiler(compilerFilePath))
+ return dumpArmCCCompilerMacros(compilerFilePath, tag, nullDevice);
+ else if (isArmClangCompiler(compilerFilePath))
+ return dumpArmClangCompilerMacros(compilerFilePath, tag, nullDevice);
+ return {};
+}
- var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
- if (staticLibraryArtifacts) {
- dep.dependencies.forEach(traverse);
- addArtifactFilePaths(dep, staticLibraryArtifacts);
- addExternalStaticLibs(dep);
- }
- }
+function dumpMcsCompilerIncludePaths(compilerFilePath) {
+ var includePath = compilerFilePath.replace(/bin[\\\/](.*)$/i, "inc");
+ return [includePath];
+}
- product.dependencies.forEach(traverse);
- addExternalStaticLibs(product);
- return result;
-}
-
-function filterStdOutput(cmd) {
- cmd.stdoutFilterFunction = function(output) {
- var sourceLines = output.split("\n");
- var filteredLines = [];
- for (var i in sourceLines) {
- if (sourceLines[i].startsWith("***")
- || sourceLines[i].startsWith(">>")
- || sourceLines[i].startsWith(" ")
- || sourceLines[i].startsWith("Program Size:")
- || sourceLines[i].startsWith("A51 FATAL")
- || sourceLines[i].startsWith("C51 FATAL")
- || sourceLines[i].startsWith("ASSEMBLER INVOKED BY")
- || sourceLines[i].startsWith("LOC OBJ LINE SOURCE")
- ) {
- filteredLines.push(sourceLines[i]);
- } else {
- var regexp = /^([0-9A-F]{4})/;
- if (regexp.exec(sourceLines[i]))
- filteredLines.push(sourceLines[i]);
- }
- }
- return filteredLines.join("\n");
- };
+function dumpC166CompilerIncludePaths(compilerFilePath) {
+ // Same as for MCS compiler.
+ return dumpMcsCompilerIncludePaths(compilerFilePath);
}
-function compilerOutputArtifacts(input, useListing) {
- var artifacts = [];
- artifacts.push({
- fileTags: ["obj"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + input.cpp.objectSuffix
- });
- if (useListing) {
- artifacts.push({
- fileTags: ["lst"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + (input.cpp.architecture === "mcs51"
- ? input.fileName : input.baseName)
- + ".lst"
- });
- }
- return artifacts;
+function dumpArmCCCompilerIncludePaths(compilerFilePath) {
+ var includePath = compilerFilePath.replace(/bin[\\\/](.*)$/i, "include");
+ return [includePath];
}
-function applicationLinkerOutputArtifacts(product) {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var mem_map = {
- fileTags: ["mem_map"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName
- + (product.cpp.architecture === "mcs51" ? ".m51" : ".map"))
- };
- return [app, mem_map];
+function dumpArmClangCompilerIncludePaths(compilerFilePath, nullDevice) {
+ var args = [ "--target=arm-arm-none-eabi", "-mcpu=cortex-m0", "-v", "-E",
+ "-x", "c++", nullDevice ];
+ var p = new Process();
+ p.exec(compilerFilePath, args, false);
+ var lines = p.readStdErr().trim().split(/\r?\n/g).map(function (line) { return line.trim(); });
+ var addIncludes = false;
+ var includePaths = [];
+ for (var i = 0; i < lines.length; ++i) {
+ var line = lines[i];
+ if (line === "#include <...> search starts here:")
+ addIncludes = true;
+ else if (line === "End of search list.")
+ addIncludes = false;
+ else if (addIncludes)
+ includePaths.push(line);
+ }
+ return includePaths;
}
-function staticLibraryLinkerOutputArtifacts(product) {
- var staticLib = {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
- };
- return [staticLib]
+function dumpDefaultPaths(compilerFilePath, nullDevice) {
+ var includePaths = [];
+ if (isMcsCompiler(compilerFilePath))
+ includePaths = dumpMcsCompilerIncludePaths(compilerFilePath);
+ else if (isC166Compiler(compilerFilePath))
+ includePaths = dumpC166CompilerIncludePaths(compilerFilePath);
+ else if (isArmCCCompiler(compilerFilePath))
+ includePaths = dumpArmCCCompilerIncludePaths(compilerFilePath);
+ else if (isArmClangCompiler(compilerFilePath))
+ includePaths = dumpArmClangCompilerIncludePaths(compilerFilePath, nullDevice);
+ return { "includePaths": includePaths };
}
+function filterMcsOutput(output) {
+ var filteredLines = [];
+ output.split(/\r\n|\r|\n/).forEach(function(line) {
+ var regexp = /^\s*\*{3}\s|^\s{29}|^\s{4}\S|^\s{2}[0-9A-F]{4}|^\s{21,25}\d+|^[0-9A-F]{4}\s\d+/;
+ if (regexp.exec(line))
+ filteredLines.push(line);
+ });
+ return filteredLines.join('\n');
+};
+
+function filterC166Output(output) {
+ var filteredLines = [];
+ output.split(/\r\n|\r|\n/).forEach(function(line) {
+ var regexp = /^\s*\*{3}\s|^\s{29}|^\s{27,28}\d+|^\s{21}\d+|^\s{4}\S|^\s{2}[0-9A-F]{4}|^[0-9A-F]{4}\s\d+/;
+ if (regexp.exec(line))
+ filteredLines.push(line);
+ });
+ return filteredLines.join('\n');
+};
+
function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Determine which C-language we're compiling.
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
var args = [];
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
-
- 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);
-
var architecture = input.qbs.architecture;
- if (architecture === "mcs51") {
+ if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
// Input.
- args.push(FileInfo.toWindowsSeparators(input.filePath));
+ args.push(input.filePath);
// Output.
- args.push("OBJECT (" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")");
+ args.push("OBJECT(" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")");
// Defines.
- if (allDefines.length > 0)
- args = args.concat("DEFINE (" + allDefines.join(",") + ")");
+ var defines = Cpp.collectDefines(input);
+ if (defines.length > 0)
+ args = args.concat("DEFINE (" + defines.join(",") + ")");
// Includes.
- if (allIncludePaths.length > 0) {
- var adjusted = adjustPathsToWindowsSeparators(allIncludePaths);
- args = args.concat("INCDIR (" + adjusted.join(";") + ")");
- }
+ var allIncludePaths = [].concat(Cpp.collectIncludePaths(input),
+ Cpp.collectSystemIncludePaths(input));
+ if (allIncludePaths.length > 0)
+ args = args.concat("INCDIR(" + allIncludePaths.map(function(path) {
+ return FileInfo.toWindowsSeparators(path); }).join(";") + ")");
// Debug information flags.
if (input.cpp.debugInformation)
@@ -440,153 +514,191 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
break;
case "all":
args.push("WARNINGLEVEL (2)");
- args.push("FARWARNING");
+ if (isMcs51Architecture(architecture))
+ args.push("FARWARNING");
break;
}
// Listing files generation flag.
- if (!product.cpp.generateCompilerListingFiles)
+ if (!input.cpp.generateCompilerListingFiles)
args.push("NOPRINT");
else
args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.lst[0].filePath) + ")");
- } else if (architecture === "arm") {
+ } else if (isArmArchitecture(architecture)) {
// Input.
args.push("-c", input.filePath);
// Output.
args.push("-o", outputs.obj[0].filePath);
+ // Preinclude headers.
+ args = args.concat(Cpp.collectPreincludePathsArguments(input, true));
+
// Defines.
- args = args.concat(allDefines.map(function(define) { return '-D' + define }));
+ args = args.concat(Cpp.collectDefinesArguments(input));
// Includes.
- args = args.concat(allIncludePaths.map(function(include) { return '-I' + include }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
+
+ var compilerPath = input.cpp.compilerPath;
+ if (isArmCCCompiler(compilerPath)) {
+ // Debug information flags.
+ if (input.cpp.debugInformation) {
+ args.push("--debug");
+ args.push("-g");
+ }
- // 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")
+ break;
+ case "fast":
+ args.push("-Otime")
+ break;
+ case "none":
+ args.push("-O0")
+ break;
+ }
- // Optimization level flags.
- switch (input.cpp.optimization) {
- case "small":
- args.push("-Ospace")
- break;
- case "fast":
- args.push("-Otime")
- break;
- case "none":
- args.push("-O0")
- break;
- }
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "none":
+ args.push("-W");
+ break;
+ default:
+ // By default all warnings are enabled.
+ break;
+ }
- // Warning level flags.
- switch (input.cpp.warningLevel) {
- case "none":
- args.push("-W");
- break;
- default:
- // By default all warnings are enabled.
- break;
- }
+ if (tag === "c") {
+ // 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") {
+ // 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");
+ }
- if (tag === "c") {
- // C language version flags.
- var knownCLanguageValues = ["c99", "c90"];
- var cLanguageVersion = Cpp.languageVersion(
- input.cpp.cLanguageVersion, knownCLanguageValues, "C");
- switch (cLanguageVersion) {
- case "c99":
- args.push("--c99");
+ // Listing files generation flag.
+ if (input.cpp.generateCompilerListingFiles) {
+ args.push("--list");
+ args.push("--list_dir", FileInfo.path(outputs.lst[0].filePath));
+ }
+ } else if (isArmClangCompiler(compilerPath)) {
+ // Debug information flags.
+ if (input.cpp.debugInformation)
+ args.push("-g");
+
+ // Optimization level flags.
+ switch (input.cpp.optimization) {
+ case "small":
+ args.push("-Oz")
+ break;
+ case "fast":
+ args.push("-Ofast")
break;
- case "c90":
- args.push("--c90");
+ case "none":
+ args.push("-O0")
break;
}
- } else if (tag === "cpp") {
- // 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");
+
+ // Warning level flags.
+ switch (input.cpp.warningLevel) {
+ case "all":
+ args.push("-Wall");
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");
- }
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("-Werror");
+
+ if (tag === "c") {
+ // C language version flags.
+ var knownCLanguageValues = ["c11", "c99", "c90", "c89"];
+ var cLanguageVersion = Cpp.languageVersion(
+ input.cpp.cLanguageVersion, knownCLanguageValues, "C");
+ if (cLanguageVersion)
+ args.push("-std=" + cLanguageVersion);
+ } else if (tag === "cpp") {
+ // C++ language version flags.
+ var knownCppLanguageValues = ["c++17", "c++14", "c++11", "c++03", "c++98"];
+ var cppLanguageVersion = Cpp.languageVersion(
+ input.cpp.cxxLanguageVersion, knownCppLanguageValues, "C++");
+ if (cppLanguageVersion)
+ args.push("-std=" + cppLanguageVersion);
+
+ // Exceptions flags.
+ var enableExceptions = input.cpp.enableExceptions;
+ if (enableExceptions !== undefined)
+ args.push(enableExceptions ? "-fexceptions" : "-fno-exceptions");
+
+ // RTTI flags.
+ var enableRtti = input.cpp.enableRtti;
+ if (enableRtti !== undefined)
+ args.push(enableRtti ? "-frtti" : "-fno-rtti");
+ }
- // Listing files generation flag.
- if (product.cpp.generateCompilerListingFiles) {
- args.push("--list");
- args.push("--list_dir", FileInfo.path(outputs.lst[0].filePath));
+ // Listing files generation does not supported!
+ // There are only a workaround: http://www.keil.com/support/docs/4152.htm
}
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
- ModUtils.moduleProperty(input, "flags"),
- ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(input));
return args;
}
function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
- // Determine which C-language we're compiling
- var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
var args = [];
-
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
-
- 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);
-
var architecture = input.qbs.architecture;
- if (architecture === "mcs51") {
+ if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
// Input.
- args.push(FileInfo.toWindowsSeparators(input.filePath));
+ args.push(input.filePath);
// Output.
- args.push("OBJECT (" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")");
-
- // Defines.
- if (allDefines.length > 0)
- args = args.concat("DEFINE (" + allDefines.join(",") + ")");
+ args.push("OBJECT(" + FileInfo.toWindowsSeparators(outputs.obj[0].filePath) + ")");
// Includes.
- if (allIncludePaths.length > 0) {
- var adjusted = adjustPathsToWindowsSeparators(allIncludePaths);
- args = args.concat("INCDIR (" + adjusted.join(";") + ")");
- }
+ var allIncludePaths = [].concat(Cpp.collectIncludePaths(input),
+ Cpp.collectSystemIncludePaths(input));
+ if (allIncludePaths.length > 0)
+ args = args.concat("INCDIR(" + allIncludePaths.map(function(path) {
+ return FileInfo.toWindowsSeparators(path); }).join(";") + ")");
// Debug information flags.
if (input.cpp.debugInformation)
@@ -596,31 +708,20 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("EP");
// Listing files generation flag.
- if (!product.cpp.generateAssemblerListingFiles)
+ if (!input.cpp.generateAssemblerListingFiles)
args.push("NOPRINT");
else
args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.lst[0].filePath) + ")");
- } else if (architecture === "arm") {
+ } else if (isArmArchitecture(architecture)) {
// Input.
args.push(input.filePath);
// Output.
args.push("-o", outputs.obj[0].filePath);
- // Defines.
- allDefines.forEach(function(define) {
- var parts = define.split("=");
- args.push("--pd");
- if (parts[1] === undefined)
- args.push(parts[0] + " SETA " + 1);
- else if (parts[1].contains("\""))
- args.push(parts[0] + " SETS " + parts[1]);
- else
- args.push(parts[0] + " SETA " + parts[1]);
- });
-
// Includes.
- args = args.concat(allIncludePaths.map(function(include) { return '-I' + include }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
// Debug information flags.
if (input.cpp.debugInformation) {
@@ -638,72 +739,86 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push((endianness === "little") ? "--littleend" : "--bigend");
// Listing files generation flag.
- if (product.cpp.generateAssemblerListingFiles)
+ if (input.cpp.generateAssemblerListingFiles)
args.push("--list", outputs.lst[0].filePath);
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+ return args;
+}
+
+function disassemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = ["--disassemble", "--interleave=source"];
+ args.push(outputs.obj[0].filePath);
+ args.push("--output=" + outputs.lst[0].filePath);
return args;
}
-function linkerFlags(project, product, input, outputs) {
+function linkerFlags(project, product, inputs, outputs) {
var args = [];
+ var libraryPaths = Cpp.collectLibraryPaths(product);
+
var architecture = product.qbs.architecture;
- if (architecture === "mcs51") {
- // Note: The C51 linker does not distinguish an object files and
+ if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
+ // Semi-intelligent handling the library paths.
+ // We need to add the full path prefix to the library file if this
+ // file is not absolute or not relative. Reason is that the C51, C251,
+ // and C166 linkers does not support the library paths.
+ function collectLibraryObjectPaths(product) {
+ var libraryObjects = Cpp.collectLibraryDependencies(product);
+ return libraryObjects.map(function(dep) {
+ var filePath = dep.filePath;
+ if (FileInfo.isAbsolutePath(filePath))
+ return filePath;
+ for (var i = 0; i < libraryPaths.length; ++i) {
+ var fullPath = FileInfo.joinPaths(libraryPaths[i], filePath);
+ if (File.exists(fullPath))
+ return fullPath;
+ }
+ return filePath;
+ });
+ }
+
+ // Note: The C51, C251, or C166 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);
+ function collectAllObjectPathsArguments(product, inputs) {
+ return [].concat(Cpp.collectLinkerObjectPaths(inputs),
+ collectLibraryObjectPaths(product));
}
- // Inputs.
- if (inputs.obj)
- inputs.obj.map(function(obj) { addObjectPath(obj) });
-
- // 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(","));
+ var allObjectPaths = collectAllObjectPathsArguments(product, inputs);
+ if (allObjectPaths.length > 0)
+ args = args.concat(allObjectPaths.map(function(path) {
+ return FileInfo.toWindowsSeparators(path); }).join(","));
// 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) + '"');
+ args.push("TO", FileInfo.toWindowsSeparators(outputs.application[0].filePath));
// Map file generation flag.
if (!product.cpp.generateLinkerMapFile)
- args.push("NOMAP");
- } else if (architecture === "arm") {
+ args.push("NOPRINT");
+ else
+ args.push("PRINT(" + FileInfo.toWindowsSeparators(outputs.mem_map[0].filePath) + ")");
+ } else if (isArmArchitecture(architecture)) {
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
// Output.
args.push("--output", outputs.application[0].filePath);
// Library paths.
- var libraryPaths = product.cpp.libraryPaths;
- if (libraryPaths)
- args.push("--userlibpath=" + libraryPaths.join(","));
+ if (libraryPaths.length > 0)
+ args.push(product.cpp.libraryPathFlag + libraryPaths.join(","));
// Library dependencies.
- var libraryDependencies = collectLibraryDependencies(product);
- args = args.concat(libraryDependencies.map(function(dep) { return dep.filePath; }));
+ args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
- // Debug information flag.
- var debugInformation = product.cpp.debugInformation;
- if (debugInformation !== undefined)
- args.push(debugInformation ? "--debug" : "--no_debug");
+ // Linker scripts.
+ args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs, true));
// Map file generation flag.
if (product.cpp.generateLinkerMapFile)
@@ -713,43 +828,38 @@ function linkerFlags(project, product, input, outputs) {
if (product.cpp.entryPoint)
args.push("--entry", product.cpp.entryPoint);
- // Linker scripts flags.
- var linkerScripts = inputs.linkerscript
- ? inputs.linkerscript.map(function(a) { return a.filePath; }) : [];
- linkerScripts.forEach(function(script) { args.push("--scatter", script); });
+ // Debug information flag.
+ var debugInformation = product.cpp.debugInformation;
+ if (debugInformation !== undefined)
+ args.push(debugInformation ? "--debug" : "--no_debug");
}
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(product, "driverLinkerFlags"));
+ args = args.concat(Cpp.collectMiscEscapableLinkerArguments(product),
+ Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
return args;
}
-function archiverFlags(project, product, input, outputs) {
+function archiverFlags(project, product, inputs, outputs) {
var args = [];
+ // Inputs.
+ var objectPaths = Cpp.collectLinkerObjectPaths(inputs);
+
var architecture = product.qbs.architecture;
- if (architecture === "mcs51") {
+ if (isMcsArchitecture(architecture) || isC166Architecture(architecture)) {
// Library creation command.
args.push("TRANSFER");
- 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(","));
+ if (objectPaths.length > 0)
+ args = args.concat(objectPaths.map(function(path) {
+ return FileInfo.toWindowsSeparators(path); }).join(","));
// 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") {
+ args.push("TO", FileInfo.toWindowsSeparators(outputs.staticlibrary[0].filePath));
+ } else if (isArmArchitecture(architecture)) {
// Note: The ARM archiver command line expect the output file
// first, and then a set of input objects.
@@ -757,8 +867,7 @@ function archiverFlags(project, product, input, outputs) {
args.push("--create", outputs.staticlibrary[0].filePath);
// Inputs.
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(objectPaths);
// Debug information flag.
if (product.cpp.debugInformation)
@@ -768,48 +877,116 @@ function archiverFlags(project, product, input, outputs) {
return args;
}
+// The ARMCLANG compiler does not support generation
+// for the listing files:
+// * https://www.keil.com/support/docs/4152.htm
+// So, we generate the listing files from the object files
+// using the disassembler.
+function generateClangCompilerListing(project, product, inputs, outputs, input, output) {
+ if (isArmClangCompiler(input.cpp.compilerPath) && input.cpp.generateCompilerListingFiles) {
+ var args = disassemblerFlags(project, product, input, outputs, explicitlyDependsOn);
+ var disassemblerPath = input.cpp.disassemblerPath;
+ var cmd = new Command(disassemblerPath, args);
+ cmd.silent = true;
+ return cmd;
+ }
+}
+
+// The ARMCC compiler generates the listing files only in a short form,
+// e.g. to 'module.lst' instead of 'module.{c|cpp}.lst', that complicates
+// the auto-tests. Therefore we need to rename generated listing files
+// with correct unified names.
+function generateArmccCompilerListing(project, product, inputs, outputs, input, output) {
+ if (isArmCCCompiler(input.cpp.compilerPath) && input.cpp.generateCompilerListingFiles) {
+ var listingPath = FileInfo.path(outputs.lst[0].filePath);
+ var cmd = new JavaScriptCommand();
+ cmd.oldListing = FileInfo.joinPaths(listingPath, input.baseName + ".lst");
+ cmd.newListing = FileInfo.joinPaths(
+ listingPath, input.fileName + input.cpp.compilerListingSuffix);
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.move(oldListing, newListing); };
+ return cmd;
+ }
+}
+
function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
var compilerPath = input.cpp.compilerPath;
var architecture = input.cpp.architecture;
var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
- cmd.maxExitCode = getMaxExitCode(architecture);
- filterStdOutput(cmd);
- return [cmd];
-}
+ cmd.jobPool = "compiler";
+ if (isMcsArchitecture(architecture)) {
+ cmd.maxExitCode = 1;
+ cmd.stdoutFilterFunction = filterMcsOutput;
+ } else if (isC166Architecture(architecture)) {
+ cmd.maxExitCode = 1;
+ cmd.stdoutFilterFunction = filterC166Output;
+ }
+ cmds.push(cmd);
+
+ cmd = generateClangCompilerListing(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+ cmd = generateArmccCompilerListing(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+
+ return cmds;
+}
function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn);
var assemblerPath = input.cpp.assemblerPath;
+ var architecture = input.cpp.architecture;
var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
- filterStdOutput(cmd);
+ cmd.jobPool = "assembler";
+ if (isMcsArchitecture(architecture)) {
+ cmd.maxExitCode = 1;
+ cmd.stdoutFilterFunction = filterMcsOutput;
+ } else if (isC166Architecture(architecture)) {
+ cmd.maxExitCode = 1;
+ cmd.stdoutFilterFunction = filterC166Output;
+ }
return [cmd];
}
function prepareLinker(project, product, inputs, outputs, input, output) {
var primaryOutput = outputs.application[0];
- var args = linkerFlags(project, product, input, outputs);
+ var args = linkerFlags(project, product, inputs, outputs);
var linkerPath = product.cpp.linkerPath;
var architecture = product.cpp.architecture;
var cmd = new Command(linkerPath, args);
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
- cmd.maxExitCode = getMaxExitCode(architecture);
- filterStdOutput(cmd);
+ cmd.jobPool = "linker";
+ if (isMcsArchitecture(architecture)) {
+ cmd.maxExitCode = 1;
+ cmd.stdoutFilterFunction = filterMcsOutput;
+ } else if (isC166Architecture(architecture)) {
+ cmd.maxExitCode = 1;
+ cmd.stdoutFilterFunction = filterC166Output;
+ }
return [cmd];
}
function prepareArchiver(project, product, inputs, outputs, input, output) {
- var args = archiverFlags(project, product, input, outputs);
+ var args = archiverFlags(project, product, inputs, outputs);
var archiverPath = product.cpp.archiverPath;
+ var architecture = product.cpp.architecture;
var cmd = new Command(archiverPath, args);
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
- filterStdOutput(cmd);
+ cmd.jobPool = "linker";
+ if (isMcsArchitecture(architecture)) {
+ cmd.stdoutFilterFunction = filterMcsOutput;
+ } else if (isC166Architecture(architecture)) {
+ cmd.stdoutFilterFunction = filterC166Output;
+ }
return [cmd];
}
diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs
index 67ea5e675..5922ad4e2 100644
--- a/share/qbs/modules/cpp/keil.qbs
+++ b/share/qbs/modules/cpp/keil.qbs
@@ -28,15 +28,15 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.File
import qbs.FileInfo
-import qbs.ModUtils
+import qbs.Host
import qbs.Probes
+import "cpp.js" as Cpp
import "keil.js" as KEIL
CppModule {
- condition: qbs.hostOS.contains("windows") && qbs.toolchain && qbs.toolchain.contains("keil")
+ condition: Host.os().includes("windows") && qbs.toolchain && qbs.toolchain.includes("keil")
Probes.BinaryProbe {
id: compilerPathProbe
@@ -52,6 +52,7 @@ CppModule {
}
qbs.architecture: keilProbe.found ? keilProbe.architecture : original
+ qbs.targetPlatform: "none"
compilerVersionMajor: keilProbe.versionMajor
compilerVersionMinor: keilProbe.versionMinor
@@ -61,45 +62,56 @@ CppModule {
compilerDefinesByLanguage: keilProbe.compilerDefinesByLanguage
compilerIncludePaths: keilProbe.includePaths
- property string toolchainInstallPath: compilerPathProbe.found
- ? compilerPathProbe.path : undefined
-
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
property string cxxCompilerName: compilerName
- compilerName: KEIL.compilerName(qbs) + compilerExtension
+ compilerName: toolchainDetails.compilerName + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: KEIL.assemblerName(qbs) + compilerExtension
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: KEIL.linkerName(qbs) + compilerExtension
+ linkerName: toolchainDetails.linkerName + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: KEIL.archiverName(qbs) + compilerExtension
+ property string archiverName: toolchainDetails.archiverName + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
- runtimeLibrary: "static"
+ property string disassemblerName: toolchainDetails.disassemblerName + compilerExtension
+ property string disassemblerPath: FileInfo.joinPaths(toolchainInstallPath, disassemblerName)
- staticLibrarySuffix: KEIL.staticLibrarySuffix(qbs)
- executableSuffix: KEIL.executableSuffix(qbs)
+ runtimeLibrary: "static"
- property string objectSuffix: KEIL.objectSuffix(qbs)
+ staticLibrarySuffix: ".lib"
+ executableSuffix: toolchainDetails.executableSuffix
+ objectSuffix: toolchainDetails.objectSuffix
+ linkerMapSuffix: toolchainDetails.linkerMapSuffix
- imageFormat: KEIL.imageFormat(qbs)
+ imageFormat: toolchainDetails.imageFormat
enableExceptions: false
enableRtti: false
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: KEIL.preincludeFlag(compilerPath)
+ libraryDependencyFlag: ""
+ libraryPathFlag: "--userlibpath="
+ linkerScriptFlag: "--scatter"
+
+ toolchainDetails: KEIL.toolchainDetails(qbs)
+
+ knownArchitectures: ["arm", "c166", "mcs251", "mcs51"]
+
Rule {
id: assembler
inputs: ["asm"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: KEIL.compilerOutputArtifacts(
- input, input.cpp.generateAssemblerListingFiles)
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
prepare: KEIL.prepareAssembler.apply(KEIL, arguments)
}
@@ -112,9 +124,8 @@ CppModule {
id: compiler
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
- outputFileTags: ["obj", "lst"]
- outputArtifacts: KEIL.compilerOutputArtifacts(
- input, input.cpp.generateCompilerListingFiles)
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
prepare: KEIL.prepareCompiler.apply(KEIL, arguments)
}
@@ -122,8 +133,9 @@ CppModule {
id: applicationLinker
multiplex: true
inputs: ["obj", "linkerscript"]
- outputFileTags: ["application", "mem_map"]
- outputArtifacts: KEIL.applicationLinkerOutputArtifacts(product)
+ inputsFromDependencies: ["staticlibrary"]
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
prepare: KEIL.prepareLinker.apply(KEIL, arguments)
}
@@ -132,8 +144,8 @@ CppModule {
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["staticlibrary"]
- outputArtifacts: KEIL.staticLibraryLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
prepare: KEIL.prepareArchiver.apply(KEIL, arguments)
}
}
diff --git a/share/qbs/modules/cpp/macos-gcc.qbs b/share/qbs/modules/cpp/macos-gcc.qbs
index 612b46ae8..c667bbc29 100644
--- a/share/qbs/modules/cpp/macos-gcc.qbs
+++ b/share/qbs/modules/cpp/macos-gcc.qbs
@@ -33,8 +33,8 @@ import qbs.Utilities
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('macos') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('macos') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
targetSystem: "macosx" + (minimumMacosVersion || "")
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index b67ab811f..1700c21b3 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -28,6 +28,7 @@
**
****************************************************************************/
+var Codesign = require("../codesign/codesign.js");
var Cpp = require("cpp.js");
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
@@ -35,6 +36,22 @@ var ModUtils = require("qbs.ModUtils");
var Utilities = require("qbs.Utilities");
var WindowsUtils = require("qbs.WindowsUtils");
+function effectiveLinkerPath(product, inputs) {
+ if (product.cpp.linkerMode === "automatic") {
+ var compiler = product.cpp.compilerPath;
+ if (compiler) {
+ if (inputs.obj || inputs.staticlibrary) {
+ console.log("Found C/C++ objects, using compiler as a linker for " + product.name);
+ return compiler;
+ }
+ }
+
+ console.log("Found no C-language objects, choosing system linker for " + product.name);
+ }
+
+ return product.cpp.linkerPath;
+}
+
function handleCpuFeatures(input, flags) {
if (!input.qbs.architecture)
return;
@@ -62,20 +79,54 @@ function hasCxx17Option(input)
{
// Probably this is not the earliest version to support the flag, but we have tested this one
// and it's a pain to find out the exact minimum.
- return Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0
- || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 7);
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 7)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0;
+}
+
+function hasZCplusPlusOption(input)
+{
+ // /Zc:__cplusplus is supported starting from Visual Studio 15.7
+ // Looks like closest MSVC version is 14.14.26428 (cl ver 19.14.26433)
+ // At least, this version is tested
+ // https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus
+ // clang-cl supports this option starting around-ish versions 8/9, but it
+ // ignores this option, so this doesn't really matter
+ // https://reviews.llvm.org/D45877
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 9)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.14.26433") >= 0;
}
-function addLanguageVersionFlag(input, args) {
+function hasCxx20Option(input)
+{
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 13)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30133.0") >= 0;
+}
+
+function hasCVerOption(input)
+{
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 13)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30138.0") >= 0;
+}
+
+function supportsExternalIncludesOption(input) {
+ if (input.qbs.toolchain.includes("clang-cl"))
+ return false; // Exclude clang-cl.
+ // This option was introcuded since MSVC 2017 v15.6 (aka _MSC_VER 19.13).
+ // But due to some MSVC bugs:
+ // * https://developercommunity.visualstudio.com/content/problem/181006/externali-include-paths-not-working.html
+ // this option has been fixed since MSVC 2017 update 9, v15.9 (aka _MSC_VER 19.16).
+ return Utilities.versionCompare(input.cpp.compilerVersion, "19.16") >= 0;
+}
+
+function addCxxLanguageVersionFlag(input, args) {
var cxxVersion = Cpp.languageVersion(input.cpp.cxxLanguageVersion,
- ["c++17", "c++14", "c++11", "c++98"], "C++");
+ ["c++23", "c++20", "c++17", "c++14", "c++11", "c++98"], "C++");
if (!cxxVersion)
return;
- // Visual C++ 2013, Update 3
- var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0
- // or clang-cl
- || input.qbs.toolchain.contains("clang-cl");
+ // Visual C++ 2013, Update 3 or clang-cl
+ var hasStdOption = input.qbs.toolchain.includes("clang-cl")
+ || Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0;
if (!hasStdOption)
return;
@@ -84,12 +135,42 @@ function addLanguageVersionFlag(input, args) {
flag = "/std:c++14";
else if (cxxVersion === "c++17" && hasCxx17Option(input))
flag = "/std:c++17";
+ else if (cxxVersion === "c++20" && hasCxx20Option(input))
+ flag = "/std:c++20";
else if (cxxVersion !== "c++11" && cxxVersion !== "c++98")
flag = "/std:c++latest";
if (flag)
args.push(flag);
}
+function addCLanguageVersionFlag(input, args) {
+ var cVersion = Cpp.languageVersion(input.cpp.cLanguageVersion,
+ ["c17", "c11"], "C");
+ if (!cVersion)
+ return;
+
+ var hasStdOption = hasCVerOption(input);
+ if (!hasStdOption)
+ return;
+
+ var flag;
+ if (cVersion === "c17")
+ flag = "/std:c17";
+ else if (cVersion === "c11")
+ flag = "/std:c11";
+ if (flag)
+ args.push(flag);
+}
+
+function handleClangClArchitectureFlags(product, architecture, flags) {
+ if (product.qbs.toolchain.includes("clang-cl")) {
+ if (architecture === "x86")
+ flags.push("-m32");
+ else if (architecture === "x86_64")
+ flags.push("-m64");
+ }
+}
+
function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var i;
var debugInformation = input.cpp.debugInformation;
@@ -99,7 +180,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
// Determine which C-language we're compiling
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(Object.keys(outputs)));
- if (!["c", "cpp"].contains(tag))
+ if (!["c", "cpp"].includes(tag))
throw ("unsupported source language");
var enableExceptions = input.cpp.enableExceptions;
@@ -135,6 +216,8 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
break;
}
+ handleClangClArchitectureFlags(product, input.cpp.architecture, args);
+
if (debugInformation) {
if (product.cpp.separateDebugInformation)
args.push('/Zi');
@@ -150,6 +233,8 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
args.push(rtl);
}
+ args = args.concat(Cpp.collectMiscDriverArguments(product));
+
// warnings:
var warningLevel = input.cpp.warningLevel;
if (warningLevel === 'none')
@@ -158,24 +243,33 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
args.push('/Wall')
if (input.cpp.treatWarningsAsErrors)
args.push('/WX')
- var allIncludePaths = [];
- var includePaths = input.cpp.includePaths;
- if (includePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- var systemIncludePaths = input.cpp.systemIncludePaths;
- if (systemIncludePaths)
- allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
- for (i in allIncludePaths)
- args.push('/I' + FileInfo.toWindowsSeparators(allIncludePaths[i]))
- var allDefines = [];
- var platformDefines = input.cpp.platformDefines;
- if (platformDefines)
- allDefines = allDefines.uniqueConcat(platformDefines);
- var defines = input.cpp.defines;
- if (defines)
- allDefines = allDefines.uniqueConcat(defines);
- for (i in allDefines)
- args.push('/D' + allDefines[i].replace(/%/g, "%%"));
+
+ var includePaths = Cpp.collectIncludePaths(input);
+ args = args.concat([].uniqueConcat(includePaths).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ var includeFlag = input.qbs.toolchain.includes("clang-cl")
+ ? input.cpp.systemIncludeFlag : input.cpp.includeFlag;
+ if (!input.qbs.toolchain.includes("clang-cl")) {
+ if (supportsExternalIncludesOption(input)) {
+ args.push("/experimental:external");
+ var enforcesSlashW =
+ Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30037") >= 0
+ if (enforcesSlashW)
+ args.push("/external:W0")
+ includeFlag = input.cpp.systemIncludeFlag;
+ }
+ }
+ var systemIncludePaths = Cpp.collectSystemIncludePaths(input);
+ args = args.concat([].uniqueConcat(systemIncludePaths).map(function(path) {
+ return includeFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ var defines = Cpp.collectDefines(input);
+ args = args.concat([].uniqueConcat(defines).map(function(define) {
+ return input.cpp.defineFlag + define.replace(/%/g, "%%");
+ }));
var minimumWindowsVersion = product.cpp.minimumWindowsVersion;
if (minimumWindowsVersion) {
@@ -183,7 +277,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
if (hexVersion) {
var versionDefs = [ 'WINVER', '_WIN32_WINNT', '_WIN32_WINDOWS' ];
for (i in versionDefs) {
- args.push('/D' + versionDefs[i] + '=' + hexVersion);
+ args.push(input.cpp.defineFlag + versionDefs[i] + '=' + hexVersion);
}
}
}
@@ -191,21 +285,29 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
if (product.cpp.debugInformation && product.cpp.separateDebugInformation)
args.push("/Fd" + product.targetName + ".cl" + product.cpp.debugInfoSuffix);
+ if (input.cpp.generateCompilerListingFiles)
+ args.push("/Fa" + FileInfo.toWindowsSeparators(outputs.lst[0].filePath));
+
+ if (input.cpp.enableCxxLanguageMacro && hasZCplusPlusOption(input))
+ args.push("/Zc:__cplusplus");
+
var objectMap = outputs.obj || outputs.intermediate_obj
var objOutput = objectMap ? objectMap[0] : undefined
args.push('/Fo' + FileInfo.toWindowsSeparators(objOutput.filePath))
args.push(FileInfo.toWindowsSeparators(input.filePath))
- var prefixHeaders = product.cpp.prefixHeaders;
- for (i in prefixHeaders)
- args.push("/FI" + FileInfo.toWindowsSeparators(prefixHeaders[i]));
+ var preincludePaths = Cpp.collectPreincludePaths(input);
+ args = args.concat([].uniqueConcat(preincludePaths).map(function(path) {
+ return input.cpp.preincludeFlag + FileInfo.toWindowsSeparators(path);
+ }));
// Language
if (tag === "cpp") {
args.push("/TP");
- addLanguageVersionFlag(input, args);
+ addCxxLanguageVersionFlag(input, args);
} else if (tag === "c") {
args.push("/TC");
+ addCLanguageVersionFlag(input, args);
}
// Whether we're compiling a precompiled header or normal source file
@@ -213,7 +315,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var pchInputs = explicitlyDependsOn[tag + "_pch"];
if (pchOutput) {
// create PCH
- if (input.qbs.toolchain.contains("clang-cl")) {
+ if (input.qbs.toolchain.includes("clang-cl")) {
// clang-cl does not support /Yc flag without filename
args.push("/Yc" + FileInfo.toWindowsSeparators(input.filePath));
// clang-cl complains when pch file is not included
@@ -243,10 +345,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
}
}
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags'),
- ModUtils.moduleProperty(input, 'flags'),
- ModUtils.moduleProperty(input, 'platformFlags', tag),
- ModUtils.moduleProperty(input, 'flags', tag));
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag));
var compilerPath = product.cpp.compilerPath;
var wrapperArgs = product.cpp.compilerWrapper;
@@ -272,74 +371,10 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
return [cmd];
}
-function collectLibraryDependencies(product) {
- var seen = {};
- var result = [];
-
- function addFilePath(filePath, wholeArchive, productName) {
- result.push({ filePath: filePath, wholeArchive: wholeArchive, productName: productName });
- }
-
- function addArtifactFilePaths(dep, artifacts) {
- if (!artifacts)
- return;
- var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
- var wholeArchive = dep.parameters.cpp && dep.parameters.cpp.linkWholeArchive;
- var artifactsAreImportLibs = artifacts.length > 0
- && artifacts[0].fileTags.contains("dynamiclibrary_import");
- for (var i = 0; i < artifactFilePaths.length; ++i) {
- addFilePath(artifactFilePaths[i], wholeArchive,
- artifactsAreImportLibs ? dep.name : undefined);
- }
- }
-
- function addExternalLibs(obj) {
- if (!obj.cpp)
- return;
- function ensureArray(a) {
- return Array.isArray(a) ? a : [];
- }
- function sanitizedModuleListProperty(obj, moduleName, propertyName) {
- return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
- }
- var externalLibs = [].concat(
- sanitizedModuleListProperty(obj, "cpp", "staticLibraries"),
- sanitizedModuleListProperty(obj, "cpp", "dynamicLibraries"));
- externalLibs.forEach(function (libName) {
- if (!libName.match(/\.lib$/i) && !libName.startsWith('@'))
- libName += ".lib";
- addFilePath(libName, false);
- });
- }
-
- function traverse(dep) {
- if (seen.hasOwnProperty(dep.name))
- return;
- seen[dep.name] = true;
-
- if (dep.parameters.cpp && dep.parameters.cpp.link === false)
- return;
-
- var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
- var dynamicLibraryArtifacts = staticLibraryArtifacts
- ? null : dep.artifacts["dynamiclibrary_import"];
- if (staticLibraryArtifacts) {
- dep.dependencies.forEach(traverse);
- addArtifactFilePaths(dep, staticLibraryArtifacts);
- addExternalLibs(dep);
- } else if (dynamicLibraryArtifacts) {
- addArtifactFilePaths(dep, dynamicLibraryArtifacts);
- }
- }
-
- product.dependencies.forEach(traverse);
- addExternalLibs(product);
- return result;
-}
-
function linkerSupportsWholeArchive(product)
{
- return Utilities.versionCompare(product.cpp.compilerVersion, "19.0.24215.1") >= 0
+ return product.qbs.toolchainType.includes("clang-cl") ||
+ Utilities.versionCompare(product.cpp.compilerVersion, "19.0.24215.1") >= 0
}
function handleDiscardProperty(product, flags) {
@@ -355,49 +390,76 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var linkDLL = (outputs.dynamiclibrary ? true : false)
var primaryOutput = (linkDLL ? outputs.dynamiclibrary[0] : outputs.application[0])
var debugInformation = product.cpp.debugInformation;
- var additionalManifestInputs = Array.prototype.map.call(inputs["native.pe.manifest"],
+ var additionalManifestInputs = Array.prototype.map.call(inputs["native.pe.manifest"] || [],
+ function (a) {
+ return a.filePath;
+ });
+ var moduleDefinitionInputs = Array.prototype.map.call(inputs["def"] || [],
function (a) {
return a.filePath;
});
var generateManifestFiles = !linkDLL && product.cpp.generateManifestFile;
- var canEmbedManifest = (product.cpp.compilerVersionMajor >= 17); // VS 2012
+ var useClangCl = product.qbs.toolchain.includes("clang-cl");
+ var canEmbedManifest = useClangCl || product.cpp.compilerVersionMajor >= 17 // VS 2012
+
+ var linkerPath = effectiveLinkerPath(product, inputs);
+ var useCompilerDriver = linkerPath === product.cpp.compilerPath;
+ // args variable is built as follows:
+ // [linkerWrapper] linkerPath /nologo [driverFlags driverLinkerFlags]
+ // allInputs libDeps [/link] linkerArgs
+ var args = []
+
+ if (useCompilerDriver) {
+ args.push('/nologo');
+ args = args.concat(Cpp.collectMiscDriverArguments(product),
+ Cpp.collectMiscLinkerArguments(product));
+ }
+
+ var allInputs = [].concat(Cpp.collectLinkerObjectPaths(inputs),
+ Cpp.collectResourceObjectPaths(inputs));
+ args = args.concat([].uniqueConcat(allInputs).map(function(path) {
+ return FileInfo.toWindowsSeparators(path);
+ }));
- var args = ['/nologo']
+ var linkerArgs = ['/nologo']
if (linkDLL) {
- args.push('/DLL');
- args.push('/IMPLIB:' + FileInfo.toWindowsSeparators(outputs.dynamiclibrary_import[0].filePath));
+ linkerArgs.push('/DLL');
+ linkerArgs.push('/IMPLIB:' + FileInfo.toWindowsSeparators(outputs.dynamiclibrary_import[0].filePath));
}
if (debugInformation) {
- args.push("/DEBUG");
+ linkerArgs.push("/DEBUG");
var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll;
if (debugInfo)
- args.push("/PDB:" + debugInfo[0].fileName);
+ linkerArgs.push("/PDB:" + debugInfo[0].fileName);
} else {
- args.push('/INCREMENTAL:NO')
+ linkerArgs.push('/INCREMENTAL:NO')
}
switch (product.qbs.architecture) {
case "x86":
- args.push("/MACHINE:X86");
+ linkerArgs.push("/MACHINE:X86");
break;
case "x86_64":
- args.push("/MACHINE:X64");
+ linkerArgs.push("/MACHINE:X64");
break;
case "ia64":
- args.push("/MACHINE:IA64");
+ linkerArgs.push("/MACHINE:IA64");
break;
case "armv7":
- args.push("/MACHINE:ARM");
+ linkerArgs.push("/MACHINE:ARM");
break;
case "arm64":
- args.push("/MACHINE:ARM64");
+ linkerArgs.push("/MACHINE:ARM64");
break;
}
+ if (useCompilerDriver)
+ handleClangClArchitectureFlags(product, product.qbs.architecture, args);
+
var requireAppContainer = product.cpp.requireAppContainer;
if (requireAppContainer !== undefined)
- args.push("/APPCONTAINER" + (requireAppContainer ? "" : ":NO"));
+ linkerArgs.push("/APPCONTAINER" + (requireAppContainer ? "" : ":NO"));
var minimumWindowsVersion = product.cpp.minimumWindowsVersion;
var subsystemSwitch = undefined;
@@ -407,26 +469,29 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
subsystemSwitch = product.consoleApplication === false ? '/SUBSYSTEM:WINDOWS' : '/SUBSYSTEM:CONSOLE';
}
+ var useLldLink = useCompilerDriver && product.cpp.linkerVariant === "lld"
+ || !useCompilerDriver && product.cpp.linkerName === "lld-link.exe";
if (minimumWindowsVersion) {
var subsystemVersion = WindowsUtils.getWindowsVersionInFormat(minimumWindowsVersion,
'subsystem');
if (subsystemVersion) {
subsystemSwitch += ',' + subsystemVersion;
- if (product.cpp.linkerName !== "lld-link.exe") // llvm linker does not support /OSVERSION
- args.push('/OSVERSION:' + subsystemVersion);
+ // llvm linker does not support /OSVERSION
+ if (!useLldLink)
+ linkerArgs.push('/OSVERSION:' + subsystemVersion);
}
}
if (subsystemSwitch)
- args.push(subsystemSwitch);
+ linkerArgs.push(subsystemSwitch);
var linkerOutputNativeFilePath = FileInfo.toWindowsSeparators(primaryOutput.filePath);
var manifestFileNames = [];
if (generateManifestFiles) {
if (canEmbedManifest) {
- args.push("/MANIFEST:embed");
+ linkerArgs.push("/MANIFEST:embed");
additionalManifestInputs.forEach(function (manifestFileName) {
- args.push("/MANIFESTINPUT:" + manifestFileName);
+ linkerArgs.push("/MANIFESTINPUT:" + manifestFileName);
});
} else {
linkerOutputNativeFilePath
@@ -435,20 +500,19 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
+ primaryOutput.fileName);
var manifestFileName = linkerOutputNativeFilePath + ".manifest";
- args.push('/MANIFEST', '/MANIFESTFILE:' + manifestFileName);
+ linkerArgs.push('/MANIFEST', '/MANIFESTFILE:' + manifestFileName);
manifestFileNames = [manifestFileName].concat(additionalManifestInputs);
}
}
- var allInputs = inputs.obj || [];
- for (i in allInputs) {
- var fileName = FileInfo.toWindowsSeparators(allInputs[i].filePath)
- args.push(fileName)
- }
+ if (moduleDefinitionInputs.length === 1)
+ linkerArgs.push("/DEF:" + moduleDefinitionInputs[0]);
+ else if (moduleDefinitionInputs.length > 1)
+ throw new Error("Only one '.def' file can be specified for linking");
var wholeArchiveSupported = linkerSupportsWholeArchive(product);
var wholeArchiveRequested = false;
- var libDeps = collectLibraryDependencies(product);
+ var libDeps = Cpp.collectLibraryDependencies(product);
var prevLib;
for (i = 0; i < libDeps.length; ++i) {
var dep = libDeps[i];
@@ -456,8 +520,16 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
if (lib === prevLib)
continue;
prevLib = lib;
- args.push((wholeArchiveSupported && dep.wholeArchive ? "/WHOLEARCHIVE:" : "")
- + FileInfo.toWindowsSeparators(lib));
+
+ if (wholeArchiveSupported && dep.wholeArchive) {
+ // need to pass libraries to the driver to avoid "no input files" error if no object
+ // files are specified; thus libraries are duplicated when using "WHOLEARCHIVE"
+ if (useCompilerDriver && allInputs.length === 0)
+ args.push(FileInfo.toWindowsSeparators(lib));
+ linkerArgs.push("/WHOLEARCHIVE:" + FileInfo.toWindowsSeparators(lib));
+ } else {
+ args.push(FileInfo.toWindowsSeparators(lib));
+ }
if (dep.wholeArchive)
wholeArchiveRequested = true;
}
@@ -468,25 +540,31 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
}
if (product.cpp.entryPoint)
- args.push("/ENTRY:" + product.cpp.entryPoint);
+ linkerArgs.push("/ENTRY:" + product.cpp.entryPoint);
- if (outputs.application && product.cpp.generateLinkerMapFile)
- args.push("/MAP:" + outputs.mem_map[0].filePath);
-
- args.push('/OUT:' + linkerOutputNativeFilePath)
- var libraryPaths = product.cpp.libraryPaths;
- if (libraryPaths)
- libraryPaths = [].uniqueConcat(libraryPaths);
- for (i in libraryPaths) {
- args.push('/LIBPATH:' + FileInfo.toWindowsSeparators(libraryPaths[i]))
+ if (outputs.application && product.cpp.generateLinkerMapFile) {
+ if (useLldLink)
+ linkerArgs.push("/lldmap:" + outputs.mem_map[0].filePath);
+ else
+ linkerArgs.push("/MAP:" + outputs.mem_map[0].filePath);
}
- handleDiscardProperty(product, args);
+
+ if (useCompilerDriver)
+ args.push('/Fe' + linkerOutputNativeFilePath);
+ else
+ linkerArgs.push('/OUT:' + linkerOutputNativeFilePath);
+
+ var libraryPaths = Cpp.collectLibraryPaths(product);
+ linkerArgs = linkerArgs.concat([].uniqueConcat(libraryPaths).map(function(path) {
+ return product.cpp.libraryPathFlag + FileInfo.toWindowsSeparators(path);
+ }));
+
+ handleDiscardProperty(product, linkerArgs);
var linkerFlags = product.cpp.platformLinkerFlags.concat(product.cpp.linkerFlags);
- args = args.concat(linkerFlags);
+ linkerArgs = linkerArgs.concat(linkerFlags);
if (product.cpp.allowUnresolvedSymbols)
- args.push("/FORCE:UNRESOLVED");
+ linkerArgs.push("/FORCE:UNRESOLVED");
- var linkerPath = product.cpp.linkerPath;
var wrapperArgs = product.cpp.linkerWrapper;
if (wrapperArgs && wrapperArgs.length > 0) {
args.unshift(linkerPath);
@@ -509,6 +587,10 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
}
};
commands.push(warningCmd);
+
+ if (linkerArgs.length !== 0)
+ args = args.concat(useCompilerDriver ? ['/link'] : []).concat(linkerArgs);
+
var cmd = new Command(linkerPath, args)
cmd.description = 'linking ' + primaryOutput.fileName;
cmd.highlight = 'linker';
@@ -516,9 +598,13 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
cmd.relevantEnvironmentVariables = ["LINK", "_LINK_", "LIB", "TMP"];
cmd.workingDirectory = FileInfo.path(primaryOutput.filePath)
cmd.responseFileUsagePrefix = '@';
+ cmd.responseFileSeparator = useCompilerDriver ? ' ' : '\n';
cmd.stdoutFilterFunction = function(output) {
res = output.replace(/^.*performing full link.*\s*/, "");
- return res.replace(/^ *Creating library.*\r\n$/, "");
+ res = res.replace(/^ *Creating library.*\s*/, "");
+ res = res.replace(/^\s*Generating code\s*/, "");
+ res = res.replace(/^\s*Finished generating code\s*/, "");
+ return res;
};
commands.push(cmd);
@@ -542,6 +628,12 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
commands.push(cmd);
}
+ if (product.cpp.shouldSignArtifacts) {
+ Array.prototype.push.apply(
+ commands, Codesign.prepareSigntool(
+ project, product, inputs, outputs, input, output));
+ }
+
return commands;
}
diff --git a/share/qbs/modules/cpp/qnx-qcc.qbs b/share/qbs/modules/cpp/qnx-qcc.qbs
index a39a6a998..69288ddd8 100644
--- a/share/qbs/modules/cpp/qnx-qcc.qbs
+++ b/share/qbs/modules/cpp/qnx-qcc.qbs
@@ -33,8 +33,8 @@ import qbs.FileInfo
UnixGCC {
Depends { name: "qnx" }
- condition: qbs.targetOS.contains("qnx") &&
- qbs.toolchain && qbs.toolchain.contains("qcc")
+ condition: qbs.targetOS.includes("qnx") &&
+ qbs.toolchain && qbs.toolchain.includes("qcc")
priority: 1
distributionIncludePaths: FileInfo.joinPaths(qnx.targetDir, "usr", "include")
@@ -79,7 +79,7 @@ UnixGCC {
toolchainPrefix: target + "-"
- targetVendor: ["x86", "x86_64"].contains(qbs.architecture) ? "pc" : base
+ targetVendor: ["x86", "x86_64"].includes(qbs.architecture) ? "pc" : base
targetSystem: "nto"
targetAbi: "qnx" + qnx.version + (qnxTargetArchName === "armv7le" ? "eabi" : "")
diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js
index 70d0506b9..49da8a715 100644
--- a/share/qbs/modules/cpp/sdcc.js
+++ b/share/qbs/modules/cpp/sdcc.js
@@ -28,10 +28,12 @@
**
****************************************************************************/
+var BinaryFile = require("qbs.BinaryFile");
var Cpp = require("cpp.js");
var Environment = require("qbs.Environment");
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
+var Host = require("qbs.Host");
var ModUtils = require("qbs.ModUtils");
var PathTools = require("qbs.PathTools");
var Process = require("qbs.Process");
@@ -40,34 +42,24 @@ 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";
+function toolchainDetails(qbs) {
+ var architecture = qbs.architecture;
+ if (architecture === "mcs51") {
+ return {
+ "assemblerName": "sdas8051",
+ "linkerName": "sdld"
+ }
+ } else if (architecture === "stm8") {
+ return {
+ "assemblerName": "sdasstm8",
+ "linkerName": "sdldstm8"
+ }
+ } else if (architecture === "hcs8") {
+ return {
+ "assemblerName": "sdas6808",
+ "linkerName": "sdld6808"
+ }
}
- throw "Unable to deduce linker name for unsupported architecture: '"
- + qbs.architecture + "'";
-}
-
-function archiverName(qbs) {
- return "sdar";
}
function targetArchitectureFlag(architecture) {
@@ -75,6 +67,8 @@ function targetArchitectureFlag(architecture) {
return "-mmcs51";
if (architecture === "stm8")
return "-mstm8";
+ if (architecture === "hcs8")
+ return "-mhc08";
}
function guessArchitecture(macros) {
@@ -82,6 +76,8 @@ function guessArchitecture(macros) {
return "mcs51";
if (macros["__SDCC_stm8"] === "1")
return "stm8";
+ if (macros["__SDCC_hc08"] === "1")
+ return "hcs8";
}
function guessEndianness(macros) {
@@ -90,10 +86,20 @@ function guessEndianness(macros) {
}
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"] }
+ if ("__SDCC_VERSION_MAJOR" in macros
+ && "__SDCC_VERSION_MINOR" in macros
+ && "__SDCC_VERSION_PATCH" in macros) {
+ return { major: parseInt(macros["__SDCC_VERSION_MAJOR"], 10),
+ minor: parseInt(macros["__SDCC_VERSION_MINOR"], 10),
+ patch: parseInt(macros["__SDCC_VERSION_PATCH"], 10) }
+ } else if ("__SDCC" in macros) {
+ var versions = macros["__SDCC"].split("_");
+ if (versions.length === 3) {
+ return { major: parseInt(versions[0], 10),
+ minor: parseInt(versions[1], 10),
+ patch: parseInt(versions[2], 10) };
+ }
+ }
}
function dumpMacros(compilerFilePath, architecture) {
@@ -107,12 +113,7 @@ function dumpMacros(compilerFilePath, architecture) {
var p = new Process();
p.exec(compilerFilePath, args, true);
- var map = {};
- p.readStdOut().trim().split(/\r?\n/g).map(function (line) {
- var parts = line.split(" ", 3);
- map[parts[1]] = parts[2];
- });
- return map;
+ return Cpp.extractMacros(p.readStdOut());
}
function dumpDefaultPaths(compilerFilePath, architecture) {
@@ -137,7 +138,8 @@ function dumpDefaultPaths(compilerFilePath, architecture) {
|| line.startsWith("libpath:")) {
addIncludePaths = false;
} else if (addIncludePaths) {
- includePaths.push(line);
+ if (File.exists(line))
+ includePaths.push(line);
}
}
@@ -163,142 +165,69 @@ function escapeLinkerFlags(product, linkerFlags) {
return ["-Wl " + linkerFlags.join(",")];
}
-function collectLibraryDependencies(product) {
- var seen = {};
- var result = [];
-
- function addFilePath(filePath) {
- result.push({ filePath: filePath });
- }
-
- function addArtifactFilePaths(dep, artifacts) {
- if (!artifacts)
- return;
- var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
- artifactFilePaths.forEach(addFilePath);
- }
-
- function addExternalStaticLibs(obj) {
- if (!obj.cpp)
- return;
- function ensureArray(a) {
- return Array.isArray(a) ? a : [];
- }
- function sanitizedModuleListProperty(obj, moduleName, propertyName) {
- return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
- }
- var externalLibs = [].concat(
- sanitizedModuleListProperty(obj, "cpp", "staticLibraries"));
- var staticLibrarySuffix = obj.moduleProperty("cpp", "staticLibrarySuffix");
- externalLibs.forEach(function(staticLibraryName) {
- if (!staticLibraryName.endsWith(staticLibrarySuffix))
- staticLibraryName += staticLibrarySuffix;
- addFilePath(staticLibraryName);
- });
- }
-
- function traverse(dep) {
- if (seen.hasOwnProperty(dep.name))
- return;
- seen[dep.name] = true;
-
- if (dep.parameters.cpp && dep.parameters.cpp.link === false)
- return;
-
- var staticLibraryArtifacts = dep.artifacts["staticlibrary"];
- if (staticLibraryArtifacts) {
- dep.dependencies.forEach(traverse);
- addArtifactFilePaths(dep, staticLibraryArtifacts);
- addExternalStaticLibs(dep);
- }
- }
+function escapePreprocessorFlags(preprocessorFlags) {
+ if (!preprocessorFlags || preprocessorFlags.length === 0)
+ return preprocessorFlags;
+ return ["-Wp " + preprocessorFlags.join(",")];
+}
- product.dependencies.forEach(traverse);
- addExternalStaticLibs(product);
- return result;
+// We need to use the asm_adb, asm_src, asm_sym and rst_data
+// artifacts without of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraCompilerOutputTags() {
+ return ["asm_adb", "asm_src", "asm_sym", "rst_data"];
}
-function compilerOutputArtifacts(input) {
- var obj = {
- fileTags: ["obj"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + input.cpp.objectSuffix
- };
+// We need to use the lk_cmd, and mem_summary artifacts without
+// of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraApplicationLinkerOutputTags() {
+ return ["lk_cmd", "mem_summary"];
+}
- // We need to use the asm_adb, lst, asm_src, asm_sym and rst_data
- // artifacts without of any conditions. Because SDCC always generates
- // it (and seems, this behavior can not be disabled for SDCC).
- var asm_adb = {
+// We need to use the asm_adb, asm_src, asm_sym and rst_data
+// artifacts without of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraCompilerOutputArtifacts(input) {
+ return [{
fileTags: ["asm_adb"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".adb"
- };
- var lst = {
- fileTags: ["lst"],
- filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".lst"
- };
- var asm_src = {
+ + input.fileName + ".adb"
+ }, {
fileTags: ["asm_src"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".asm"
- };
- var asm_sym = {
+ + input.fileName + ".asm"
+ }, {
fileTags: ["asm_sym"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".sym"
- };
- var rst_data = {
+ + input.fileName + ".sym"
+ }, {
fileTags: ["rst_data"],
filePath: Utilities.getHash(input.baseDir) + "/"
- + input.fileName + ".rst"
- };
- return [obj, asm_adb, lst, asm_src, asm_sym, rst_data];
+ + input.fileName + ".rst"
+ }];
}
-function applicationLinkerOutputArtifacts(product) {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var lk_cmd = {
+// We need to use the lk_cmd, and mem_summary artifacts without
+// of any conditions. Because SDCC always generates
+// it (and seems, this behavior can not be disabled for SDCC).
+function extraApplicationLinkerOutputArtifacts(product) {
+ return [{
fileTags: ["lk_cmd"],
filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + ".lk")
- };
- var mem_summary = {
+ product.destinationDirectory,
+ product.targetName + ".lk")
+ }, {
fileTags: ["mem_summary"],
filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + ".mem")
- };
- var mem_map = {
- fileTags: ["mem_map"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- product.targetName + ".map")
- };
- return [app, lk_cmd, mem_summary, mem_map]
-}
-
-function staticLibraryLinkerOutputArtifacts(product) {
- var staticLib = {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
- };
- return [staticLib]
+ product.destinationDirectory,
+ product.targetName + ".mem")
+ }];
}
function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
- // Determine which C-language we"re compiling.
- var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
-
var args = [];
+ var escapablePreprocessorFlags = [];
// Input.
args.push(input.filePath);
@@ -307,29 +236,19 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("-c");
args.push("-o", outputs.obj[0].filePath);
+ // Prefix headers.
+ escapablePreprocessorFlags = escapablePreprocessorFlags.concat(
+ Cpp.collectPreincludePathsArguments(input));
+
// 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 }));
+ args = args.concat(Cpp.collectDefinesArguments(input));
// 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 }));
+ args = args.concat(Cpp.collectIncludePathsArguments(input));
+ escapablePreprocessorFlags = escapablePreprocessorFlags.concat(
+ Cpp.collectSystemIncludePathsArguments(input));
+ // Target MCU flag.
var targetFlag = targetArchitectureFlag(input.cpp.architecture);
if (targetFlag)
args.push(targetFlag);
@@ -352,56 +271,56 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
}
// Warning level flags.
- if (input.cpp.warningLevel === "none")
+ var warnings = input.cpp.warningLevel
+ if (warnings === "none") {
args.push("--less-pedantic");
+ escapablePreprocessorFlags.push("-w");
+ } else if (warnings === "all") {
+ escapablePreprocessorFlags.push("-Wall");
+ }
if (input.cpp.treatWarningsAsErrors)
args.push("--Werror");
+ // Determine which C-language we"re compiling.
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+
// C language version flags.
if (tag === "c") {
- var knownValues = ["c11", "c89"];
+ var knownValues = ["c2x", "c17", "c11", "c99", "c89"];
var cLanguageVersion = Cpp.languageVersion(
input.cpp.cLanguageVersion, knownValues, "C");
switch (cLanguageVersion) {
+ case "c17":
+ cLanguageVersion = "c11";
+ // fall through
case "c89":
- args.push("--std-c89");
- break;
+ case "c99":
case "c11":
- args.push("--std-c11");
+ case "c2x":
+ args.push("--std-" + cLanguageVersion);
break;
}
}
- // Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags"),
- ModUtils.moduleProperty(input, "flags"),
- ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ var escapedPreprocessorFlags = escapePreprocessorFlags(escapablePreprocessorFlags);
+ if (escapedPreprocessorFlags)
+ Array.prototype.push.apply(args, escapedPreprocessorFlags);
+ // Misc flags.
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(input));
return args;
}
function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
- // Determine which C-language we"re compiling
- var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
-
var args = [];
// Includes.
- var allIncludePaths = [];
- 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 = args.concat(Cpp.collectIncludePathsArguments(input));
+ args = args.concat(Cpp.collectSystemIncludePathsArguments(input, input.cpp.includeFlag));
// Misc flags.
- args = args.concat(ModUtils.moduleProperty(input, "platformFlags", tag),
- ModUtils.moduleProperty(input, "flags", tag),
- ModUtils.moduleProperty(input, "driverFlags", tag));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
args.push("-ol");
args.push(outputs.obj[0].filePath);
@@ -409,7 +328,7 @@ function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
return args;
}
-function linkerFlags(project, product, input, outputs) {
+function linkerFlags(project, product, inputs, outputs) {
var args = [];
// Target MCU flag.
@@ -417,118 +336,237 @@ function linkerFlags(project, product, input, outputs) {
if (targetFlag)
args.push(targetFlag);
- var allLibraryPaths = [];
- var libraryPaths = product.cpp.libraryPaths;
- if (libraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(libraryPaths);
- var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
- if (distributionLibraryPaths)
- allLibraryPaths = allLibraryPaths.uniqueConcat(distributionLibraryPaths);
-
- var libraryDependencies = collectLibraryDependencies(product);
-
var escapableLinkerFlags = [];
// Map file generation flag.
if (product.cpp.generateLinkerMapFile)
escapableLinkerFlags.push("-m");
- if (product.cpp.platformLinkerFlags)
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.platformLinkerFlags);
- if (product.cpp.linkerFlags)
- Array.prototype.push.apply(escapableLinkerFlags, product.cpp.linkerFlags);
+ escapableLinkerFlags = escapableLinkerFlags.concat(Cpp.collectMiscEscapableLinkerArguments(product));
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 }));
-
- // 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);
- });
- }
+
+ // Output.
+ if (useCompilerDriver)
+ args.push("-o");
+ args.push(outputs.application[0].filePath);
+
+ // Inputs.
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
+
+ // Library paths.
+ var libraryPathFlag = useCompilerDriver ? "-L" : "-k";
+ args = args.concat(Cpp.collectLibraryPathsArguments(product, libraryPathFlag));
+
+ // Linker scripts.
+ // Note: We need to split the '-f' flag and the file path to separate
+ // lines when we don't use the compiler driver mode.
+ escapableLinkerFlags = escapableLinkerFlags.concat(
+ Cpp.collectLinkerScriptPathsArguments(product, inputs, !useCompilerDriver));
// Library dependencies.
- if (libraryDependencies)
- args = args.concat(libraryDependencies.map(function(dep) { return "-l" + dep.filePath }));
+ args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
- // Misc flags.
var escapedLinkerFlags = escapeLinkerFlags(product, escapableLinkerFlags);
if (escapedLinkerFlags)
Array.prototype.push.apply(args, escapedLinkerFlags);
- var driverLinkerFlags = useCompilerDriver ? product.cpp.driverLinkerFlags : undefined;
- if (driverLinkerFlags)
- Array.prototype.push.apply(args, driverLinkerFlags);
+
+ // Misc flags.
+ if (useCompilerDriver) {
+ args = args.concat(Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+ }
return args;
}
-function archiverFlags(project, product, input, outputs) {
+function archiverFlags(project, product, inputs, outputs) {
var args = ["-rc"];
args.push(outputs.staticlibrary[0].filePath);
- if (inputs.obj)
- args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs));
return args;
}
+function buildLinkerMapFilePath(target, suffix) {
+ return FileInfo.joinPaths(FileInfo.path(target.filePath),
+ FileInfo.completeBaseName(target.fileName) + suffix);
+}
+
+// This is the workaround for the SDCC bug on a Windows host:
+// * https://sourceforge.net/p/sdcc/bugs/2970/
+// We need to replace the '\r\n\' line endings with the'\n' line
+// endings for each generated object file.
+function patchObjectFile(project, product, inputs, outputs, input, output) {
+ var isWindows = Host.os().includes("windows");
+ if (isWindows && input.cpp.debugInformation) {
+ var cmd = new JavaScriptCommand();
+ cmd.objectPath = outputs.obj[0].filePath;
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ var file = new BinaryFile(objectPath, BinaryFile.ReadWrite);
+ var data = file.read(file.size());
+ file.resize(0);
+ for (var pos = 0; pos < data.length; ++pos) {
+ // Find the next index of CR (\r) symbol.
+ var index = data.indexOf(0x0d, pos);
+ if (index < 0)
+ index = data.length;
+ // Write next data chunk between the previous position and the CR
+ // symbol, exclude the CR symbol.
+ file.write(data.slice(pos, index));
+ pos = index;
+ }
+ };
+ return cmd;
+ }
+}
+
+// It is a workaround which removes the generated linker map file
+// if it is disabled by cpp.generateLinkerMapFile property.
+// Reason is that the SDCC compiler always generates this file,
+// and does not have an option to disable generation for a linker
+// map file. So, we can to remove a listing files only after the
+// linking completes.
+function removeLinkerMapFile(project, product, inputs, outputs, input, output) {
+ if (!product.cpp.generateLinkerMapFile) {
+ var target = outputs.application[0];
+ var cmd = new JavaScriptCommand();
+ cmd.mapFilePath = buildLinkerMapFilePath(target, product.cpp.linkerMapSuffix)
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.remove(mapFilePath); };
+ return cmd;
+ }
+}
+
+// It is a workaround to rename the extension of the output linker
+// map file to the specified one, since the linker generates only
+// files with the '.map' extension.
+function renameLinkerMapFile(project, product, inputs, outputs, input, output) {
+ if (product.cpp.generateLinkerMapFile && (product.cpp.linkerMapSuffix !== ".map")) {
+ var target = outputs.application[0];
+ var cmd = new JavaScriptCommand();
+ cmd.newMapFilePath = buildLinkerMapFilePath(target, product.cpp.linkerMapSuffix);
+ cmd.oldMapFilePath = buildLinkerMapFilePath(target, ".map");
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.move(oldMapFilePath, newMapFilePath); };
+ return cmd;
+ }
+}
+
+// It is a workaround which removes the generated listing files
+// if it is disabled by cpp.generateCompilerListingFiles property
+// or when the cpp.compilerListingSuffix differs with '.lst'.
+// Reason is that the SDCC compiler does not have an option to
+// disable generation for a listing files. Besides, the SDCC
+// compiler use this files and for the linking. So, we can to
+// remove a listing files only after the linking completes.
+function removeCompilerListingFiles(project, product, inputs, outputs, input, output) {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ inputs.obj.forEach(function(object) {
+ if (!object.filePath.endsWith(".c" + object.cpp.objectSuffix))
+ return; // Skip the assembler generated objects.
+ if (!object.cpp.generateCompilerListingFiles
+ || (object.cpp.compilerListingSuffix !== ".lst")) {
+ var listingPath = FileInfo.joinPaths(FileInfo.path(object.filePath),
+ object.completeBaseName + ".lst");
+ File.remove(listingPath);
+ }
+ })
+ };
+ return cmd;
+}
+
+// It is a workaround that duplicates the generated listing files
+// but with desired names. The problem is that the SDCC compiler does
+// not support an options to specify names for the generated listing
+// files. At the same time, the compiler always generates the listing
+// files in the form of 'module.c.lst', which makes it impossible to
+// change the file suffix to a user-specified one. In addition, these
+// files are also somehow used for linking. Thus, we can not rename them
+// on the compiling stage.
+function duplicateCompilerListingFile(project, product, inputs, outputs, input, output) {
+ if (input.cpp.generateCompilerListingFiles
+ && (input.cpp.compilerListingSuffix !== ".lst")) {
+ var cmd = new JavaScriptCommand();
+ cmd.newListing = outputs.lst[0].filePath;
+ cmd.oldListing = FileInfo.joinPaths(FileInfo.path(outputs.lst[0].filePath),
+ outputs.lst[0].completeBaseName + ".lst");
+ cmd.silent = true;
+ cmd.sourceCode = function() { File.copy(oldListing, newListing); };
+ return cmd;
+ }
+}
+
function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
var compilerPath = input.cpp.compilerPath;
var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
- return [cmd];
+ cmd.jobPool = "compiler";
+ cmds.push(cmd);
+
+ cmd = patchObjectFile(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+
+ cmd = duplicateCompilerListingFile(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+
+ return cmds;
}
function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
var args = assemblerFlags(project, product, input, outputs, explicitlyDependsOn);
var assemblerPath = input.cpp.assemblerPath;
var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
- return [cmd];
+ cmd.jobPool = "assembler";
+ cmds.push(cmd);
+
+ cmd = patchObjectFile(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+
+ return cmds;
}
function prepareLinker(project, product, inputs, outputs, input, output) {
- var primaryOutput = outputs.application[0];
- var args = linkerFlags(project, product, input, outputs);
+ var cmds = [];
+ var args = linkerFlags(project, product, inputs, outputs);
var linkerPath = effectiveLinkerPath(product);
var cmd = new Command(linkerPath, args);
- cmd.description = "linking " + primaryOutput.fileName;
+ cmd.description = "linking " + outputs.application[0].fileName;
cmd.highlight = "linker";
- return [cmd];
+ cmd.jobPool = "linker";
+ cmds.push(cmd);
+
+ cmd = removeCompilerListingFiles(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+
+ cmd = renameLinkerMapFile(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+
+ cmd = removeLinkerMapFile(project, product, inputs, outputs, input, output);
+ if (cmd)
+ cmds.push(cmd);
+
+ return cmds;
}
function prepareArchiver(project, product, inputs, outputs, input, output) {
- var args = archiverFlags(project, product, input, outputs);
+ var args = archiverFlags(project, product, inputs, outputs);
var archiverPath = product.cpp.archiverPath;
var cmd = new Command(archiverPath, args);
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
return [cmd];
}
diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs
index ec763ba47..24cb6d738 100644
--- a/share/qbs/modules/cpp/sdcc.qbs
+++ b/share/qbs/modules/cpp/sdcc.qbs
@@ -28,15 +28,14 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.File
import qbs.FileInfo
-import qbs.ModUtils
import qbs.Probes
+import "cpp.js" as Cpp
import "sdcc.js" as SDCC
CppModule {
- condition: qbs.toolchain && qbs.toolchain.contains("sdcc")
+ condition: qbs.toolchain && qbs.toolchain.includes("sdcc")
Probes.BinaryProbe {
id: compilerPathProbe
@@ -48,10 +47,12 @@ CppModule {
id: sdccProbe
condition: !_skipAllChecks
compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
preferredArchitecture: qbs.architecture
}
qbs.architecture: sdccProbe.found ? sdccProbe.architecture : original
+ qbs.targetPlatform: "none"
compilerVersionMajor: sdccProbe.versionMajor
compilerVersionMinor: sdccProbe.versionMinor
@@ -61,10 +62,7 @@ CppModule {
compilerDefinesByLanguage: sdccProbe.compilerDefinesByLanguage
compilerIncludePaths: sdccProbe.includePaths
- property string toolchainInstallPath: compilerPathProbe.found
- ? compilerPathProbe.path : undefined
-
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
/* Work-around for QtCreator which expects these properties to exist. */
property string cCompilerName: compilerName
@@ -72,47 +70,53 @@ CppModule {
property string linkerMode: "automatic"
- compilerName: SDCC.compilerName(qbs) + compilerExtension
+ compilerName: "sdcc" + compilerExtension
compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: SDCC.assemblerName(qbs) + compilerExtension
+ assemblerName: toolchainDetails.assemblerName + compilerExtension
assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
- linkerName: SDCC.linkerName(qbs) + compilerExtension
+ linkerName: toolchainDetails.linkerName + compilerExtension
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
- property string archiverName: SDCC.archiverName(qbs) + compilerExtension
+ property string archiverName: "sdar" + compilerExtension
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
runtimeLibrary: "static"
staticLibrarySuffix: ".lib"
executableSuffix: ".ihx"
-
- property string objectSuffix: ".rel"
+ objectSuffix: ".rel"
imageFormat: "ihx"
enableExceptions: false
enableRtti: false
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-isystem"
+ preincludeFlag: "-include"
+ libraryDependencyFlag: "-l"
+ libraryPathFlag: "-L"
+ linkerScriptFlag: "-f"
+
+ toolchainDetails: SDCC.toolchainDetails(qbs)
+
+ knownArchitectures: ["hcs8", "mcs51", "stm8"]
+
Rule {
id: assembler
inputs: ["asm"]
- outputFileTags: ["obj", "asm_adb", "lst", "asm_src", "asm_sym", "rst_data"]
- outputArtifacts: SDCC.compilerOutputArtifacts(input)
+ outputFileTags: SDCC.extraCompilerOutputTags().concat(
+ Cpp.assemblerOutputTags(generateAssemblerListingFiles))
+ outputArtifacts: SDCC.extraCompilerOutputArtifacts(input).concat(
+ Cpp.assemblerOutputArtifacts(input))
prepare: SDCC.prepareAssembler.apply(SDCC, arguments)
}
FileTagger {
- condition: qbs.architecture === "arm";
- patterns: "*.s"
- fileTags: ["asm"]
- }
-
- FileTagger {
- condition: qbs.architecture === "mcs51";
- patterns: ["*.s51", "*.asm"]
+ patterns: ["*.s", "*.a51", "*.asm"]
fileTags: ["asm"]
}
@@ -120,8 +124,10 @@ CppModule {
id: compiler
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
- outputFileTags: ["obj", "asm_adb", "lst", "asm_src", "asm_sym", "rst_data"]
- outputArtifacts: SDCC.compilerOutputArtifacts(input)
+ outputFileTags: SDCC.extraCompilerOutputTags().concat(
+ Cpp.compilerOutputTags(generateCompilerListingFiles))
+ outputArtifacts: SDCC.extraCompilerOutputArtifacts(input).concat(
+ Cpp.compilerOutputArtifacts(input))
prepare: SDCC.prepareCompiler.apply(SDCC, arguments)
}
@@ -130,8 +136,10 @@ CppModule {
multiplex: true
inputs: ["obj", "linkerscript"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["application", "lk_cmd", "mem_summary", "mem_map"]
- outputArtifacts: SDCC.applicationLinkerOutputArtifacts(product)
+ outputFileTags: SDCC.extraApplicationLinkerOutputTags().concat(
+ Cpp.applicationLinkerOutputTags(generateLinkerMapFile))
+ outputArtifacts: SDCC.extraApplicationLinkerOutputArtifacts(product).concat(
+ Cpp.applicationLinkerOutputArtifacts(product))
prepare: SDCC.prepareLinker.apply(SDCC, arguments)
}
@@ -140,8 +148,8 @@ CppModule {
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary"]
- outputFileTags: ["staticlibrary"]
- outputArtifacts: SDCC.staticLibraryLinkerOutputArtifacts(product)
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
prepare: SDCC.prepareArchiver.apply(SDCC, arguments)
}
}
diff --git a/share/qbs/modules/cpp/setuprunenv.js b/share/qbs/modules/cpp/setuprunenv.js
index 550d08d63..2ea331a30 100644
--- a/share/qbs/modules/cpp/setuprunenv.js
+++ b/share/qbs/modules/cpp/setuprunenv.js
@@ -30,11 +30,12 @@
var FileInfo = require("qbs.FileInfo");
var File = require("qbs.File");
+var Host = require("qbs.Host");
var ModUtils = require("qbs.ModUtils"); // TODO: append/prepend functionality should go to qbs.Environment
function addNewElement(list, elem)
{
- if (!list.contains(elem))
+ if (!list.includes(elem))
list.push(elem);
}
@@ -48,7 +49,7 @@ function artifactDir(artifact)
function addExternalLibPath(product, list, path)
{
addNewElement(list, path);
- if (product.qbs.hostOS.contains("windows") && FileInfo.fileName(path) === "lib") {
+ if (Host.os().includes("windows") && FileInfo.fileName(path) === "lib") {
var binPath = FileInfo.joinPaths(FileInfo.path(path), "bin");
if (File.exists(binPath))
addNewElement(list, binPath);
@@ -57,7 +58,7 @@ function addExternalLibPath(product, list, path)
function gatherPaths(product, libPaths, frameworkPaths, seenProducts)
{
- if (seenProducts.contains(product.name))
+ if (seenProducts.includes(product.name))
return;
seenProducts.push(product.name);
@@ -66,6 +67,8 @@ function gatherPaths(product, libPaths, frameworkPaths, seenProducts)
product.cpp.libraryPaths.forEach(function(p) { addExternalLibPath(product, libPaths, p); });
if (product.cpp && product.cpp.frameworkPaths)
product.cpp.frameworkPaths.forEach(function(p) { addNewElement(frameworkPaths, p); });
+ if (product.cpp && product.cpp.systemFrameworkPaths)
+ product.cpp.systemFrameworkPaths.forEach(function(p) { addNewElement(frameworkPaths, p); });
// Extract paths from dynamic libraries, if they are given as file paths.
if (product.cpp && product.cpp.dynamicLibraries) {
@@ -103,10 +106,10 @@ function gatherPaths(product, libPaths, frameworkPaths, seenProducts)
function setupRunEnvironment(product, config)
{
- if (config.contains("ignore-lib-dependencies"))
+ if (config.includes("ignore-lib-dependencies"))
return;
- if (product.qbs.hostPlatform !== product.qbs.targetPlatform)
+ if (Host.platform() !== product.qbs.targetPlatform)
return;
var libPaths = [];
@@ -117,8 +120,8 @@ function setupRunEnvironment(product, config)
if (runPaths && runPaths.length > 0) {
var canonicalRunPaths = runPaths.map(function(p) { return File.canonicalFilePath(p); });
var filterFunc = function(libPath) {
- return !runPaths.contains(libPath)
- && !canonicalRunPaths.contains(File.canonicalFilePath(libPath));
+ return !runPaths.includes(libPath)
+ && !canonicalRunPaths.includes(File.canonicalFilePath(libPath));
};
libPaths = libPaths.filter(filterFunc);
frameworkPaths = frameworkPaths.filter(filterFunc);
@@ -126,19 +129,19 @@ function setupRunEnvironment(product, config)
if (libPaths.length > 0) {
var envVarName;
- if (product.qbs.targetOS.contains("windows"))
+ if (product.qbs.targetOS.includes("windows"))
envVarName = "PATH";
- else if (product.qbs.targetOS.contains("macos"))
+ else if (product.qbs.targetOS.includes("macos"))
envVarName = "DYLD_LIBRARY_PATH";
else
envVarName = "LD_LIBRARY_PATH";
- var envVar = new ModUtils.EnvironmentVariable(envVarName, product.qbs.pathListSeparator,
- product.qbs.hostOS.contains("windows"));
+ var envVar = new ModUtils.EnvironmentVariable(envVarName, FileInfo.pathListSeparator(),
+ Host.os().includes("windows"));
libPaths.forEach(function(p) { envVar.prepend(p); });
envVar.set();
}
- if (product.qbs.targetOS.contains("macos") && frameworkPaths.length > 0) {
+ if (product.qbs.targetOS.includes("macos") && frameworkPaths.length > 0) {
envVar = new ModUtils.EnvironmentVariable("DYLD_FRAMEWORK_PATH", ':', false);
frameworkPaths.forEach(function(p) { envVar.prepend(p); });
envVar.set();
diff --git a/share/qbs/modules/cpp/tvos-gcc.qbs b/share/qbs/modules/cpp/tvos-gcc.qbs
index 19bc9b787..eba3b091e 100644
--- a/share/qbs/modules/cpp/tvos-gcc.qbs
+++ b/share/qbs/modules/cpp/tvos-gcc.qbs
@@ -30,16 +30,16 @@
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('tvos') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('tvos') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
targetSystem: "tvos" + (minimumTvosVersion || "")
minimumDarwinVersion: minimumTvosVersion
- minimumDarwinVersionCompilerFlag: qbs.targetOS.contains("tvos-simulator")
+ minimumDarwinVersionCompilerFlag: qbs.targetOS.includes("tvos-simulator")
? "-mtvos-simulator-version-min"
: "-mtvos-version-min"
- minimumDarwinVersionLinkerFlag: qbs.targetOS.contains("tvos-simulator")
+ minimumDarwinVersionLinkerFlag: qbs.targetOS.includes("tvos-simulator")
? "-tvos_simulator_version_min"
: "-tvos_version_min"
}
diff --git a/share/qbs/modules/cpp/watchos-gcc.qbs b/share/qbs/modules/cpp/watchos-gcc.qbs
index 46e4bf874..3a160f6d0 100644
--- a/share/qbs/modules/cpp/watchos-gcc.qbs
+++ b/share/qbs/modules/cpp/watchos-gcc.qbs
@@ -31,16 +31,16 @@
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('watchos') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('watchos') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
targetSystem: "watchos" + (minimumWatchosVersion || "")
minimumDarwinVersion: minimumWatchosVersion
- minimumDarwinVersionCompilerFlag: qbs.targetOS.contains("watchos-simulator")
+ minimumDarwinVersionCompilerFlag: qbs.targetOS.includes("watchos-simulator")
? "-mwatchos-simulator-version-min"
: "-mwatchos-version-min"
- minimumDarwinVersionLinkerFlag: qbs.targetOS.contains("watchos-simulator")
+ minimumDarwinVersionLinkerFlag: qbs.targetOS.includes("watchos-simulator")
? "-watchos_simulator_version_min"
: "-watchos_version_min"
}
diff --git a/share/qbs/modules/cpp/watcom.js b/share/qbs/modules/cpp/watcom.js
new file mode 100644
index 000000000..9ae893db9
--- /dev/null
+++ b/share/qbs/modules/cpp/watcom.js
@@ -0,0 +1,568 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 Denis Shienkov <denis.shienkov@gmail.com>
+** 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.
+**
+****************************************************************************/
+
+var Cpp = require("cpp.js");
+var Environment = require("qbs.Environment");
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+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");
+
+function toolchainDetails(qbs) {
+ var platform = qbs.targetPlatform;
+ var details = {};
+ if (platform === "dos") {
+ details.imageFormat = "mz";
+ details.executableSuffix = ".exe";
+ } else if (platform === "os2") {
+ details.imageFormat = "pe";
+ details.executableSuffix = ".exe";
+ details.dynamicLibrarySuffix = ".dll";
+ } else if (platform === "windows") {
+ details.imageFormat = "pe";
+ details.executableSuffix = ".exe";
+ details.dynamicLibrarySuffix = ".dll";
+ } else if (platform === "linux") {
+ details.imageFormat = "elf";
+ details.executableSuffix = "";
+ details.dynamicLibrarySuffix = ".so";
+ }
+ return details;
+}
+
+function languageFlag(tag) {
+ if (tag === "c")
+ return "-xc";
+ else if (tag === "cpp")
+ return "-xc++";
+}
+
+function targetFlag(platform, architecture, type) {
+ if (platform === "dos") {
+ if (architecture === "x86_16")
+ return "-bdos";
+ else if (architecture === "x86")
+ return "-bdos4g";
+ } else if (platform === "os2") {
+ if (architecture === "x86_16")
+ return "-bos2";
+ else if (architecture === "x86")
+ return "-bos2v2";
+ } else if (platform === "windows") {
+ if (architecture === "x86_16") {
+ if (type.includes("dynamiclibrary"))
+ return "-bwindows_dll";
+ return "-bwindows";
+ } else if (architecture === "x86") {
+ if (type.includes("dynamiclibrary"))
+ return "-bnt_dll";
+ return "-bnt";
+ }
+ } else if (platform === "linux") {
+ return "-blinux";
+ }
+}
+
+function guessVersion(macros) {
+ var version = parseInt(macros["__WATCOMC__"], 10)
+ || parseInt(macros["__WATCOM_CPLUSPLUS__"], 10);
+ if (version) {
+ return { major: parseInt((version - 1100) / 100),
+ minor: parseInt(version / 10) % 10,
+ patch: ((version % 10) > 0) ? parseInt(version % 10) : 0 }
+ }
+}
+
+function guessEnvironment(hostOs, platform, architecture,
+ toolchainInstallPath, pathListSeparator) {
+ var toolchainRootPath = FileInfo.path(toolchainInstallPath);
+ if (!File.exists(toolchainRootPath)) {
+ throw "Unable to deduce environment due to compiler root directory: '"
+ + toolchainRootPath + "' does not exist";
+ }
+
+ var env = {};
+
+ function setVariable(key, properties, path, separator) {
+ var values = [];
+ for (var i = 0; i < properties.length; ++i) {
+ if (path) {
+ var fullpath = FileInfo.joinPaths(path, properties[i]);
+ values.push(FileInfo.toNativeSeparators(fullpath));
+ } else {
+ values.push(properties[i]);
+ }
+ }
+ env[key] = values.join(separator);
+ }
+
+ setVariable("WATCOM", [toolchainRootPath], undefined, pathListSeparator);
+ setVariable("EDPATH", ["eddat"], toolchainRootPath, pathListSeparator);
+
+ if (hostOs.includes("linux"))
+ setVariable("PATH", ["binl64", "binl"], toolchainRootPath, pathListSeparator);
+ else if (hostOs.includes("windows"))
+ setVariable("PATH", ["binnt64", "binnt"], toolchainRootPath, pathListSeparator);
+
+ if (platform === "linux") {
+ setVariable("INCLUDE", ["lh"], toolchainRootPath, pathListSeparator);
+ } else {
+ // Common for DOS, Windows, OS/2.
+ setVariable("WIPFC", ["wipfc"], toolchainRootPath, pathListSeparator);
+ setVariable("WHTMLHELP", ["binnt/help"], toolchainRootPath, pathListSeparator);
+
+ var includes = ["h"];
+ if (platform === "dos") {
+ // Same includes as before.
+ } else if (platform === "os2") {
+ if (architecture === "x86")
+ includes = includes.concat(["h/os2"]);
+ else if (architecture === "x86_16")
+ includes = includes.concat(["h/os21x"]);
+ } else if (platform === "windows") {
+ if (architecture === "x86")
+ includes = includes.concat(["h/nt", "h/nt/directx", "h/nt/ddk"]);
+ else if (architecture === "x86_16")
+ includes = includes.concat(["h/win"]);
+ } else {
+ throw "Unable to deduce environment for unsupported target platform: '"
+ + platform + "'";
+ }
+
+ setVariable("INCLUDE", includes, toolchainRootPath, pathListSeparator);
+ }
+
+ return env;
+}
+
+function dumpMacros(environment, compilerPath, platform, architecture, tag) {
+ // Note: The Open Watcom compiler does not support the predefined
+ // macros dumping. So, we do it with the following trick, where we try
+ // to create and compile a special temporary file and to parse the console
+ // output with the own magic pattern: #define <key> <value>.
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.joinPaths(outputDirectory.path(), "dump-macros.c");
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+ outputFile.writeLine("#define VALUE_TO_STRING(x) #x");
+ outputFile.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
+ outputFile.writeLine("#define VAR_NAME_VALUE(var) \"#define \"#var\" \"VALUE(var)");
+ // Declare all available pre-defined macros of Watcon compiler.
+ var keys = [
+ // Prepare the DOS target macros.
+ "__DOS__", "_DOS", "MSDOS",
+ // Prepare the OS/2 target macros.
+ "__OS2__",
+ // Prepare the QNX target macros.
+ "__QNX__",
+ // Prepare the Netware target macros.
+ "__NETWARE__", "__NETWARE_386__",
+ // Prepare the Windows target macros.
+ "__NT__", "__WINDOWS__", "_WINDOWS", "__WINDOWS_386__",
+ // Prepare the Linux and Unix target macros.
+ "__LINUX__", "__UNIX__",
+ // Prepare the 16-bit target specific macros.
+ "__I86__", "M_I86", "_M_I86", "_M_IX86",
+ // Prepare the 32-bit target specific macros.
+ "__386__", "M_I386", "_M_I386", "_M_IX86",
+ // Prepare the indicated options macros.
+ "_MT", "_DLL", "__FPI__", "__CHAR_SIGNED__", "__INLINE_FUNCTIONS__",
+ "_CPPRTTI", "_CPPUNWIND", "NO_EXT_KEYS",
+ // Prepare the common memory model macros.
+ "__FLAT__", "__SMALL__", "__MEDIUM__",
+ "__COMPACT__", "__LARGE__", "__HUGE__",
+ // Prepare the 16-bit memory model macros.
+ "M_I86SM", "_M_I86SM", "M_I86MM", "_M_I86MM", "M_I86CM",
+ "_M_I86CM", "M_I86LM", "_M_I86LM", "M_I86HM", "_M_I86HM",
+ // Prepare the 32-bit memory model macros.
+ "M_386FM", "_M_386FM", "M_386SM", "M_386MM", "_M_386MM",
+ "M_386CM", "_M_386CM", "M_386LM", "_M_386LM",
+ // Prepare the compiler macros.
+ "__X86__", "__cplusplus", "__WATCOMC__", "__WATCOM_CPLUSPLUS__",
+ "_INTEGRAL_MAX_BITS", "_PUSHPOP_SUPPORTED", "_STDCALL_SUPPORTED",
+ // Prepare the other macros.
+ "__3R__", "_based", "_cdecl", "cdecl", "_export", "_far16", "_far", "far",
+ "_fastcall", "_fortran", "fortran", "_huge", "huge", "_inline", "_interrupt",
+ "interrupt", "_loadds", "_near", "near", "_pascal", "pascal", "_saveregs",
+ "_segment", "_segname", "_self", "SOMDLINK", "_STDCALL_SUPPORTED", "__SW_0",
+ "__SW_3R", "__SW_5", "__SW_FP287", "__SW_FP2", "__SW_FP387", "__SW_FP3",
+ "__SW_FPI", "__SW_MF", "__SW_MS", "__SW_ZDP", "__SW_ZFP", "__SW_ZGF",
+ "__SW_ZGP", "_stdcall", "_syscall", "__BIG_ENDIAN"
+ ];
+ for (var i = 0; i < keys.length; ++i) {
+ var key = keys[i];
+ outputFile.writeLine("#if defined(" + key + ")");
+ outputFile.writeLine("#pragma message (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("#endif");
+ }
+ outputFile.close();
+
+ var process = new Process();
+ process.setWorkingDirectory(outputDirectory.path());
+ for (var envkey in environment)
+ process.setEnv(envkey, environment[envkey]);
+
+ var target = targetFlag(platform, architecture, ["application"]);
+ var lang = languageFlag(tag);
+ var args = [ target, lang, outputFilePath ];
+
+ process.exec(compilerPath, args, false);
+ var m = Cpp.extractMacros(process.readStdOut(), /"?(#define(\s\w+){1,2})"?$/);
+ if (tag === "cpp" && m["__cplusplus"] === "1")
+ return m;
+ else if (tag === "c")
+ return m;
+}
+
+function effectiveLinkerPath(product) {
+ if (product.cpp.linkerMode === "automatic") {
+ var compilerPath = product.cpp.compilerPath;
+ if (compilerPath)
+ return compilerPath;
+ console.log("Found no C-language objects, choosing system linker for " + product.name);
+ }
+ return product.cpp.linkerPath;
+}
+
+function useCompilerDriverLinker(product) {
+ var linker = effectiveLinkerPath(product);
+ var compiler = product.cpp.compilerPath;
+ return linker === compiler;
+}
+
+function escapeLinkerFlags(useCompilerDriver, linkerFlags) {
+ if (!linkerFlags || linkerFlags.length === 0)
+ return [];
+
+ if (useCompilerDriver) {
+ var sep = ",";
+ return [["-Wl"].concat(linkerFlags).join(sep)];
+ }
+ return linkerFlags;
+}
+
+function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = [FileInfo.toNativeSeparators(input.filePath)];
+ args.push("-fo=" + FileInfo.toNativeSeparators(outputs.obj[0].filePath));
+
+ args = args.concat(Cpp.collectPreincludePaths(input).map(function(path) {
+ return "-fi" + FileInfo.toNativeSeparators(path);
+ }));
+
+ args = args.concat(Cpp.collectDefinesArguments(input, "-d"));
+
+ var includePaths = [].concat(Cpp.collectIncludePaths(input)).concat(
+ Cpp.collectSystemIncludePaths(input));
+ args = args.concat(includePaths.map(function(path) {
+ return "-i" + FileInfo.toNativeSeparators(path);
+ }));
+
+ if (input.cpp.debugInformation)
+ args.push("-d1");
+
+ var warnings = input.cpp.warningLevel
+ if (warnings === "none")
+ args.push("-w0");
+ else if (warnings === "all")
+ args.push("-wx");
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("-we");
+
+ args.push("-zq"); // Silent.
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input));
+ return args;
+}
+
+function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = ["-g" + (input.cpp.debugInformation ? "3" : "0")];
+
+ var target = targetFlag(product.qbs.targetPlatform, product.qbs.architecture,
+ product.type);
+ args.push(target);
+
+ if (product.type.includes("application")) {
+ if (product.qbs.targetPlatform === "windows") {
+ var consoleApplication = product.consoleApplication;
+ args.push(consoleApplication ? "-mconsole" : "-mwindows");
+ }
+ } else if (product.type.includes("dynamiclibrary")) {
+ args.push("-shared");
+ }
+
+ var optimization = input.cpp.optimization
+ if (optimization === "fast")
+ args.push("-Ot");
+ else if (optimization === "small")
+ args.push("-Os");
+ else if (optimization === "none")
+ args.push("-O0");
+
+ var warnings = input.cpp.warningLevel
+ if (warnings === "none") {
+ args.push("-w");
+ } else if (warnings === "all") {
+ args.push("-Wall");
+ args.push("-Wextra");
+ }
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("-Werror");
+
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+
+ var langFlag = languageFlag(tag);
+ if (langFlag)
+ args.push(langFlag);
+
+ if (tag === "cpp") {
+ var enableExceptions = input.cpp.enableExceptions;
+ if (enableExceptions) {
+ var ehModel = input.cpp.exceptionHandlingModel;
+ switch (ehModel) {
+ case "direct":
+ args.push("-feh-direct");
+ break;
+ case "table":
+ args.push("-feh-table");
+ break;
+ default:
+ args.push("-feh");
+ break;
+ }
+ } else {
+ args.push("-fno-eh");
+ }
+
+ var enableRtti = input.cpp.enableRtti;
+ args.push(enableRtti ? "-frtti" : "-fno-rtti");
+ } else if (tag === "c") {
+ var knownValues = ["c99", "c89"];
+ var cLanguageVersion = Cpp.languageVersion(input.cpp.cLanguageVersion, knownValues, "C");
+ switch (cLanguageVersion) {
+ case "c89":
+ args.push("-std=c89");
+ break;
+ case "c99":
+ args.push("-std=c99");
+ break;
+ }
+ }
+
+ var preincludePaths = Cpp.collectPreincludePaths(input);
+ for (var i = 0; i < preincludePaths.length; ++i)
+ args.push(input.cpp.preincludeFlag, preincludePaths[i]);
+
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toNativeSeparators(path);
+ }));
+
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(input));
+
+ args.push("-o", FileInfo.toNativeSeparators(outputs.obj[0].filePath));
+ args.push("-c", FileInfo.toNativeSeparators(input.filePath));
+
+ return args;
+}
+
+function resourceCompilerFlags(project, product, input, outputs) {
+ var args = [input.filePath];
+ args.push("-fo=" + FileInfo.toNativeSeparators(outputs.res[0].filePath));
+ args = args.concat(Cpp.collectDefinesArguments(input, "-d"));
+
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args.push("-q", "-ad", "-r");
+ return args;
+}
+
+function linkerFlags(project, product, inputs, outputs) {
+ var args = [];
+ var useCompilerDriver = useCompilerDriverLinker(product);
+ if (useCompilerDriver) {
+ var target = targetFlag(product.qbs.targetPlatform, product.qbs.architecture,
+ product.type);
+ args.push(target);
+
+ if (product.type.includes("application")) {
+ args.push("-o", FileInfo.toNativeSeparators(outputs.application[0].filePath));
+ if (product.cpp.generateLinkerMapFile)
+ args.push("-fm=" + FileInfo.toNativeSeparators(outputs.mem_map[0].filePath));
+ } else if (product.type.includes("dynamiclibrary")) {
+ if (product.qbs.targetPlatform === "windows") {
+ args.push("-Wl, option implib=" + FileInfo.toNativeSeparators(
+ outputs.dynamiclibrary_import[0].filePath));
+ }
+ args.push("-o", FileInfo.toNativeSeparators(outputs.dynamiclibrary[0].filePath))
+ }
+
+ var escapableLinkerFlags = [];
+ var targetLinkerFlags = product.cpp.targetLinkerFlags;
+ if (targetLinkerFlags)
+ escapableLinkerFlags = escapableLinkerFlags.concat(targetLinkerFlags);
+
+ escapableLinkerFlags = escapableLinkerFlags.concat(
+ Cpp.collectMiscEscapableLinkerArguments(product));
+
+ var escapedLinkerFlags = escapeLinkerFlags(useCompilerDriver, escapableLinkerFlags);
+ if (escapedLinkerFlags)
+ args = args.concat(escapedLinkerFlags);
+
+ args = args.concat(Cpp.collectLibraryPaths(product).map(function(path) {
+ return product.cpp.libraryPathFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return FileInfo.toNativeSeparators(path);
+ }));
+
+ var libraryDependencies = Cpp.collectLibraryDependencies(product);
+ for (var i = 0; i < libraryDependencies.length; ++i) {
+ var lib = libraryDependencies[i].filePath;
+ if (FileInfo.isAbsolutePath(lib) || lib.startsWith('@'))
+ args.push(FileInfo.toNativeSeparators(lib));
+ else
+ args.push("-Wl, libfile " + lib);
+ }
+
+ var resourcePaths = Cpp.collectResourceObjectPaths(inputs).map(function(path) {
+ return FileInfo.toNativeSeparators(path);
+ });
+ if (resourcePaths.length > 0)
+ args = args.concat("-Wl, resource " + resourcePaths.join(","));
+ }
+
+ args = args.concat(Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+ return args;
+}
+
+function libraryManagerFlags(project, product, inputs, outputs) {
+ var args = ["-b", "-n", "-q"];
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return "+" + FileInfo.toNativeSeparators(path);
+ }));
+ args.push("-o", FileInfo.toNativeSeparators(outputs.staticlibrary[0].filePath));
+ return args;
+}
+
+function disassemblerFlags(project, product, inputs, outputs) {
+ var objectPath = Cpp.relativePath(product.buildDirectory, outputs.obj[0].filePath);
+ var listingPath = Cpp.relativePath(product.buildDirectory, outputs.lst[0].filePath);
+ var args = [];
+ args.push(FileInfo.toNativeSeparators(objectPath));
+ args.push("-l=" + FileInfo.toNativeSeparators(listingPath));
+ args.push("-s", "-a");
+ return args;
+}
+
+function generateCompilerListing(project, product, inputs, outputs, input, output) {
+ var args = disassemblerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.disassemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.silent = true;
+ cmd.jobPool = "watcom_job_pool";
+ return cmd;
+}
+
+function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+ var args = assemblerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.assemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "assembling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "watcom_job_pool";
+ cmds.push(cmd);
+ if (input.cpp.generateAssemblerListingFiles)
+ cmds.push(generateCompilerListing(project, product, inputs, outputs, input, output));
+ return cmds;
+}
+
+function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+ var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
+ var cmd = new Command(input.cpp.compilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "watcom_job_pool";
+ cmds.push(cmd);
+ if (input.cpp.generateCompilerListingFiles)
+ cmds.push(generateCompilerListing(project, product, inputs, outputs, input, output));
+ return cmds;
+}
+
+function prepareResourceCompiler(project, product, inputs, outputs, input, output,
+ explicitlyDependsOn) {
+ var args = resourceCompilerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.resourceCompilerPath, args);
+ // Set working directory to source directory as a workaround
+ // to make the resources compilable by resource compiler (it is magic).
+ cmd.workingDirectory = product.sourceDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "watcom_job_pool";
+ return [cmd];
+}
+
+function prepareLinker(project, product, inputs, outputs, input, output) {
+ var primaryOutput = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : outputs.application[0];
+ var args = linkerFlags(project, product, inputs, outputs);
+ var linkerPath = effectiveLinkerPath(product);
+ var cmd = new Command(linkerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + primaryOutput.fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "watcom_job_pool";
+ return [cmd];
+}
+
+function prepareLibraryManager(project, product, inputs, outputs, input, output) {
+ var args = libraryManagerFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.libraryManagerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + outputs.staticlibrary[0].fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "watcom_job_pool";
+ return [cmd];
+}
diff --git a/share/qbs/modules/cpp/watcom.qbs b/share/qbs/modules/cpp/watcom.qbs
new file mode 100644
index 000000000..84157b67b
--- /dev/null
+++ b/share/qbs/modules/cpp/watcom.qbs
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 Denis Shienkov <denis.shienkov@gmail.com>
+** 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 1.0
+import qbs.File
+import qbs.FileInfo
+import qbs.ModUtils
+import qbs.Probes
+import "cpp.js" as Cpp
+import "watcom.js" as WATCOM
+
+CppModule {
+ condition: qbs.toolchain && qbs.toolchain.includes("watcom")
+
+ Probes.BinaryProbe {
+ id: compilerPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["owcc"]
+ }
+
+ Probes.WatcomProbe {
+ id: watcomProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ _pathListSeparator: qbs.pathListSeparator
+ _toolchainInstallPath: toolchainInstallPath
+ _targetPlatform: qbs.targetPlatform
+ _targetArchitecture: qbs.architecture
+ }
+
+ qbs.architecture: watcomProbe.found ? watcomProbe.architecture : original
+ qbs.targetPlatform: watcomProbe.found ? watcomProbe.targetPlatform : original
+
+ compilerVersionMajor: watcomProbe.versionMajor
+ compilerVersionMinor: watcomProbe.versionMinor
+ compilerVersionPatch: watcomProbe.versionPatch
+ endianness: watcomProbe.endianness
+
+ compilerDefinesByLanguage: watcomProbe.compilerDefinesByLanguage
+ compilerIncludePaths: watcomProbe.includePaths
+
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
+
+ /* Work-around for QtCreator which expects these properties to exist. */
+ property string cCompilerName: compilerName
+ property string cxxCompilerName: compilerName
+
+ compilerName: "owcc" + compilerExtension
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+
+ assemblerName: "wasm" + compilerExtension
+ assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
+
+ linkerName: "wlink" + compilerExtension
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ property string disassemblerName: "wdis" + compilerExtension
+ property string disassemblerPath: FileInfo.joinPaths(toolchainInstallPath,
+ disassemblerName)
+ property string resourceCompilerName: "wrc" + compilerExtension
+ property string resourceCompilerPath: FileInfo.joinPaths(toolchainInstallPath,
+ resourceCompilerName)
+ property string libraryManagerName: "wlib" + compilerExtension
+ property string libraryManagerPath: FileInfo.joinPaths(toolchainInstallPath,
+ libraryManagerName)
+
+ runtimeLibrary: "dynamic"
+
+ staticLibrarySuffix: ".lib"
+ dynamicLibrarySuffix: toolchainDetails.dynamicLibrarySuffix
+ executableSuffix: toolchainDetails.executableSuffix
+ objectSuffix: ".obj"
+
+ imageFormat: toolchainDetails.imageFormat
+
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: "-include"
+ libraryDependencyFlag: "-l"
+ libraryPathFlag: "-L"
+ linkerScriptFlag: ""
+
+ toolchainDetails: WATCOM.toolchainDetails(qbs)
+
+ knownArchitectures: ["x86", "x86_16"]
+
+ property var buildEnv: watcomProbe.environment
+ setupBuildEnvironment: {
+ for (var key in product.cpp.buildEnv) {
+ var v = new ModUtils.EnvironmentVariable(key, product.qbs.pathListSeparator);
+ v.prepend(product.cpp.buildEnv[key]);
+ v.set();
+ }
+ }
+
+ Rule {
+ id: assembler
+ inputs: ["asm"]
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
+ prepare: WATCOM.prepareAssembler.apply(WATCOM, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.asm"]
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ id: compiler
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
+ prepare: WATCOM.prepareCompiler.apply(WATCOM, arguments)
+ }
+
+ Rule {
+ id: rccCompiler
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.resourceCompilerOutputTags()
+ outputArtifacts: Cpp.resourceCompilerOutputArtifacts(input)
+ prepare: WATCOM.prepareResourceCompiler.apply(WATCOM, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ id: applicationLinker
+ multiplex: true
+ inputs: ["obj", "res", "linkerscript"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
+ prepare: WATCOM.prepareLinker.apply(WATCOM, arguments)
+ }
+
+ Rule {
+ id: dynamicLibraryLinker
+ condition: qbs.targetOS.includes("windows")
+ multiplex: true
+ inputs: ["obj", "res"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.dynamicLibraryLinkerOutputTags();
+ outputArtifacts: Cpp.dynamicLibraryLinkerOutputArtifacts(product)
+ prepare: WATCOM.prepareLinker.apply(WATCOM, arguments)
+ }
+
+ Rule {
+ id: libraryManager
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
+ prepare: WATCOM.prepareLibraryManager.apply(WATCOM, arguments)
+ }
+
+ JobLimit {
+ jobPool: "watcom_job_pool"
+ jobCount: 1
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-clang-cl.qbs b/share/qbs/modules/cpp/windows-clang-cl.qbs
index 1b2833060..9aa9d7395 100644
--- a/share/qbs/modules/cpp/windows-clang-cl.qbs
+++ b/share/qbs/modules/cpp/windows-clang-cl.qbs
@@ -28,19 +28,19 @@
**
****************************************************************************/
-import qbs
+import qbs.Host
import qbs.ModUtils
import qbs.Probes
import qbs.FileInfo
import 'windows-msvc-base.qbs' as MsvcBaseModule
MsvcBaseModule {
- condition: qbs.hostOS.contains('windows') &&
- qbs.targetOS.contains('windows') &&
- qbs.toolchain && qbs.toolchain.contains('clang-cl')
+ condition: Host.os().includes('windows') &&
+ qbs.targetOS.includes('windows') &&
+ qbs.toolchain && qbs.toolchain.includes('clang-cl')
priority: 100
- Probes.BinaryProbe {
+ Probes.ClangClBinaryProbe {
id: clangPathProbe
condition: !toolchainInstallPath && !_skipAllChecks
names: ["clang-cl"]
@@ -52,9 +52,12 @@ MsvcBaseModule {
compilerFilePath: compilerPath
vcvarsallFilePath: vcvarsallPath
enableDefinesByLanguage: enableCompilerDefinesByLanguage
- architecture: qbs.architecture
+ preferredArchitecture: qbs.architecture
+ winSdkVersion: windowsSdkVersion
}
+ qbs.architecture: clangClProbe.found ? clangClProbe.architecture : original
+
compilerVersionMajor: clangClProbe.versionMajor
compilerVersionMinor: clangClProbe.versionMinor
compilerVersionPatch: clangClProbe.versionPatch
@@ -65,20 +68,34 @@ MsvcBaseModule {
: undefined
buildEnv: clangClProbe.buildEnv
- property string vcvarsallPath
+ property string linkerVariant
+ PropertyOptions {
+ name: "linkerVariant"
+ allowedValues: ["lld", "link"]
+ description: "Allows to specify the linker variant. Maps to clang-cl's -fuse-ld option."
+ }
+ Properties {
+ condition: linkerVariant
+ driverLinkerFlags: "-fuse-ld=" + linkerVariant
+ }
+
+ property string vcvarsallPath : clangPathProbe.found ? clangPathProbe.vcvarsallPath : undefined
compilerName: "clang-cl.exe"
linkerName: "lld-link.exe"
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+ systemIncludeFlag: "/imsvc"
+
validateFunc: {
+ var baseFunc = base;
return function() {
if (_skipAllChecks)
return;
var validator = new ModUtils.PropertyValidator("cpp");
validator.setRequiredProperty("vcvarsallPath", vcvarsallPath);
validator.validate();
- base();
+ baseFunc();
}
}
}
diff --git a/share/qbs/modules/cpp/windows-clang-mingw.qbs b/share/qbs/modules/cpp/windows-clang-mingw.qbs
index 8389dbf2e..cfe6f2745 100644
--- a/share/qbs/modules/cpp/windows-clang-mingw.qbs
+++ b/share/qbs/modules/cpp/windows-clang-mingw.qbs
@@ -30,6 +30,7 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Utilities
import "msvc.js" as MSVC
@@ -37,8 +38,8 @@ import "msvc.js" as MSVC
import "setuprunenv.js" as SetupRunEnv
MingwBaseModule {
- condition: qbs.targetOS.contains("windows") &&
- qbs.toolchain && qbs.toolchain.contains("clang")
+ condition: qbs.targetOS.includes("windows") &&
+ qbs.toolchain && qbs.toolchain.includes("clang")
priority: 0
// llvm-as and llvm-objopy are not shipped with the official binaries on Windows at the
@@ -68,16 +69,16 @@ MingwBaseModule {
"llvm-rc" + compilerExtension)
setupBuildEnvironment: {
- if (product.qbs.hostOS.contains("windows") && product.qbs.sysroot) {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ if (Host.os().includes("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.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);
+ if (Host.os().includes("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), true);
v.prepend(FileInfo.joinPaths(product.qbs.sysroot, "bin"));
v.set();
SetupRunEnv.setupRunEnvironment(product, config);
@@ -89,10 +90,11 @@ MingwBaseModule {
auxiliaryInputs: ["hpp"]
Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
+ filePath: FileInfo.joinPaths(Utilities.getHash(input.baseDir),
+ input.completeBaseName + ".res")
fileTags: ["obj"]
}
- prepare: MSVC.createRcCommand(product.cpp.rcFilePath, input, output);
+ 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 ffed76cdd..9ba4258c5 100644
--- a/share/qbs/modules/cpp/windows-mingw.qbs
+++ b/share/qbs/modules/cpp/windows-mingw.qbs
@@ -33,11 +33,12 @@ import qbs.FileInfo
import qbs.ModUtils
import qbs.Utilities
+import 'cpp.js' as Cpp
import "setuprunenv.js" as SetupRunEnv
MingwBaseModule {
- condition: qbs.targetOS.contains("windows") &&
- qbs.toolchain && qbs.toolchain.contains("mingw")
+ condition: qbs.targetOS.includes("windows") &&
+ qbs.toolchain && qbs.toolchain.includes("mingw")
priority: 0
probeEnv: buildEnv
@@ -51,13 +52,13 @@ MingwBaseModule {
}
setupBuildEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), true);
v.prepend(product.cpp.toolchainInstallPath);
v.set();
}
setupRunEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), true);
v.prepend(product.cpp.toolchainInstallPath);
v.set();
SetupRunEnv.setupRunEnvironment(product, config);
@@ -66,12 +67,8 @@ MingwBaseModule {
Rule {
inputs: ["rc"]
auxiliaryInputs: ["hpp"]
-
- Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + "_res.o"
- fileTags: ["obj"]
- }
-
+ outputFileTags: Cpp.resourceCompilerOutputTags()
+ outputArtifacts: Cpp.resourceCompilerOutputArtifacts(input)
prepare: {
var platformDefines = input.cpp.platformDefines;
var defines = input.cpp.defines;
@@ -96,6 +93,7 @@ MingwBaseModule {
args.push(systemIncludePaths[i]);
}
+ args.push("-O", "coff"); // Set COFF format explicitly.
args = args.concat(['-i', input.filePath, '-o', output.filePath]);
var cmd = new Command(product.cpp.windresPath, args);
cmd.description = 'compiling ' + input.fileName;
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
index aa1c8256c..9613800e5 100644
--- a/share/qbs/modules/cpp/windows-msvc-base.qbs
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -35,11 +35,14 @@ import qbs.PathTools
import qbs.Probes
import qbs.Utilities
import qbs.WindowsUtils
+import 'cpp.js' as Cpp
import 'msvc.js' as MSVC
CppModule {
condition: false
+ Depends { name: "codesign" }
+
windowsApiCharacterSet: "unicode"
platformDefines: {
var defines = base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
@@ -81,7 +84,6 @@ CppModule {
separateDebugInformation: true
property bool generateManifestFile: true
- property string toolchainInstallPath
architecture: qbs.architecture
endianness: "little"
@@ -89,9 +91,11 @@ CppModule {
dynamicLibrarySuffix: ".dll"
executableSuffix: ".exe"
debugInfoSuffix: ".pdb"
+ objectSuffix: ".obj"
+ precompiledHeaderSuffix: ".pch"
imageFormat: "pe"
Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
+ condition: product.multiplexByQbsProperties.includes("buildVariants")
&& qbs.buildVariants && qbs.buildVariants.length > 1
&& qbs.buildVariant !== "release"
&& product.type.containsAny(["staticlibrary", "dynamiclibrary"])
@@ -100,6 +104,9 @@ CppModule {
property var buildEnv
+ readonly property bool shouldSignArtifacts: codesign.enableCodeSigning
+ property bool enableCxxLanguageMacro: false
+
setupBuildEnvironment: {
for (var key in product.cpp.buildEnv) {
var v = new ModUtils.EnvironmentVariable(key, ';');
@@ -108,21 +115,21 @@ CppModule {
}
}
+ property string windowsSdkVersion
+
+ defineFlag: "/D"
+ includeFlag: "/I"
+ systemIncludeFlag: "/external:I"
+ preincludeFlag: "/FI"
+ libraryPathFlag: "/LIBPATH:"
+
Rule {
condition: useCPrecompiledHeader
inputs: ["c_pch_src"]
auxiliaryInputs: ["hpp"]
- Artifact {
- fileTags: ['obj']
- filePath: Utilities.getHash(input.completeBaseName) + '_c.obj'
- }
- Artifact {
- fileTags: ['c_pch']
- filePath: product.name + '_c.pch'
- }
- prepare: {
- return MSVC.prepareCompiler.apply(MSVC, arguments);
- }
+ outputFileTags: Cpp.precompiledHeaderOutputTags("c", true)
+ outputArtifacts: Cpp.precompiledHeaderOutputArtifacts(input, product, "c", true)
+ prepare: MSVC.prepareCompiler.apply(MSVC, arguments)
}
Rule {
@@ -130,17 +137,9 @@ CppModule {
inputs: ["cpp_pch_src"]
explicitlyDependsOn: ["c_pch"] // to prevent vc--0.pdb conflict
auxiliaryInputs: ["hpp"]
- Artifact {
- fileTags: ['obj']
- filePath: Utilities.getHash(input.completeBaseName) + '_cpp.obj'
- }
- Artifact {
- fileTags: ['cpp_pch']
- filePath: product.name + '_cpp.pch'
- }
- prepare: {
- return MSVC.prepareCompiler.apply(MSVC, arguments);
- }
+ outputFileTags: Cpp.precompiledHeaderOutputTags("cpp", true)
+ outputArtifacts: Cpp.precompiledHeaderOutputArtifacts(input, product, "cpp", true)
+ prepare: MSVC.prepareCompiler.apply(MSVC, arguments)
}
Rule {
@@ -148,21 +147,9 @@ CppModule {
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
explicitlyDependsOn: ["c_pch", "cpp_pch"]
-
- outputFileTags: ["obj", "intermediate_obj"]
- outputArtifacts: {
- var tags = input.fileTags.contains("cpp_intermediate_object")
- ? ["intermediate_obj"]
- : ["obj"];
- return [{
- fileTags: tags,
- filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj"
- }];
- }
-
- prepare: {
- return MSVC.prepareCompiler.apply(MSVC, arguments);
- }
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
+ prepare: MSVC.prepareCompiler.apply(MSVC, arguments)
}
FileTagger {
@@ -170,16 +157,29 @@ CppModule {
fileTags: ["native.pe.manifest"]
}
+ FileTagger {
+ patterns: ["*.def"]
+ fileTags: ["def"]
+ }
+
Rule {
name: "applicationLinker"
multiplex: true
- inputs: ['obj', 'native.pe.manifest']
+ inputs: ['obj', 'res', 'native.pe.manifest', 'def']
inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
- outputFileTags: ["application", "debuginfo_app", "mem_map"]
+ outputFileTags: {
+ var tags = ["application", "debuginfo_app"];
+ if (generateLinkerMapFile)
+ tags.push("mem_map");
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ return tags;
+ }
outputArtifacts: {
var app = {
- fileTags: ["application"],
+ fileTags: ["application"].concat(
+ product.cpp.shouldSignArtifacts ? ["codesign.signed_artifact"] : []),
filePath: FileInfo.joinPaths(
product.destinationDirectory,
PathTools.applicationFilePath(product))
@@ -197,33 +197,39 @@ CppModule {
fileTags: ["mem_map"],
filePath: FileInfo.joinPaths(
product.destinationDirectory,
- product.targetName + ".map")
+ product.targetName + product.cpp.linkerMapSuffix)
});
}
return artifacts;
}
- prepare: {
- return MSVC.prepareLinker.apply(MSVC, arguments);
- }
+ prepare: MSVC.prepareLinker.apply(MSVC, arguments)
}
Rule {
name: "dynamicLibraryLinker"
multiplex: true
- inputs: ['obj', 'native.pe.manifest']
+ inputs: ['obj', 'res', 'native.pe.manifest', 'def']
inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"]
- outputFileTags: ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"]
+ outputFileTags: {
+ var tags = ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"];
+ if (shouldSignArtifacts)
+ tags.push("codesign.signed_artifact");
+ return tags;
+ }
outputArtifacts: {
var artifacts = [
{
- fileTags: ["dynamiclibrary"],
- filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product)
+ fileTags: ["dynamiclibrary"].concat(
+ product.cpp.shouldSignArtifacts ? ["codesign.signed_artifact"] : []),
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.dynamicLibraryFilePath(product))
},
{
fileTags: ["dynamiclibrary_import"],
- filePath: product.destinationDirectory + "/" + PathTools.importLibraryFilePath(product),
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.importLibraryFilePath(product)),
alwaysUpdated: false
}
];
@@ -238,15 +244,13 @@ CppModule {
return artifacts;
}
- prepare: {
- return MSVC.prepareLinker.apply(MSVC, arguments);
- }
+ prepare: MSVC.prepareLinker.apply(MSVC, arguments)
}
Rule {
name: "libtool"
multiplex: true
- inputs: ["obj"]
+ inputs: ["obj", "res"]
inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
outputFileTags: ["staticlibrary", "debuginfo_cl"]
outputArtifacts: {
@@ -274,6 +278,10 @@ CppModule {
var fileName = FileInfo.toWindowsSeparators(inputs.obj[i].filePath)
args.push(fileName)
}
+ for (var i in inputs.res) {
+ var fileName = FileInfo.toWindowsSeparators(inputs.res[i].filePath)
+ args.push(fileName)
+ }
var cmd = new Command("lib.exe", args);
cmd.description = 'creating ' + lib.fileName;
cmd.highlight = 'linker';
@@ -292,12 +300,8 @@ CppModule {
Rule {
inputs: ["rc"]
auxiliaryInputs: ["hpp"]
-
- Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
- fileTags: ["obj"]
- }
-
+ outputFileTags: Cpp.resourceCompilerOutputTags()
+ outputArtifacts: Cpp.resourceCompilerOutputArtifacts(input)
prepare: {
// From MSVC 2010 on, the logo can be suppressed.
var logo = product.cpp.compilerVersionMajor >= 16
@@ -313,18 +317,14 @@ CppModule {
Rule {
inputs: ["asm"]
- Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj"
- fileTags: ["obj"]
- }
+ outputFileTags: Cpp.assemblerOutputTags(false)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
prepare: {
- var args = ["/nologo", "/c",
- "/Fo" + FileInfo.toWindowsSeparators(output.filePath),
- FileInfo.toWindowsSeparators(input.filePath)];
+ var args = ["/nologo", "/c", "/Fo" + FileInfo.toWindowsSeparators(output.filePath)];
if (product.cpp.debugInformation)
args.push("/Zi");
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'),
- ModUtils.moduleProperty(input, 'flags', 'asm'));
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
var cmd = new Command(product.cpp.assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.jobPool = "assembler";
diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs
index 59032d28a..c30cec239 100644
--- a/share/qbs/modules/cpp/windows-msvc.qbs
+++ b/share/qbs/modules/cpp/windows-msvc.qbs
@@ -29,17 +29,19 @@
**
****************************************************************************/
+import qbs.Host
import qbs.Probes
import "windows-msvc-base.qbs" as MsvcBaseModule
MsvcBaseModule {
- condition: qbs.hostOS.contains('windows') &&
- qbs.targetOS.contains('windows') &&
- qbs.toolchain && qbs.toolchain.contains('msvc')
+ condition: Host.os().includes('windows') &&
+ qbs.targetOS.includes('windows') &&
+ qbs.toolchain && qbs.toolchain.includes('msvc')
priority: 50
- Probes.BinaryProbe {
+ Probes.ClBinaryProbe {
id: compilerPathProbe
+ preferredArchitecture: qbs.architecture
condition: !toolchainInstallPath && !_skipAllChecks
names: ["cl"]
}
@@ -50,6 +52,7 @@ MsvcBaseModule {
compilerFilePath: compilerPath
enableDefinesByLanguage: enableCompilerDefinesByLanguage
preferredArchitecture: qbs.architecture
+ winSdkVersion: windowsSdkVersion
}
qbs.architecture: msvcProbe.found ? msvcProbe.architecture : original
@@ -63,4 +66,6 @@ MsvcBaseModule {
toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path
: undefined
buildEnv: msvcProbe.buildEnv
+
+ enableCxxLanguageMacro: true
}