diff options
Diffstat (limited to 'share/qbs/modules')
-rw-r--r-- | share/qbs/modules/Android/ndk/ndk.qbs | 97 | ||||
-rw-r--r-- | share/qbs/modules/Android/ndk/utils.js | 28 | ||||
-rw-r--r-- | share/qbs/modules/Android/sdk/sdk.qbs | 14 | ||||
-rw-r--r-- | share/qbs/modules/cpp/CppModule.qbs | 72 | ||||
-rw-r--r-- | share/qbs/modules/cpp/GenericGCC.qbs | 3 | ||||
-rw-r--r-- | share/qbs/modules/cpp/android-gcc.qbs | 135 | ||||
-rw-r--r-- | share/qbs/modules/cpp/iar.js | 59 | ||||
-rw-r--r-- | share/qbs/modules/cpp/iar.qbs | 4 | ||||
-rw-r--r-- | share/qbs/modules/cpp/keil.js | 38 | ||||
-rw-r--r-- | share/qbs/modules/cpp/keil.qbs | 4 | ||||
-rw-r--r-- | share/qbs/modules/cpp/msvc.js | 28 | ||||
-rw-r--r-- | share/qbs/modules/cpp/sdcc.js | 380 | ||||
-rw-r--r-- | share/qbs/modules/cpp/sdcc.qbs | 205 | ||||
-rw-r--r-- | share/qbs/modules/cpp/windows-clang-cl.qbs | 84 | ||||
-rw-r--r-- | share/qbs/modules/cpp/windows-msvc-base.qbs | 372 | ||||
-rw-r--r-- | share/qbs/modules/cpp/windows-msvc.qbs | 344 | ||||
-rw-r--r-- | share/qbs/modules/protobuf/cpp/protobufcpp.qbs | 14 | ||||
-rw-r--r-- | share/qbs/modules/protobuf/objc/protobufobjc.qbs | 16 | ||||
-rw-r--r-- | share/qbs/modules/protobuf/protobufbase.qbs | 7 |
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(); + } } |