aboutsummaryrefslogtreecommitdiffstats
path: root/share/qbs/modules
diff options
context:
space:
mode:
Diffstat (limited to 'share/qbs/modules')
-rw-r--r--share/qbs/modules/Android/ndk/ndk.qbs97
-rw-r--r--share/qbs/modules/Android/ndk/utils.js28
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs14
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs72
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs3
-rw-r--r--share/qbs/modules/cpp/android-gcc.qbs135
-rw-r--r--share/qbs/modules/cpp/iar.js59
-rw-r--r--share/qbs/modules/cpp/iar.qbs4
-rw-r--r--share/qbs/modules/cpp/keil.js38
-rw-r--r--share/qbs/modules/cpp/keil.qbs4
-rw-r--r--share/qbs/modules/cpp/msvc.js28
-rw-r--r--share/qbs/modules/cpp/sdcc.js380
-rw-r--r--share/qbs/modules/cpp/sdcc.qbs205
-rw-r--r--share/qbs/modules/cpp/windows-clang-cl.qbs84
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs372
-rw-r--r--share/qbs/modules/cpp/windows-msvc.qbs344
-rw-r--r--share/qbs/modules/protobuf/cpp/protobufcpp.qbs14
-rw-r--r--share/qbs/modules/protobuf/objc/protobufobjc.qbs16
-rw-r--r--share/qbs/modules/protobuf/protobufbase.qbs7
19 files changed, 1309 insertions, 595 deletions
diff --git a/share/qbs/modules/Android/ndk/ndk.qbs b/share/qbs/modules/Android/ndk/ndk.qbs
index 5d86d6e3a..3b104558c 100644
--- a/share/qbs/modules/Android/ndk/ndk.qbs
+++ b/share/qbs/modules/Android/ndk/ndk.qbs
@@ -47,68 +47,33 @@ Module {
readonly property string abi: NdkUtils.androidAbi(qbs.architecture)
PropertyOptions {
name: "abi"
- description: "Corresponds to the 'APP_ABI' variable in an Android.mk file."
- allowedValues: ["arm64-v8a", "armeabi", "armeabi-v7a", "mips", "mips64", "x86", "x86_64"]
+ description: "Supported Android ABIs"
+ allowedValues: ["arm64-v8a", "armeabi", "armeabi-v7a", "x86", "x86_64"]
}
- property string appStl: version && Utilities.versionCompare(version, "17") >= 0
- ? "c++_shared" : "system"
- PropertyOptions {
- name: "appStl"
- description: "Corresponds to the 'APP_STL' variable in an Android.mk file."
- allowedValues: [
- "system", "gabi++_static", "gabi++_shared", "stlport_static", "stlport_shared",
- "gnustl_static", "gnustl_shared", "c++_static", "c++_shared"
- ]
- }
+ // See https://developer.android.com/ndk/guides/cpp-support.html
+ property string appStl: "c++_shared"
- property string toolchainVersion: latestToolchainVersion
PropertyOptions {
- name: "toolchainVersion"
- description: "Corresponds to the 'NDK_TOOLCHAIN_VERSION' variable in an Android.mk file."
+ name: "appStl"
+ description: "C++ Runtime Libraries."
+ allowedValues: ["c++_static", "c++_shared"]
}
property string hostArch: ndkProbe.hostArch
property string ndkDir: ndkProbe.path
property string ndkSamplesDir: ndkProbe.samplesDir
- property string platform: ndkProbe.ndkPlatform
-
- property bool useUnifiedHeaders: version && Utilities.versionCompare(version, "15") >= 0
-
- // Internal properties.
- property stringList availableToolchains: ndkProbe.toolchains
-
- property stringList availableToolchainVersions: {
- var tcs = availableToolchains;
- var versions = [];
- for (var i = 0; i < tcs.length; ++i) {
- if ((qbs.toolchain.contains("clang") && tcs[i].startsWith("llvm-"))
- || toolchainDirPrefixAbis.contains(tcs[i].split("-")[0])) {
- var re = /\-((?:[0-9]+)\.(?:[0-9]+))$/;
- var m = tcs[i].match(re);
- if (m)
- versions.push(m[1]);
- }
+ property string platform: {
+ switch (abi) {
+ case "armeabi":
+ case "armeabi-v7a":
+ // case "x86": // x86 has broken wstring support
+ return "android-19";
+ default:
+ return "android-21";
}
-
- // Sort by version number
- versions.sort(function (a, b) {
- var re = /^([0-9]+)\.([0-9]+)$/;
- a = a.match(re);
- a = {major: a[1], minor: a[2]};
- b = b.match(re);
- b = {major: b[1], minor: b[2]};
- if (a.major === b.major)
- return a.minor - b.minor;
- return a.major - b.major;
- });
-
- return versions;
}
- property string latestToolchainVersion: availableToolchainVersions
- [availableToolchainVersions.length - 1]
-
property int platformVersion: {
if (platform) {
var match = platform.match(/^android-([0-9]+)$/);
@@ -120,29 +85,13 @@ Module {
property stringList abis: {
var list = ["armeabi", "armeabi-v7a"];
- if (platformVersion >= 9)
- list.push("mips", "x86");
- if (platformVersion >= 21)
- list.push("arm64-v8a", "mips64", "x86_64");
- return list;
- }
-
- property stringList toolchainDirPrefixAbis: {
- var list = ["arm"];
- if (platformVersion >= 9)
- list.push("mipsel", "x86");
+ if (platformVersion >= 16)
+ list.push("x86");
if (platformVersion >= 21)
- list.push("aarch64", "mips64el", "x86_64");
+ list.push("arm64-v8a", "x86_64");
return list;
}
- property string toolchainVersionNumber: {
- var prefix = "clang";
- if (toolchainVersion && toolchainVersion.startsWith(prefix))
- return toolchainVersion.substr(prefix.length);
- return toolchainVersion;
- }
-
property string armMode: abi && abi.startsWith("armeabi")
? (qbs.buildVariant === "debug" ? "arm" : "thumb")
: undefined;
@@ -152,8 +101,6 @@ Module {
allowedValues: ["arm", "thumb"]
}
- property bool haveUnifiedStl: version && Utilities.versionCompare(version, "12") >= 0
-
validate: {
if (!ndkDir) {
throw ModUtils.ModuleError("Could not find an Android NDK at any of the following "
@@ -163,15 +110,19 @@ Module {
+ "ANDROID_NDK_ROOT environment variable to a valid "
+ "Android NDK location.");
}
+
+ if (Utilities.versionCompare(version, "19") < 0)
+ throw ModUtils.ModuleError("Unsupported NDK version "
+ + Android.ndk.version
+ + ", please upgrade your NDK to r19+");
+
if (product.aggregate && !product.multiplexConfigurationId)
return;
var validator = new ModUtils.PropertyValidator("Android.ndk");
validator.setRequiredProperty("abi", abi);
validator.setRequiredProperty("appStl", appStl);
- validator.setRequiredProperty("toolchainVersion", toolchainVersion);
validator.setRequiredProperty("hostArch", hostArch);
validator.setRequiredProperty("platform", platform);
- validator.setRequiredProperty("toolchainVersionNumber", toolchainVersionNumber);
return validator.validate();
}
}
diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js
index 3bc3b6d9d..739c205ae 100644
--- a/share/qbs/modules/Android/ndk/utils.js
+++ b/share/qbs/modules/Android/ndk/utils.js
@@ -28,6 +28,8 @@
**
****************************************************************************/
+var Utilities = require("qbs.Utilities")
+
function abiNameToDirName(abiName) {
switch (abiName) {
case "armeabi":
@@ -50,21 +52,16 @@ function androidAbi(arch) {
case "armv7":
case "armv7a":
return "armeabi-v7a";
- case "mips":
- case "mipsel":
- return "mips";
- case "mips64":
- case "mips64el":
- return "mips64";
default:
return arch;
}
}
-function commonCompilerFlags(toolchain, buildVariant, abi, armMode) {
- var flags = ["-ffunction-sections", "-funwind-tables",
- "-Werror=format-security", "-fstack-protector-strong"];
+function commonCompilerFlags(toolchain, buildVariant, ndk) {
+ var flags = ["-Werror=format-security"];
+ var abi = ndk.abi;
+ var armMode = ndk.armMode;
if (abi === "arm64-v8a")
flags.push("-fpic");
@@ -86,12 +83,17 @@ function commonCompilerFlags(toolchain, buildVariant, abi, armMode) {
"-frerun-cse-after-loop", "-frename-registers");
}
- if ((abi === "x86" || abi === "x86_64") && toolchain.contains("clang"))
+ if (abi === "x86" || abi === "x86_64")
flags.push("-fPIC");
+ flags.push("-fno-limit-debug-info");
+
if (armMode)
flags.push("-m" + armMode);
+ // TODO: Remove when https://github.com/android-ndk/ndk/issues/884 is fixed.
+ flags.push("-fno-addrsig");
+
return flags;
}
@@ -99,8 +101,6 @@ function commonLinkerFlags(abi) {
return ["-z", "noexecstack", "-z", "relro", "-z", "now"];
}
-function getBinutilsPath(ndk, toolchainPrefix) {
- if (["x86", "x86_64"].contains(ndk.abi))
- return ndk.abi + "-" + ndk.toolchainVersionNumber;
- return toolchainPrefix + ndk.toolchainVersionNumber;
+function stlFilePath(path, ndk, suffix) {
+ return path + ndk.appStl.slice(0, ndk.appStl.indexOf('_')) + suffix + "." + ndk.platformVersion;
}
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index 14ad92fdf..f8a046c3a 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -61,7 +61,14 @@ Module {
property string platform: sdkProbe.platform
// Product-specific properties and files
- property string packageName: product.name
+ property string packageName: {
+ var idx = product.name.indexOf(".")
+ if (idx > 0 && idx < product.name.length)
+ return product.name;
+ return "com.example." + product.name;
+ }
+ property int versionCode
+ property string versionName
property string apkBaseName: packageName
property bool automaticSources: true
property bool legacyLayout: false
@@ -266,7 +273,10 @@ Module {
+ "'com.mycompany.myproduct' pattern."
}
rootElem.setAttribute("package", packageName);
-
+ if (product.Android.sdk.versionCode !== undefined)
+ rootElem.setAttribute("android:versionCode", product.Android.sdk.versionCode);
+ if (product.Android.sdk.versionName !== undefined)
+ rootElem.setAttribute("android:versionName", product.Android.sdk.versionName);
manifestData.save(output.filePath, 4);
}
return cmd;
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index 01b0f8af9..35a5de4f0 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -454,42 +454,48 @@ Module {
fileTags: ["hpp"]
}
- validate: {
- var validator = new ModUtils.PropertyValidator("cpp");
- validator.setRequiredProperty("architecture", architecture,
- "you might want to re-run 'qbs-setup-toolchains'");
- validator.addCustomValidator("architecture", architecture, function (value) {
- return !architecture || architecture === Utilities.canonicalArchitecture(architecture);
- }, "'" + architecture + "' is invalid. You must use the canonical name '" +
- Utilities.canonicalArchitecture(architecture) + "'");
- validator.setRequiredProperty("endianness", endianness);
- validator.setRequiredProperty("compilerDefinesByLanguage", compilerDefinesByLanguage);
- validator.setRequiredProperty("compilerVersion", compilerVersion);
- validator.setRequiredProperty("compilerVersionMajor", compilerVersionMajor);
- validator.setRequiredProperty("compilerVersionMinor", compilerVersionMinor);
- validator.setRequiredProperty("compilerVersionPatch", compilerVersionPatch);
- validator.addVersionValidator("compilerVersion", compilerVersion, 3, 3);
- validator.addRangeValidator("compilerVersionMajor", compilerVersionMajor, 1);
- validator.addRangeValidator("compilerVersionMinor", compilerVersionMinor, 0);
- validator.addRangeValidator("compilerVersionPatch", compilerVersionPatch, 0);
- if (minimumWindowsVersion) {
- validator.addVersionValidator("minimumWindowsVersion", minimumWindowsVersion, 2, 2);
- validator.addCustomValidator("minimumWindowsVersion", minimumWindowsVersion, function (v) {
- return !v || v === WindowsUtils.canonicalizeVersion(v);
- }, "'" + minimumWindowsVersion + "' is invalid. Did you mean '" +
- WindowsUtils.canonicalizeVersion(minimumWindowsVersion) + "'?");
- }
- validator.validate();
-
- if (minimumWindowsVersion && !WindowsUtils.isValidWindowsVersion(minimumWindowsVersion)) {
- console.warn("Unknown Windows version '" + minimumWindowsVersion
- + "'; expected one of: "
- + WindowsUtils.knownWindowsVersions().map(function (a) {
- return '"' + a + '"'; }).join(", ")
- + ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version");
+ property var validateFunc: {
+ return function() {
+ var validator = new ModUtils.PropertyValidator("cpp");
+ validator.setRequiredProperty("architecture", architecture,
+ "you might want to re-run 'qbs-setup-toolchains'");
+ validator.addCustomValidator("architecture", architecture, function (value) {
+ return !architecture || architecture === Utilities.canonicalArchitecture(architecture);
+ }, "'" + architecture + "' is invalid. You must use the canonical name '" +
+ Utilities.canonicalArchitecture(architecture) + "'");
+ validator.setRequiredProperty("endianness", endianness);
+ validator.setRequiredProperty("compilerDefinesByLanguage", compilerDefinesByLanguage);
+ validator.setRequiredProperty("compilerVersion", compilerVersion);
+ validator.setRequiredProperty("compilerVersionMajor", compilerVersionMajor);
+ validator.setRequiredProperty("compilerVersionMinor", compilerVersionMinor);
+ validator.setRequiredProperty("compilerVersionPatch", compilerVersionPatch);
+ validator.addVersionValidator("compilerVersion", compilerVersion, 3, 3);
+ validator.addRangeValidator("compilerVersionMajor", compilerVersionMajor, 1);
+ validator.addRangeValidator("compilerVersionMinor", compilerVersionMinor, 0);
+ validator.addRangeValidator("compilerVersionPatch", compilerVersionPatch, 0);
+ if (minimumWindowsVersion) {
+ validator.addVersionValidator("minimumWindowsVersion", minimumWindowsVersion, 2, 2);
+ validator.addCustomValidator("minimumWindowsVersion", minimumWindowsVersion, function (v) {
+ return !v || v === WindowsUtils.canonicalizeVersion(v);
+ }, "'" + minimumWindowsVersion + "' is invalid. Did you mean '" +
+ WindowsUtils.canonicalizeVersion(minimumWindowsVersion) + "'?");
+ }
+ validator.validate();
+
+ if (minimumWindowsVersion && !WindowsUtils.isValidWindowsVersion(minimumWindowsVersion)) {
+ console.warn("Unknown Windows version '" + minimumWindowsVersion
+ + "'; expected one of: "
+ + WindowsUtils.knownWindowsVersions().map(function (a) {
+ return '"' + a + '"'; }).join(", ")
+ + ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version");
+ }
}
}
+ validate: {
+ return validateFunc();
+ }
+
setupRunEnvironment: {
SetupRunEnv.setupRunEnvironment(product, config);
}
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index b4e755a3e..f9537884e 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -729,6 +729,9 @@ CppModule {
match = regexp.exec(linkerScript.readLine());
if(match) {
var additionalPath = match[1];
+ // path can be quoted to use non-latin letters, remove quotes if present
+ if (additionalPath.startsWith("\"") && additionalPath.endsWith("\""))
+ additionalPath = additionalPath.slice(1, additionalPath.length - 1);
retval.push(additionalPath);
}
}
diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs
index 7079d95b4..7642b246a 100644
--- a/share/qbs/modules/cpp/android-gcc.qbs
+++ b/share/qbs/modules/cpp/android-gcc.qbs
@@ -39,44 +39,17 @@ import 'gcc.js' as Gcc
LinuxGCC {
Depends { name: "Android.ndk" }
- condition: qbs.targetOS.contains("android") &&
- qbs.toolchain && qbs.toolchain.contains("gcc")
+ condition: qbs.targetOS.contains("android") && qbs.toolchain && qbs.toolchain.contains("llvm")
priority: 2
rpaths: [rpathOrigin]
- property string toolchainDir: {
- if (qbs.toolchain && qbs.toolchain.contains("clang")) {
- return Utilities.versionCompare(Android.ndk.version, "10") <= 0
- ? "llvm-" + Android.ndk.toolchainVersionNumber : "llvm";
- }
- return NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-")
- }
-
+ cxxLanguageVersion: "c++14"
property string cxxStlBaseDir: FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "cxx-stl")
- property string gabiBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "gabi++")
- property string stlPortBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "stlport")
- property string gnuStlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "gnu-libstdc++",
- Android.ndk.toolchainVersionNumber)
- property string llvmStlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "llvm-libc++")
- property string stlBaseDir: {
- if (Android.ndk.appStl.startsWith("gabi++_"))
- return gabiBaseDir;
- else if (Android.ndk.appStl.startsWith("stlport_"))
- return stlPortBaseDir;
- else if (Android.ndk.appStl.startsWith("gnustl_"))
- return gnuStlBaseDir;
- else if (Android.ndk.appStl.startsWith("c++_"))
- return llvmStlBaseDir;
- return undefined;
- }
+ property string stlBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "llvm-libc++")
property string stlLibsDir: {
- if (stlBaseDir) {
- var infix = Android.ndk.abi;
- if (Android.ndk.armMode === "thumb" && !Android.ndk.haveUnifiedStl)
- infix = FileInfo.joinPaths(infix, "thumb");
- return FileInfo.joinPaths(stlBaseDir, "libs", infix);
- }
+ if (stlBaseDir)
+ return FileInfo.joinPaths(stlBaseDir, "libs", Android.ndk.abi);
return undefined;
}
@@ -84,7 +57,7 @@ LinuxGCC {
? FileInfo.joinPaths(stlLibsDir, dynamicLibraryPrefix + Android.ndk.appStl + dynamicLibrarySuffix)
: undefined
property string staticStlFilePath: (stlLibsDir && Android.ndk.appStl.endsWith("_static"))
- ? FileInfo.joinPaths(stlLibsDir, staticLibraryPrefix + Android.ndk.appStl + staticLibrarySuffix)
+ ? FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(staticLibraryPrefix, Android.ndk, staticLibrarySuffix))
: undefined
Group {
@@ -104,17 +77,13 @@ LinuxGCC {
}
toolchainInstallPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains",
- toolchainDir, "prebuilt",
+ "llvm", "prebuilt",
Android.ndk.hostArch, "bin")
property string toolchainTriple: [targetAbi === "androideabi" ? "arm" : targetArch,
targetSystem, targetAbi].join("-")
- toolchainPrefix: {
- if (qbs.toolchain && qbs.toolchain.contains("clang"))
- return undefined;
- return toolchainTriple + "-";
- }
+ toolchainPrefix: undefined
machineType: {
if (Android.ndk.abi === "armeabi")
@@ -128,87 +97,61 @@ LinuxGCC {
enableExceptions: Android.ndk.appStl !== "system"
enableRtti: Android.ndk.appStl !== "system"
- commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.toolchain, qbs.buildVariant,
- Android.ndk.abi, Android.ndk.armMode)
+ commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.toolchain, qbs.buildVariant, Android.ndk)
- linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi)
+ linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi);
+ driverLinkerFlags: {
+ var flags = ["-fuse-ld=lld", "-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a"];
+ if (Android.ndk.appStl.startsWith("c++") && Android.ndk.abi === "armeabi-v7a")
+ flags = flags.concat(["-Wl,--exclude-libs,libunwind.a"]);
+ return flags;
+ }
- platformDriverFlags: ["-no-canonical-prefixes"]
+ 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 === "mips64" || Android.ndk.abi === "x86_64") // no lib64 for arm64-v8a
+ 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(sharedStlFilePath);
- return libs;
- }
- staticLibraries: {
- var libs = ["gcc"];
- if (staticStlFilePath) {
- libs.push(staticStlFilePath);
- if (Android.ndk.appStl === "c++_static") {
- var libAbi = FileInfo.joinPaths(stlLibsDir, "libc++abi.a");
- if (File.exists(libAbi))
- libs.push(libAbi);
- }
- }
+ libs.push(FileInfo.joinPaths(stlLibsDir, NdkUtils.stlFilePath(dynamicLibraryPrefix, Android.ndk, dynamicLibrarySuffix)));
return libs;
}
+ staticLibraries: staticStlFilePath
systemIncludePaths: {
- var includes = [];
- if (Android.ndk.useUnifiedHeaders) {
- // Might not be needed with Clang in a future NDK release
- includes.push(FileInfo.joinPaths(sysroot, "usr", "include", toolchainTriple));
- }
- if (Android.ndk.appStl === "system") {
- includes.push(FileInfo.joinPaths(cxxStlBaseDir, "system", "include"));
- } else if (Android.ndk.appStl.startsWith("gabi++")) {
- includes.push(FileInfo.joinPaths(gabiBaseDir, "include"));
- } else if (Android.ndk.appStl.startsWith("stlport")) {
- includes.push(FileInfo.joinPaths(stlPortBaseDir, "stlport"));
- } else if (Android.ndk.appStl.startsWith("gnustl")) {
- includes.push(FileInfo.joinPaths(gnuStlBaseDir, "include"));
- includes.push(FileInfo.joinPaths(gnuStlBaseDir, "libs", Android.ndk.abi, "include"));
- includes.push(FileInfo.joinPaths(gnuStlBaseDir, "include", "backward"));
- } else if (Android.ndk.appStl.startsWith("c++_")) {
- if (Utilities.versionCompare(Android.ndk.version, "13") >= 0) {
- includes.push(FileInfo.joinPaths(llvmStlBaseDir, "include"));
- includes.push(FileInfo.joinPaths(llvmStlBaseDir + "abi", "include"));
- } else {
- includes.push(FileInfo.joinPaths(llvmStlBaseDir, "libcxx", "include"));
- includes.push(FileInfo.joinPaths(llvmStlBaseDir + "abi", "libcxxabi", "include"));
- }
+ 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"];
- if (Android.ndk.useUnifiedHeaders) {
- // Might be superseded by an -mandroid-version or similar Clang compiler flag in future
- list.push("__ANDROID_API__=" + Android.ndk.platformVersion);
- }
+ // Might be superseded by an -mandroid-version or similar Clang compiler flag in future
+ list.push("__ANDROID_API__=" + Android.ndk.platformVersion);
return list;
}
- binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains",
- NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-"),
- "prebuilt", Android.ndk.hostArch, "bin");
- binutilsPathPrefix: Gcc.pathPrefix(binutilsPath, toolchainTriple + "-")
- driverFlags: qbs.toolchain.contains("clang")
- ? ["-gcc-toolchain", FileInfo.path(binutilsPath)].concat(base || []) : base
+
+ binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", "llvm", "prebuilt",
+ Android.ndk.hostArch, "bin");
+ binutilsPathPrefix: "llvm-"
syslibroot: FileInfo.joinPaths(Android.ndk.ndkDir, "platforms",
Android.ndk.platform, "arch-"
+ NdkUtils.abiNameToDirName(Android.ndk.abi))
- sysroot: !Android.ndk.useUnifiedHeaders
- ? syslibroot
- : FileInfo.joinPaths(Android.ndk.ndkDir, "sysroot")
+ sysroot: FileInfo.joinPaths(Android.ndk.ndkDir, "sysroot")
targetArch: {
switch (qbs.architecture) {
@@ -222,12 +165,6 @@ LinuxGCC {
return qbs.architecture;
case "x86":
return "i686";
- case "mips":
- case "mipsel":
- return "mipsel";
- case "mips64":
- case "mips64el":
- return "mips64el";
}
}
diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js
index 35ed29da3..646826e8a 100644
--- a/share/qbs/modules/cpp/iar.js
+++ b/share/qbs/modules/cpp/iar.js
@@ -56,16 +56,18 @@ function guessEndianness(macros)
return "big"
}
-function dumpMacros(compilerFilePath, qbs, nullDevice) {
+function dumpMacros(compilerFilePath, tag) {
var tempDir = new TemporaryDir();
var inFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/empty-source.c");
var inFile = new TextFile(inFilePath, TextFile.WriteOnly);
var outFilePath = FileInfo.fromNativeSeparators(tempDir.path() + "/iar-macros.predef");
- var p = new Process();
- p.exec(compilerFilePath,
- [ inFilePath, "--predef_macros", outFilePath ],
- true);
+ var args = [ inFilePath, "--predef_macros", outFilePath ];
+ if (tag && tag === "cpp")
+ args.push("--ec++");
+
+ var p = new Process();
+ p.exec(compilerFilePath, args, true);
var outFile = new TextFile(outFilePath, TextFile.ReadOnly);
var map = {};
outFile.readAll().trim().split(/\r?\n/g).map(function (line) {
@@ -75,6 +77,53 @@ function dumpMacros(compilerFilePath, qbs, nullDevice) {
return map;
}
+function dumpDefaultPaths(compilerFilePath, tag) {
+ 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")
+ args.push("--ec++");
+
+ var p = new Process();
+ // This process should return an error, 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 = [];
diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs
index 3dea255db..6d15781a5 100644
--- a/share/qbs/modules/cpp/iar.qbs
+++ b/share/qbs/modules/cpp/iar.qbs
@@ -50,6 +50,7 @@ CppModule {
id: iarProbe
condition: !_skipAllChecks
compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
}
qbs.architecture: iarProbe.found ? iarProbe.architecture : original
@@ -59,7 +60,8 @@ CppModule {
compilerVersionPatch: iarProbe.versionPatch
endianness: iarProbe.endianness
- compilerDefinesByLanguage: []
+ compilerDefinesByLanguage: iarProbe.compilerDefinesByLanguage
+ compilerIncludePaths: iarProbe.includePaths
property string toolchainInstallPath: compilerPathProbe.found
? compilerPathProbe.path : undefined
diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js
index 314d84c69..c19fdd738 100644
--- a/share/qbs/modules/cpp/keil.js
+++ b/share/qbs/modules/cpp/keil.js
@@ -81,7 +81,11 @@ function guessVersion(macros)
// 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, qbs) {
+function dumpC51CompilerMacros(compilerFilePath, tag) {
+ // C51 compiler support only C language.
+ if (tag === "cpp")
+ return {};
+
function createDumpMacrosFile() {
var td = new TemporaryDir();
var fn = FileInfo.fromNativeSeparators(td.path() + "/dump-macros.c");
@@ -107,11 +111,13 @@ function dumpC51CompilerMacros(compilerFilePath, qbs) {
return map;
}
-function dumpArmCompilerMacros(compilerFilePath, qbs, nullDevice) {
+function dumpArmCompilerMacros(compilerFilePath, tag, nullDevice) {
+ var args = [ "-E", "--list-macros", nullDevice ];
+ if (tag === "cpp")
+ args.push("--cpp");
+
var p = new Process();
- p.exec(compilerFilePath,
- [ "-E", "--list-macros", nullDevice ],
- false);
+ p.exec(compilerFilePath, args, false);
var map = {};
p.readStdOut().trim().split(/\r?\n/g).map(function (line) {
if (!line.startsWith("#define"))
@@ -122,9 +128,9 @@ function dumpArmCompilerMacros(compilerFilePath, qbs, nullDevice) {
return map;
}
-function dumpMacros(compilerFilePath, qbs, nullDevice) {
- var map1 = dumpC51CompilerMacros(compilerFilePath, qbs);
- var map2 = dumpArmCompilerMacros(compilerFilePath, qbs, nullDevice);
+function dumpMacros(compilerFilePath, tag, nullDevice) {
+ var map1 = dumpC51CompilerMacros(compilerFilePath, tag, nullDevice);
+ var map2 = dumpArmCompilerMacros(compilerFilePath, tag, nullDevice);
var map = {};
for (var attrname in map1)
map[attrname] = map1[attrname];
@@ -133,6 +139,22 @@ function dumpMacros(compilerFilePath, qbs, nullDevice) {
return map;
}
+function dumpDefaultPaths(compilerFilePath, architecture) {
+ var includePaths = [];
+
+ if (architecture === "mcs51") {
+ var path = compilerFilePath.replace(/bin[\\\/](.*)$/i, "inc");
+ includePaths.push(path);
+ } else if (architecture === "arm") {
+ var path = compilerFilePath.replace(/bin[\\\/](.*)$/i, "include");
+ includePaths.push(path);
+ }
+
+ return {
+ "includePaths": includePaths
+ };
+}
+
function adjustPathsToWindowsSeparators(sourcePaths) {
var resulingPaths = [];
sourcePaths.forEach(function(path) {
diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs
index dab37801a..10bc39e12 100644
--- a/share/qbs/modules/cpp/keil.qbs
+++ b/share/qbs/modules/cpp/keil.qbs
@@ -50,6 +50,7 @@ CppModule {
id: keilProbe
condition: !_skipAllChecks
compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
}
qbs.architecture: keilProbe.found ? keilProbe.architecture : original
@@ -59,7 +60,8 @@ CppModule {
compilerVersionPatch: keilProbe.versionPatch
endianness: keilProbe.endianness
- compilerDefinesByLanguage: []
+ compilerDefinesByLanguage: keilProbe.compilerDefinesByLanguage
+ compilerIncludePaths: keilProbe.includePaths
property string toolchainInstallPath: compilerPathProbe.found
? compilerPathProbe.path : undefined
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index 1864c40e1..5da2ad0cf 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -62,7 +62,8 @@ 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;
+ return Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0
+ || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 7);
}
function addLanguageVersionFlag(input, args) {
@@ -72,7 +73,9 @@ function addLanguageVersionFlag(input, args) {
return;
// Visual C++ 2013, Update 3
- var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0;
+ var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0
+ // or clang-cl
+ || input.qbs.toolchain.contains("clang-cl");
if (!hasStdOption)
return;
@@ -210,10 +213,20 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var pchInputs = explicitlyDependsOn[tag + "_pch"];
if (pchOutput) {
// create PCH
- args.push("/Yc");
- args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath));
- args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath));
- args.push(FileInfo.toWindowsSeparators(input.filePath));
+ if (input.qbs.toolchain.contains("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
+ args.push("/FI" + FileInfo.toWindowsSeparators(input.filePath));
+ args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath));
+ args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath));
+ } else { // real msvc
+ args.push("/Yc");
+ args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath));
+ args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath));
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
+ }
+
} else if (pchInputs && pchInputs.length === 1
&& ModUtils.moduleProperty(input, "usePrecompiledHeader", tag)) {
// use PCH
@@ -399,7 +412,8 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
'subsystem');
if (subsystemVersion) {
subsystemSwitch += ',' + subsystemVersion;
- args.push('/OSVERSION:' + subsystemVersion);
+ if (product.cpp.linkerName !== "lld-link.exe") // llvm linker does not support /OSVERSION
+ args.push('/OSVERSION:' + subsystemVersion);
}
}
diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js
new file mode 100644
index 000000000..2f148d2c2
--- /dev/null
+++ b/share/qbs/modules/cpp/sdcc.js
@@ -0,0 +1,380 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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");
+var WindowsUtils = require("qbs.WindowsUtils");
+
+function targetArchitectureFlag(architecture) {
+ if (architecture === "mcs51")
+ return "-mmcs51";
+}
+
+function guessArchitecture(macros)
+{
+ if (macros["__SDCC_mcs51"] === "1")
+ return "mcs51";
+}
+
+function guessEndianness(macros)
+{
+ // SDCC stores numbers in little-endian format.
+ return "little";
+}
+
+function dumpMacros(compilerFilePath, architecture) {
+ var tempDir = new TemporaryDir();
+ var fakeIn = new TextFile(tempDir.path() + "/empty-source.c", TextFile.WriteOnly);
+ var args = [ fakeIn.filePath(), "-dM", "-E" ];
+
+ var targetFlag = targetArchitectureFlag(architecture);
+ if (targetFlag)
+ args.push(targetFlag);
+
+ 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;
+}
+
+function dumpDefaultPaths(compilerFilePath, architecture) {
+ var args = [ "--print-search-dirs" ];
+
+ var targetFlag = targetArchitectureFlag(architecture);
+ if (targetFlag)
+ args.push(targetFlag);
+
+ var p = new Process();
+ p.exec(compilerFilePath, args, true);
+ var includePaths = [];
+ var addIncludePaths = false;
+ var lines = p.readStdOut().trim().split(/\r?\n/g);
+ for (var i in lines) {
+ var line = lines[i];
+ if (line.startsWith("includedir:")) {
+ addIncludePaths = true;
+ } else if (line.startsWith("programs:")
+ || line.startsWith("datadir:")
+ || line.startsWith("libdir:")
+ || line.startsWith("libpath:")) {
+ addIncludePaths = false;
+ } else if (addIncludePaths) {
+ includePaths.push(line);
+ }
+ }
+
+ return {
+ "includePaths": includePaths
+ }
+}
+
+function effectiveLinkerPath(product) {
+ if (product.cpp.linkerMode === "automatic")
+ return product.cpp.compilerPath;
+ return product.cpp.linkerPath;
+}
+
+function useCompilerDriverLinker(product) {
+ var linker = effectiveLinkerPath(product);
+ return linker === product.cpp.compilerPath;
+}
+
+function escapeLinkerFlags(product, linkerFlags) {
+ if (!linkerFlags || linkerFlags.length === 0 || !useCompilerDriverLinker(product))
+ return 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);
+ }
+ }
+
+ product.dependencies.forEach(traverse);
+ addExternalStaticLibs(product);
+ return result;
+}
+
+function compilerFlags(project, product, input, output, explicitlyDependsOn) {
+ // Determine which C-language we"re compiling.
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
+
+ var args = [];
+
+ args.push(input.filePath);
+ args.push("-c");
+ args.push("-o", output.filePath);
+
+ switch (input.cpp.optimization) {
+ case "small":
+ args.push("--opt-code-size");
+ break;
+ case "fast":
+ args.push("--opt-code-speed");
+ break;
+ case "none":
+ // SDCC has not option to disable the optimization.
+ break;
+ }
+
+ if (input.cpp.debugInformation)
+ args.push("--debug");
+
+ var warnings = input.cpp.warningLevel;
+ if (warnings === "none")
+ args.push("--less-pedantic");
+
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("--Werror");
+
+ if (tag === "c") {
+ if (input.cpp.cLanguageVersion === "c89")
+ args.push("--std-c89");
+ else if (input.cpp.cLanguageVersion === "c11")
+ args.push("--std-c11");
+ }
+
+ var allDefines = [];
+ var platformDefines = input.cpp.platformDefines;
+ if (platformDefines)
+ allDefines = allDefines.uniqueConcat(platformDefines);
+ var defines = input.cpp.defines;
+ if (defines)
+ allDefines = allDefines.uniqueConcat(defines);
+ args = args.concat(allDefines.map(function(define) { return "-D" + define }));
+
+ var allIncludePaths = [];
+ var includePaths = input.cpp.includePaths;
+ if (includePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
+ var systemIncludePaths = input.cpp.systemIncludePaths;
+ if (systemIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(systemIncludePaths);
+ var compilerIncludePaths = input.cpp.compilerIncludePaths;
+ if (compilerIncludePaths)
+ allIncludePaths = allIncludePaths.uniqueConcat(compilerIncludePaths);
+ args = args.concat(allIncludePaths.map(function(include) { return "-I" + include }));
+
+ args = 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));
+
+ return args;
+}
+
+function assemblerFlags(project, product, input, output, explicitlyDependsOn) {
+ // Determine which C-language we"re compiling
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
+
+ var args = [];
+ args.push(input.filePath);
+ args.push("-o", output.filePath);
+
+ 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(ModUtils.moduleProperty(input, "platformFlags", tag),
+ ModUtils.moduleProperty(input, "flags", tag),
+ ModUtils.moduleProperty(input, "driverFlags", tag));
+ return args;
+}
+
+function linkerFlags(project, product, input, outputs) {
+ var args = [];
+
+ 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 = [];
+
+ if (product.cpp.generateMapFile)
+ 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);
+
+ var useCompilerDriver = useCompilerDriverLinker(product);
+ if (useCompilerDriver) {
+ args.push("-o", outputs.application[0].filePath);
+
+ if (inputs.obj)
+ args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+
+ args = args.concat(allLibraryPaths.map(function(path) { return "-L" + path }));
+
+ var scripts = inputs.linkerscript
+ ? inputs.linkerscript.map(function(scr) { return "-f" + scr.filePath; }) : [];
+ if (scripts)
+ Array.prototype.push.apply(escapableLinkerFlags, scripts);
+ } else {
+ args.push(outputs.application[0].filePath);
+
+ if (inputs.obj)
+ args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+
+ args = args.concat(allLibraryPaths.map(function(path) { return "-k" + path }));
+
+ var scripts = inputs.linkerscript;
+ if (scripts) {
+ // Note: We need to split the '-f' and the file path to separate
+ // lines; otherwise the linking fails.
+ scripts.forEach(function(scr) {
+ escapableLinkerFlags.push("-f", scr.filePath);
+ });
+ }
+ }
+
+ if (libraryDependencies)
+ args = args.concat(libraryDependencies.map(function(dep) { return "-l" + dep.filePath }));
+
+ var escapedLinkerFlags = escapeLinkerFlags(product, escapableLinkerFlags);
+ if (escapedLinkerFlags)
+ Array.prototype.push.apply(args, escapedLinkerFlags);
+
+ return args;
+}
+
+function archiverFlags(project, product, input, outputs) {
+ var args = [];
+ args.push(outputs.staticlibrary[0].filePath);
+ if (inputs.obj)
+ args = args.concat(inputs.obj.map(function(obj) { return obj.filePath }));
+ return args;
+}
+
+function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var args = compilerFlags(project, product, input, output, explicitlyDependsOn);
+ var compilerPath = input.cpp.compilerPath;
+ var cmd = new Command(compilerPath, args)
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ return [cmd];
+}
+
+function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var args = assemblerFlags(project, product, input, output, explicitlyDependsOn);
+ var assemblerPath = input.cpp.assemblerPath;
+ var cmd = new Command(assemblerPath, args)
+ cmd.description = "assembling " + input.fileName;
+ cmd.highlight = "compiler";
+ return [cmd];
+}
+
+function prepareLinker(project, product, inputs, outputs, input, output) {
+ var primaryOutput = outputs.application[0];
+ var args = linkerFlags(project, product, input, outputs);
+ var linkerPath = effectiveLinkerPath(product);
+ var cmd = new Command(linkerPath, args)
+ cmd.description = "linking " + primaryOutput.fileName;
+ cmd.highlight = "linker";
+ return [cmd];
+}
+
+function prepareArchiver(project, product, inputs, outputs, input, output) {
+ var args = archiverFlags(project, product, input, outputs);
+ var archiverPath = product.cpp.archiverPath;
+ var cmd = new Command(archiverPath, args)
+ cmd.description = "linking " + output.fileName;
+ cmd.highlight = "linker";
+ return [cmd];
+}
diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs
new file mode 100644
index 000000000..a0d795b40
--- /dev/null
+++ b/share/qbs/modules/cpp/sdcc.qbs
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.PathTools
+import qbs.Probes
+import qbs.Utilities
+import "sdcc.js" as SDCC
+
+CppModule {
+ condition: qbs.toolchain && qbs.toolchain.contains("sdcc")
+
+ Probes.BinaryProbe {
+ id: compilerPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["sdcc"]
+ }
+
+ Probes.SdccProbe {
+ id: sdccProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ preferredArchitecture: qbs.architecture
+ }
+
+ qbs.architecture: sdccProbe.found ? sdccProbe.architecture : original
+
+ compilerVersionMajor: sdccProbe.versionMajor
+ compilerVersionMinor: sdccProbe.versionMinor
+ compilerVersionPatch: sdccProbe.versionPatch
+ endianness: sdccProbe.endianness
+
+ compilerDefinesByLanguage: sdccProbe.compilerDefinesByLanguage
+ compilerIncludePaths: sdccProbe.includePaths
+
+ property string toolchainInstallPath: compilerPathProbe.found
+ ? compilerPathProbe.path : undefined
+
+ property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
+
+ property bool generateMapFile: true
+ PropertyOptions {
+ name: "generateMapFile"
+ description: "produce a linker list file (enabled by default)"
+ }
+
+ /* Work-around for QtCreator which expects these properties to exist. */
+ property string cCompilerName: compilerName
+ property string cxxCompilerName: compilerName
+
+ property string linkerMode: "automatic"
+
+ compilerName: "sdcc" + compilerExtension
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+
+ assemblerName: {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "sdas8051" + compilerExtension;
+ }
+ }
+ assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
+
+ linkerName: {
+ switch (qbs.architecture) {
+ case "mcs51":
+ return "sdld" + compilerExtension;
+ }
+ }
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ property string archiverName: "sdcclib" + compilerExtension
+ property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
+
+ runtimeLibrary: "static"
+
+ staticLibrarySuffix: ".lib"
+ executableSuffix: ".ihx"
+
+ property string objectSuffix: ".rel"
+
+ imageFormat: "ihx"
+
+ enableExceptions: false
+ enableRtti: false
+
+ Rule {
+ id: assembler
+ inputs: ["asm"]
+
+ Artifact {
+ fileTags: ["obj"]
+ filePath: Utilities.getHash(input.baseDir) + "/"
+ + input.fileName + input.cpp.objectSuffix
+ }
+
+ prepare: SDCC.prepareAssembler.apply(SDCC, arguments);
+ }
+
+ FileTagger {
+ condition: qbs.architecture === "arm";
+ patterns: "*.s"
+ fileTags: ["asm"]
+ }
+
+ FileTagger {
+ condition: qbs.architecture === "mcs51";
+ patterns: ["*.s51", "*.asm"]
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ id: compiler
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+
+ Artifact {
+ fileTags: ["obj"]
+ filePath: Utilities.getHash(input.baseDir) + "/"
+ + input.fileName + input.cpp.objectSuffix
+ }
+
+ prepare: SDCC.prepareCompiler.apply(SDCC, arguments);
+ }
+
+ Rule {
+ id: applicationLinker
+ multiplex: true
+ inputs: ["obj", "linkerscript"]
+ inputsFromDependencies: ["staticlibrary"]
+
+ outputFileTags: {
+ var tags = ["application"];
+ if (product.moduleProperty("cpp", "generateMapFile"))
+ tags.push("map_file");
+ return tags;
+ }
+ outputArtifacts: {
+ var app = {
+ fileTags: ["application"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ PathTools.applicationFilePath(product))
+ };
+ var artifacts = [app];
+ if (product.cpp.generateMapFile) {
+ artifacts.push({
+ fileTags: ["map_file"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ product.targetName + ".map")
+ });
+ }
+ return artifacts;
+ }
+
+ prepare:SDCC.prepareLinker.apply(SDCC, arguments);
+ }
+
+ Rule {
+ id: staticLibraryLinker
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary"]
+
+ Artifact {
+ fileTags: ["staticlibrary"]
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ PathTools.staticLibraryFilePath(product))
+ }
+
+ prepare: SDCC.prepareArchiver.apply(SDCC, arguments);
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-clang-cl.qbs b/share/qbs/modules/cpp/windows-clang-cl.qbs
new file mode 100644
index 000000000..1b2833060
--- /dev/null
+++ b/share/qbs/modules/cpp/windows-clang-cl.qbs
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Ivan Komissarov (abbapoh@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
+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')
+ priority: 100
+
+ Probes.BinaryProbe {
+ id: clangPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["clang-cl"]
+ }
+
+ Probes.ClangClProbe {
+ id: clangClProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ vcvarsallFilePath: vcvarsallPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ architecture: qbs.architecture
+ }
+
+ compilerVersionMajor: clangClProbe.versionMajor
+ compilerVersionMinor: clangClProbe.versionMinor
+ compilerVersionPatch: clangClProbe.versionPatch
+ compilerIncludePaths: clangClProbe.includePaths
+ compilerDefinesByLanguage: clangClProbe.compilerDefinesByLanguage
+
+ toolchainInstallPath: clangPathProbe.found ? clangPathProbe.path
+ : undefined
+ buildEnv: clangClProbe.buildEnv
+
+ property string vcvarsallPath
+
+ compilerName: "clang-cl.exe"
+ linkerName: "lld-link.exe"
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ validateFunc: {
+ return function() {
+ if (_skipAllChecks)
+ return;
+ var validator = new ModUtils.PropertyValidator("cpp");
+ validator.setRequiredProperty("vcvarsallPath", vcvarsallPath);
+ validator.validate();
+ base();
+ }
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
new file mode 100644
index 000000000..d36daa99f
--- /dev/null
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -0,0 +1,372 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.File
+import qbs.FileInfo
+import qbs.ModUtils
+import qbs.PathTools
+import qbs.Probes
+import qbs.Utilities
+import qbs.WindowsUtils
+import 'msvc.js' as MSVC
+
+CppModule {
+ condition: false
+
+ windowsApiCharacterSet: "unicode"
+ platformDefines: {
+ var defines = base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
+ .concat("WIN32");
+ var def = WindowsUtils.winapiFamilyDefine(windowsApiFamily);
+ if (def)
+ defines.push("WINAPI_FAMILY=WINAPI_FAMILY_" + def);
+ (windowsApiAdditionalPartitions || []).map(function (name) {
+ defines.push("WINAPI_PARTITION_" + WindowsUtils.winapiPartitionDefine(name) + "=1");
+ });
+ return defines;
+ }
+ platformCommonCompilerFlags: {
+ var flags = base;
+ if (compilerVersionMajor >= 18) // 2013
+ flags.push("/FS");
+ return flags;
+ }
+ warningLevel: "default"
+ compilerName: "cl.exe"
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+ assemblerName: {
+ switch (qbs.architecture) {
+ case "armv7":
+ return "armasm.exe";
+ case "arm64":
+ return "armasm64.exe";
+ case "ia64":
+ return "ias.exe";
+ case "x86":
+ return "ml.exe";
+ case "x86_64":
+ return "ml64.exe";
+ }
+ }
+
+ linkerName: "link.exe"
+ runtimeLibrary: "dynamic"
+ separateDebugInformation: true
+
+ property bool generateManifestFile: true
+ property string toolchainInstallPath
+
+ architecture: qbs.architecture
+ endianness: "little"
+ staticLibrarySuffix: ".lib"
+ dynamicLibrarySuffix: ".dll"
+ executableSuffix: ".exe"
+ debugInfoSuffix: ".pdb"
+ imageFormat: "pe"
+ Properties {
+ condition: product.multiplexByQbsProperties.contains("buildVariants")
+ && qbs.buildVariants && qbs.buildVariants.length > 1
+ && qbs.buildVariant !== "release"
+ && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
+ variantSuffix: "d"
+ }
+
+ property var buildEnv
+
+ setupBuildEnvironment: {
+ for (var key in product.cpp.buildEnv) {
+ var v = new ModUtils.EnvironmentVariable(key, ';');
+ v.prepend(product.cpp.buildEnv[key]);
+ v.set();
+ }
+ }
+
+ 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);
+ }
+ }
+
+ Rule {
+ condition: useCxxPrecompiledHeader
+ 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);
+ }
+ }
+
+ Rule {
+ name: "compiler"
+ 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);
+ }
+ }
+
+ FileTagger {
+ patterns: ["*.manifest"]
+ fileTags: ["native.pe.manifest"]
+ }
+
+ Rule {
+ name: "applicationLinker"
+ multiplex: true
+ inputs: ['obj', 'native.pe.manifest']
+ inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
+
+ outputFileTags: ["application", "debuginfo_app"]
+ outputArtifacts: {
+ var app = {
+ fileTags: ["application"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ PathTools.applicationFilePath(product))
+ };
+ var artifacts = [app];
+ if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
+ artifacts.push({
+ fileTags: ["debuginfo_app"],
+ filePath: app.filePath.substr(0, app.filePath.length - 4)
+ + product.cpp.debugInfoSuffix
+ });
+ }
+ return artifacts;
+ }
+
+ prepare: {
+ return MSVC.prepareLinker.apply(MSVC, arguments);
+ }
+ }
+
+ Rule {
+ name: "dynamicLibraryLinker"
+ multiplex: true
+ inputs: ['obj', 'native.pe.manifest']
+ inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"]
+
+ outputFileTags: ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"]
+ outputArtifacts: {
+ var artifacts = [
+ {
+ fileTags: ["dynamiclibrary"],
+ filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product)
+ },
+ {
+ fileTags: ["dynamiclibrary_import"],
+ filePath: product.destinationDirectory + "/" + PathTools.importLibraryFilePath(product),
+ alwaysUpdated: false
+ }
+ ];
+ if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
+ var lib = artifacts[0];
+ artifacts.push({
+ fileTags: ["debuginfo_dll"],
+ filePath: lib.filePath.substr(0, lib.filePath.length - 4)
+ + product.cpp.debugInfoSuffix
+ });
+ }
+ return artifacts;
+ }
+
+ prepare: {
+ return MSVC.prepareLinker.apply(MSVC, arguments);
+ }
+ }
+
+ Rule {
+ name: "libtool"
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: ["staticlibrary", "debuginfo_cl"]
+ outputArtifacts: {
+ var artifacts = [
+ {
+ fileTags: ["staticlibrary"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.staticLibraryFilePath(product))
+ }
+ ];
+ if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
+ artifacts.push({
+ fileTags: ["debuginfo_cl"],
+ filePath: product.targetName + ".cl" + product.cpp.debugInfoSuffix
+ });
+ }
+ return artifacts;
+ }
+ prepare: {
+ var args = ['/nologo']
+ var lib = outputs["staticlibrary"][0];
+ var nativeOutputFileName = FileInfo.toWindowsSeparators(lib.filePath)
+ args.push('/OUT:' + nativeOutputFileName)
+ for (var i in inputs.obj) {
+ var fileName = FileInfo.toWindowsSeparators(inputs.obj[i].filePath)
+ args.push(fileName)
+ }
+ var cmd = new Command("lib.exe", args);
+ cmd.description = 'creating ' + lib.fileName;
+ cmd.highlight = 'linker';
+ cmd.jobPool = "linker";
+ cmd.workingDirectory = FileInfo.path(lib.filePath)
+ cmd.responseFileUsagePrefix = '@';
+ return cmd;
+ }
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+
+ Artifact {
+ filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
+ fileTags: ["obj"]
+ }
+
+ prepare: {
+ var platformDefines = input.cpp.platformDefines;
+ var defines = input.cpp.defines;
+ var includePaths = input.cpp.includePaths;
+ var systemIncludePaths = input.cpp.systemIncludePaths;
+ var args = [];
+ var i;
+ var hasNoLogo = product.cpp.compilerVersionMajor >= 16; // 2010
+ if (hasNoLogo)
+ args.push("/nologo");
+
+ for (i in platformDefines) {
+ args.push('/d');
+ args.push(platformDefines[i]);
+ }
+ for (i in defines) {
+ args.push('/d');
+ args.push(defines[i]);
+ }
+ for (i in includePaths) {
+ args.push('/i');
+ args.push(includePaths[i]);
+ }
+ for (i in systemIncludePaths) {
+ args.push('/i');
+ args.push(systemIncludePaths[i]);
+ }
+
+ args = args.concat(['/fo', output.filePath, input.filePath]);
+ var cmd = new Command('rc', args);
+ cmd.description = 'compiling ' + input.fileName;
+ cmd.highlight = 'compiler';
+ cmd.jobPool = "compiler";
+
+ if (!hasNoLogo) {
+ // Remove the first two lines of stdout. That's the logo.
+ cmd.stdoutFilterFunction = function(output) {
+ var idx = 0;
+ for (var i = 0; i < 3; ++i)
+ idx = output.indexOf('\n', idx + 1);
+ return output.substr(idx + 1);
+ }
+ }
+
+ return cmd;
+ }
+ }
+
+ FileTagger {
+ patterns: "*.asm"
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ inputs: ["asm"]
+ Artifact {
+ filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj"
+ fileTags: ["obj"]
+ }
+ prepare: {
+ var args = ["/nologo", "/c",
+ "/Fo" + FileInfo.toWindowsSeparators(output.filePath),
+ FileInfo.toWindowsSeparators(input.filePath)];
+ if (product.cpp.debugInformation)
+ args.push("/Zi");
+ args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'),
+ ModUtils.moduleProperty(input, 'flags', 'asm'));
+ var cmd = new Command(product.cpp.assemblerPath, args);
+ cmd.description = "assembling " + input.fileName;
+ cmd.jobPool = "assembler";
+ cmd.inputFileName = input.fileName;
+ cmd.stdoutFilterFunction = function(output) {
+ var lines = output.split("\r\n").filter(function (s) {
+ return !s.endsWith(inputFileName); });
+ return lines.join("\r\n");
+ };
+ return cmd;
+ }
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs
index 8dd6dd2c0..59032d28a 100644
--- a/share/qbs/modules/cpp/windows-msvc.qbs
+++ b/share/qbs/modules/cpp/windows-msvc.qbs
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com)
** Contact: http://www.qt.io/licensing
**
** This file is part of Qbs.
@@ -28,19 +29,14 @@
**
****************************************************************************/
-import qbs.File
-import qbs.FileInfo
-import qbs.ModUtils
-import qbs.PathTools
import qbs.Probes
-import qbs.Utilities
-import qbs.WindowsUtils
-import 'msvc.js' as MSVC
+import "windows-msvc-base.qbs" as MsvcBaseModule
-CppModule {
+MsvcBaseModule {
condition: qbs.hostOS.contains('windows') &&
qbs.targetOS.contains('windows') &&
qbs.toolchain && qbs.toolchain.contains('msvc')
+ priority: 50
Probes.BinaryProbe {
id: compilerPathProbe
@@ -62,335 +58,9 @@ CppModule {
compilerVersionMinor: msvcProbe.versionMinor
compilerVersionPatch: msvcProbe.versionPatch
compilerIncludePaths: msvcProbe.includePaths
-
- windowsApiCharacterSet: "unicode"
- platformDefines: {
- var defines = base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
- .concat("WIN32");
- var def = WindowsUtils.winapiFamilyDefine(windowsApiFamily);
- if (def)
- defines.push("WINAPI_FAMILY=WINAPI_FAMILY_" + def);
- (windowsApiAdditionalPartitions || []).map(function (name) {
- defines.push("WINAPI_PARTITION_" + WindowsUtils.winapiPartitionDefine(name) + "=1");
- });
- return defines;
- }
- platformCommonCompilerFlags: {
- var flags = base;
- if (compilerVersionMajor >= 18) // 2013
- flags.push("/FS");
- return flags;
- }
compilerDefinesByLanguage: msvcProbe.compilerDefinesByLanguage
- warningLevel: "default"
- compilerName: "cl.exe"
- compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: {
- switch (qbs.architecture) {
- case "armv7":
- return "armasm.exe";
- case "arm64":
- return "armasm64.exe";
- case "ia64":
- return "ias.exe";
- case "x86":
- return "ml.exe";
- case "x86_64":
- return "ml64.exe";
- }
- }
-
- linkerName: "link.exe"
- runtimeLibrary: "dynamic"
- separateDebugInformation: true
-
- property bool generateManifestFile: true
- property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path
- : undefined
- architecture: qbs.architecture
- endianness: "little"
- staticLibrarySuffix: ".lib"
- dynamicLibrarySuffix: ".dll"
- executableSuffix: ".exe"
- debugInfoSuffix: ".pdb"
- imageFormat: "pe"
- Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
- && qbs.buildVariants && qbs.buildVariants.length > 1
- && qbs.buildVariant !== "release"
- && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
- variantSuffix: "d"
- }
-
- property var buildEnv: msvcProbe.buildEnv
-
- setupBuildEnvironment: {
- for (var key in product.cpp.buildEnv) {
- var v = new ModUtils.EnvironmentVariable(key, ';');
- v.prepend(product.cpp.buildEnv[key]);
- v.set();
- }
- }
-
- 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);
- }
- }
-
- Rule {
- condition: useCxxPrecompiledHeader
- 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);
- }
- }
-
- Rule {
- name: "compiler"
- 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);
- }
- }
-
- FileTagger {
- patterns: ["*.manifest"]
- fileTags: ["native.pe.manifest"]
- }
-
- Rule {
- name: "applicationLinker"
- multiplex: true
- inputs: ['obj', 'native.pe.manifest']
- inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
-
- outputFileTags: ["application", "debuginfo_app"]
- outputArtifacts: {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var artifacts = [app];
- if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
- artifacts.push({
- fileTags: ["debuginfo_app"],
- filePath: app.filePath.substr(0, app.filePath.length - 4)
- + product.cpp.debugInfoSuffix
- });
- }
- return artifacts;
- }
- prepare: {
- return MSVC.prepareLinker.apply(MSVC, arguments);
- }
- }
-
- Rule {
- name: "dynamicLibraryLinker"
- multiplex: true
- inputs: ['obj', 'native.pe.manifest']
- inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"]
-
- outputFileTags: ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"]
- outputArtifacts: {
- var artifacts = [
- {
- fileTags: ["dynamiclibrary"],
- filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product)
- },
- {
- fileTags: ["dynamiclibrary_import"],
- filePath: product.destinationDirectory + "/" + PathTools.importLibraryFilePath(product),
- alwaysUpdated: false
- }
- ];
- if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
- var lib = artifacts[0];
- artifacts.push({
- fileTags: ["debuginfo_dll"],
- filePath: lib.filePath.substr(0, lib.filePath.length - 4)
- + product.cpp.debugInfoSuffix
- });
- }
- return artifacts;
- }
-
- prepare: {
- return MSVC.prepareLinker.apply(MSVC, arguments);
- }
- }
-
- Rule {
- name: "libtool"
- multiplex: true
- inputs: ["obj"]
- inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
- outputFileTags: ["staticlibrary", "debuginfo_cl"]
- outputArtifacts: {
- var artifacts = [
- {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
- }
- ];
- if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
- artifacts.push({
- fileTags: ["debuginfo_cl"],
- filePath: product.targetName + ".cl" + product.cpp.debugInfoSuffix
- });
- }
- return artifacts;
- }
- prepare: {
- var args = ['/nologo']
- var lib = outputs["staticlibrary"][0];
- var nativeOutputFileName = FileInfo.toWindowsSeparators(lib.filePath)
- args.push('/OUT:' + nativeOutputFileName)
- for (var i in inputs.obj) {
- var fileName = FileInfo.toWindowsSeparators(inputs.obj[i].filePath)
- args.push(fileName)
- }
- var cmd = new Command("lib.exe", args);
- cmd.description = 'creating ' + lib.fileName;
- cmd.highlight = 'linker';
- cmd.jobPool = "linker";
- cmd.workingDirectory = FileInfo.path(lib.filePath)
- cmd.responseFileUsagePrefix = '@';
- return cmd;
- }
- }
-
- FileTagger {
- patterns: ["*.rc"]
- fileTags: ["rc"]
- }
-
- Rule {
- inputs: ["rc"]
- auxiliaryInputs: ["hpp"]
-
- Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
- fileTags: ["obj"]
- }
-
- prepare: {
- var platformDefines = input.cpp.platformDefines;
- var defines = input.cpp.defines;
- var includePaths = input.cpp.includePaths;
- var systemIncludePaths = input.cpp.systemIncludePaths;
- var args = [];
- var i;
- var hasNoLogo = product.cpp.compilerVersionMajor >= 16; // 2010
- if (hasNoLogo)
- args.push("/nologo");
-
- for (i in platformDefines) {
- args.push('/d');
- args.push(platformDefines[i]);
- }
- for (i in defines) {
- args.push('/d');
- args.push(defines[i]);
- }
- for (i in includePaths) {
- args.push('/i');
- args.push(includePaths[i]);
- }
- for (i in systemIncludePaths) {
- args.push('/i');
- args.push(systemIncludePaths[i]);
- }
-
- args = args.concat(['/fo', output.filePath, input.filePath]);
- var cmd = new Command('rc', args);
- cmd.description = 'compiling ' + input.fileName;
- cmd.highlight = 'compiler';
- cmd.jobPool = "compiler";
-
- if (!hasNoLogo) {
- // Remove the first two lines of stdout. That's the logo.
- cmd.stdoutFilterFunction = function(output) {
- var idx = 0;
- for (var i = 0; i < 3; ++i)
- idx = output.indexOf('\n', idx + 1);
- return output.substr(idx + 1);
- }
- }
-
- return cmd;
- }
- }
-
- FileTagger {
- patterns: "*.asm"
- fileTags: ["asm"]
- }
-
- Rule {
- inputs: ["asm"]
- Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj"
- fileTags: ["obj"]
- }
- prepare: {
- var args = ["/nologo", "/c",
- "/Fo" + FileInfo.toWindowsSeparators(output.filePath),
- FileInfo.toWindowsSeparators(input.filePath)];
- if (product.cpp.debugInformation)
- args.push("/Zi");
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'),
- ModUtils.moduleProperty(input, 'flags', 'asm'));
- var cmd = new Command(product.cpp.assemblerPath, args);
- cmd.description = "assembling " + input.fileName;
- cmd.jobPool = "assembler";
- cmd.inputFileName = input.fileName;
- cmd.stdoutFilterFunction = function(output) {
- var lines = output.split("\r\n").filter(function (s) {
- return !s.endsWith(inputFileName); });
- return lines.join("\r\n");
- };
- return cmd;
- }
- }
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path
+ : undefined
+ buildEnv: msvcProbe.buildEnv
}
diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
index 5cb3257d4..2b6e94e83 100644
--- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
+++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
@@ -28,12 +28,14 @@ ProtobufBase {
prepare: HelperFunctions.doPrepare(input.protobuf.cpp, product, input, outputs, "cpp")
}
- validate: {
- baseValidate();
- if (!HelperFunctions.checkPath(includePath))
- throw "Can't find cpp protobuf include files. Please set the includePath property.";
- if (!HelperFunctions.checkPath(libraryPath))
- throw "Can't find cpp protobuf library. Please set the libraryPath property.";
+ validateFunc: {
+ return function() {
+ base();
+ if (!HelperFunctions.checkPath(includePath))
+ throw "Can't find cpp protobuf include files. Please set the includePath property.";
+ if (!HelperFunctions.checkPath(libraryPath))
+ throw "Can't find cpp protobuf library. Please set the libraryPath property.";
+ }
}
Probes.IncludeProbe {
diff --git a/share/qbs/modules/protobuf/objc/protobufobjc.qbs b/share/qbs/modules/protobuf/objc/protobufobjc.qbs
index c252d9949..e2c4b5260 100644
--- a/share/qbs/modules/protobuf/objc/protobufobjc.qbs
+++ b/share/qbs/modules/protobuf/objc/protobufobjc.qbs
@@ -43,13 +43,15 @@ ProtobufBase {
prepare: HelperFunctions.doPrepare(input.protobuf.objc, product, input, outputs, "objc")
}
- validate: {
- baseValidate();
- if (!HelperFunctions.checkPath(frameworkPath)) {
- if (!HelperFunctions.checkPath(includePath))
- throw "Can't find objective-c protobuf include files. Please set the includePath or frameworkPath property.";
- if (!HelperFunctions.checkPath(libraryPath))
- throw "Can't find objective-c protobuf library. Please set the libraryPath or frameworkPath property.";
+ validateFunc: {
+ return function() {
+ base();
+ if (!HelperFunctions.checkPath(frameworkPath)) {
+ if (!HelperFunctions.checkPath(includePath))
+ throw "Can't find objective-c protobuf include files. Please set the includePath or frameworkPath property.";
+ if (!HelperFunctions.checkPath(libraryPath))
+ throw "Can't find objective-c protobuf library. Please set the libraryPath or frameworkPath property.";
+ }
}
}
diff --git a/share/qbs/modules/protobuf/protobufbase.qbs b/share/qbs/modules/protobuf/protobufbase.qbs
index 1c2e68800..0ac6c1949 100644
--- a/share/qbs/modules/protobuf/protobufbase.qbs
+++ b/share/qbs/modules/protobuf/protobufbase.qbs
@@ -9,9 +9,8 @@ Module {
property pathList importPaths: []
property string outputDir: product.buildDirectory + "/protobuf"
- readonly property string protobufRoot: FileInfo.path(FileInfo.path(protocBinary))
- readonly property var baseValidate: {
+ property var validateFunc: {
return function() {
if (!File.exists(protocBinary))
throw "Can't find protoc binary. Please set the protocBinary property or make sure it is found in PATH";
@@ -27,4 +26,8 @@ Module {
id: protocProbe
names: ["protoc"]
}
+
+ validate: {
+ validateFunc();
+ }
}