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.qbs6
-rw-r--r--share/qbs/modules/Android/ndk/utils.js37
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs251
-rw-r--r--share/qbs/modules/Android/sdk/utils.js96
-rw-r--r--share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs1
-rw-r--r--share/qbs/modules/Exporter/qbs/qbsexporter.qbs1
-rw-r--r--share/qbs/modules/archiver/archiver.qbs3
-rw-r--r--share/qbs/modules/autotest/autotest.qbs5
-rw-r--r--share/qbs/modules/bundle/BundleModule.qbs6
-rw-r--r--share/qbs/modules/cli/CLIModule.qbs1
-rw-r--r--share/qbs/modules/cli/mono.qbs3
-rw-r--r--share/qbs/modules/cli/windows-dotnet.qbs1
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs3
-rw-r--r--share/qbs/modules/cpp/DarwinGCC.qbs9
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs48
-rw-r--r--share/qbs/modules/cpp/LinuxGCC.qbs1
-rw-r--r--share/qbs/modules/cpp/UnixGCC.qbs1
-rw-r--r--share/qbs/modules/cpp/android-gcc.qbs92
-rw-r--r--share/qbs/modules/cpp/freebsd-gcc.qbs1
-rw-r--r--share/qbs/modules/cpp/gcc.js53
-rw-r--r--share/qbs/modules/cpp/ios-gcc.qbs1
-rw-r--r--share/qbs/modules/cpp/macos-gcc.qbs1
-rw-r--r--share/qbs/modules/cpp/msvc.js35
-rw-r--r--share/qbs/modules/cpp/qnx-qcc.qbs1
-rw-r--r--share/qbs/modules/cpp/tvos-gcc.qbs2
-rw-r--r--share/qbs/modules/cpp/watchos-gcc.qbs2
-rw-r--r--share/qbs/modules/cpp/windows-mingw.qbs1
-rw-r--r--share/qbs/modules/cpp/windows-msvc.qbs25
-rw-r--r--share/qbs/modules/cpufeatures/cpufeatures.qbs2
-rw-r--r--share/qbs/modules/dmg/DMGModule.qbs3
-rw-r--r--share/qbs/modules/ib/IBModule.qbs3
-rw-r--r--share/qbs/modules/ico/IcoModule.qbs1
-rw-r--r--share/qbs/modules/innosetup/InnoSetupModule.qbs1
-rw-r--r--share/qbs/modules/java/JavaModule.qbs15
-rw-r--r--share/qbs/modules/lex_yacc/lexyacc.qbs1
-rw-r--r--share/qbs/modules/nodejs/NodeJS.qbs5
-rw-r--r--share/qbs/modules/nsis/NSISModule.qbs1
-rw-r--r--share/qbs/modules/protobuf/cpp/protobufcpp.qbs48
-rw-r--r--share/qbs/modules/protobuf/objc/protobufobjc.qbs70
-rw-r--r--share/qbs/modules/protobuf/protobuf.js111
-rw-r--r--share/qbs/modules/protobuf/protobufbase.qbs30
-rw-r--r--share/qbs/modules/qbs/common.qbs28
-rw-r--r--share/qbs/modules/qnx/qnx.qbs3
-rw-r--r--share/qbs/modules/texttemplate/texttemplate.qbs64
-rw-r--r--share/qbs/modules/typescript/TypeScriptModule.qbs1
-rw-r--r--share/qbs/modules/vcs/vcs-module.qbs1
-rw-r--r--share/qbs/modules/wix/WiXModule.qbs1
-rw-r--r--share/qbs/modules/xcode/xcode.qbs1
48 files changed, 756 insertions, 321 deletions
diff --git a/share/qbs/modules/Android/ndk/ndk.qbs b/share/qbs/modules/Android/ndk/ndk.qbs
index 226423d61..94211ea39 100644
--- a/share/qbs/modules/Android/ndk/ndk.qbs
+++ b/share/qbs/modules/Android/ndk/ndk.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
@@ -146,8 +145,6 @@ Module {
return toolchainVersion;
}
- property string gdbserverFileName: "gdbserver"
-
property string armMode: abi && abi.startsWith("armeabi")
? (qbs.buildVariant === "debug" ? "arm" : "thumb")
: undefined;
@@ -168,7 +165,8 @@ Module {
+ "ANDROID_NDK_ROOT environment variable to a valid "
+ "Android NDK location.");
}
-
+ if (product.aggregate && !product.multiplexConfigurationId)
+ return;
var validator = new ModUtils.PropertyValidator("Android.ndk");
validator.setRequiredProperty("abi", abi);
validator.setRequiredProperty("appStl", appStl);
diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js
index 7d1f7d6d0..a2e342897 100644
--- a/share/qbs/modules/Android/ndk/utils.js
+++ b/share/qbs/modules/Android/ndk/utils.js
@@ -63,25 +63,13 @@ function androidAbi(arch) {
function commonCompilerFlags(toolchain, buildVariant, abi, armMode) {
var flags = ["-ffunction-sections", "-funwind-tables",
- "-Wa,--noexecstack", "-Werror=format-security"];
+ "-Wa,--noexecstack", "-Werror=format-security", "-fstack-protector-strong"];
- if (buildVariant === "debug")
- flags.push("-fno-omit-frame-pointer", "-fno-strict-aliasing");
- if (buildVariant === "release")
- flags.push("-fomit-frame-pointer");
-
- if (abi === "arm64-v8a") {
- flags.push("-fpic", "-fstack-protector")
- if (!toolchain.contains("clang"))
- flags.push("-finline-limit=300", "-funswitch-loops");
- if (buildVariant === "release")
- flags.push("-fstrict-aliasing");
- }
+ if (abi === "arm64-v8a")
+ flags.push("-fpic");
if (abi === "armeabi" || abi === "armeabi-v7a") {
- flags.push("-fpic", "-fstack-protector");
- if (!toolchain.contains("clang"))
- flags.push("-finline-limit=64");
+ flags.push("-fpic");
if (abi === "armeabi")
flags.push("-mtune=xscale", "-msoft-float");
@@ -90,29 +78,16 @@ function commonCompilerFlags(toolchain, buildVariant, abi, armMode) {
flags.push("-mfpu=vfpv3-d16");
flags.push("-mfloat-abi=softfp");
}
-
- if (buildVariant === "release")
- flags.push("-fno-strict-aliasing");
}
if (abi === "mips" || abi === "mips64") {
flags.push("-fpic", "-finline-functions", "-fmessage-length=0",
"-fno-inline-functions-called-once", "-fgcse-after-reload",
"-frerun-cse-after-loop", "-frename-registers");
- if (buildVariant === "release") {
- flags.push("-fno-strict-aliasing");
- if (!toolchain.contains("clang"))
- flags.push("-funswitch-loops", "-finline-limit=300");
- }
}
- if (abi === "x86" || abi === "x86_64") {
- flags.push("-fstack-protector");
- if (!toolchain.contains("clang"))
- flags.push("-funswitch-loops", "-finline-limit=300");
- if (buildVariant === "release")
- flags.push("-fstrict-aliasing");
- }
+ if ((abi === "x86" || abi === "x86_64") && toolchain.contains("clang"))
+ flags.push("-fPIC");
if (armMode)
flags.push("-m" + armMode);
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index 84cee56e9..79ec9ad81 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.Environment
import qbs.File
import qbs.FileInfo
@@ -36,6 +35,7 @@ import qbs.ModUtils
import qbs.Probes
import qbs.TextFile
import qbs.Utilities
+import qbs.Xml
import "utils.js" as SdkUtils
Module {
@@ -60,6 +60,58 @@ Module {
property int buildToolsVersionPatch: buildToolsVersionParts[2]
property string platform: sdkProbe.platform
+ // Product-specific properties and files
+ property string packageName: product.name
+ property string apkBaseName: packageName
+ property bool automaticSources: true
+ property bool legacyLayout: false
+ property string sourceSetDir: legacyLayout
+ ? product.sourceDirectory
+ : FileInfo.joinPaths(product.sourceDirectory, "src/main")
+ property string resourcesDir: FileInfo.joinPaths(sourceSetDir, "res")
+ property string assetsDir: FileInfo.joinPaths(sourceSetDir, "assets")
+ property string sourcesDir: FileInfo.joinPaths(sourceSetDir, legacyLayout ? "src" : "java")
+ property string manifestFile: defaultManifestFile
+ readonly property string defaultManifestFile: FileInfo.joinPaths(sourceSetDir,
+ "AndroidManifest.xml")
+
+ property bool _enableRules: !product.multiplexConfigurationId && !!packageName
+
+ Group {
+ name: "java sources"
+ condition: Android.sdk.automaticSources
+ prefix: Android.sdk.sourcesDir + '/'
+ files: "**/*.java"
+ }
+
+ Group {
+ name: "android resources"
+ condition: Android.sdk.automaticSources
+ fileTags: ["android.resources"]
+ prefix: Android.sdk.resourcesDir + '/'
+ files: "**/*"
+ }
+
+ Group {
+ name: "android assets"
+ condition: Android.sdk.automaticSources
+ fileTags: ["android.assets"]
+ prefix: Android.sdk.assetsDir + '/'
+ files: "**/*"
+ }
+
+ Group {
+ name: "manifest"
+ condition: Android.sdk.automaticSources
+ fileTags: ["android.manifest"]
+ files: Android.sdk.manifestFile
+ && Android.sdk.manifestFile !== Android.sdk.defaultManifestFile
+ ? [Android.sdk.manifestFile]
+ : (File.exists(Android.sdk.defaultManifestFile)
+ ? [Android.sdk.defaultManifestFile] : [])
+ }
+
+
// Internal properties.
property int platformVersion: {
if (platform) {
@@ -84,9 +136,11 @@ Module {
property path zipalignFilePath: FileInfo.joinPaths(buildToolsDir, "zipalign")
property path androidJarFilePath: FileInfo.joinPaths(sdkDir, "platforms", platform,
"android.jar")
+ property path frameworkAidlFilePath: FileInfo.joinPaths(sdkDir, "platforms", platform,
+ "framework.aidl")
property path generatedJavaFilesBaseDir: FileInfo.joinPaths(product.buildDirectory, "gen")
property path generatedJavaFilesDir: FileInfo.joinPaths(generatedJavaFilesBaseDir,
- (product.packageName || "").split('.').join('/'))
+ (packageName || "").split('.').join('/'))
property string apkContentsDir: FileInfo.joinPaths(product.buildDirectory, "bin")
property string debugKeyStorePath: FileInfo.joinPaths(
Environment.getEnv(qbs.hostOS.contains("windows")
@@ -94,11 +148,15 @@ Module {
".android", "debug.keystore")
property bool useApksigner: buildToolsVersion && Utilities.versionCompare(
buildToolsVersion, "24.0.3") >= 0
+ property stringList aidlSearchPaths
- Depends { name: "java" }
- java.languageVersion: platformJavaVersion
- java.runtimeVersion: platformJavaVersion
- java.bootClassPaths: androidJarFilePath
+ Depends { name: "java"; condition: _enableRules }
+ Properties {
+ condition: _enableRules
+ java.languageVersion: platformJavaVersion
+ java.runtimeVersion: platformJavaVersion
+ java.bootClassPaths: androidJarFilePath
+ }
validate: {
if (!sdkDir) {
@@ -156,6 +214,7 @@ Module {
}
Rule {
+ condition: _enableRules
inputs: ["android.aidl"]
Artifact {
filePath: FileInfo.joinPaths(Utilities.getHash(input.filePath),
@@ -164,16 +223,51 @@ Module {
}
prepare: {
- var aidl = ModUtils.moduleProperty(product, "aidlFilePath");
- cmd = new Command(aidl, [input.filePath, output.filePath]);
+ var aidl = product.Android.sdk.aidlFilePath;
+ var args = ["-p" + product.Android.sdk.frameworkAidlFilePath];
+ var aidlSearchPaths = input.Android.sdk.aidlSearchPaths;
+ for (var i = 0; i < (aidlSearchPaths ? aidlSearchPaths.length : 0); ++i)
+ args.push("-I" + aidlSearchPaths[i]);
+ args.push(input.filePath, output.filePath);
+ cmd = new Command(aidl, args);
cmd.description = "Processing " + input.fileName;
return [cmd];
}
}
+ property bool customManifestProcessing: false
+ Group {
+ condition: !Android.sdk.customManifestProcessing
+ fileTagsFilter: "android.manifest_processed"
+ fileTags: "android.manifest_final"
+ }
Rule {
+ condition: _enableRules
+ inputs: "android.manifest"
+ Artifact {
+ filePath: FileInfo.joinPaths("processed_manifest", input.fileName)
+ fileTags: "android.manifest_processed"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "Ensuring correct package name in Android manifest file";
+ cmd.sourceCode = function() {
+ var manifestData = new Xml.DomDocument();
+ manifestData.load(input.filePath);
+ var rootElem = manifestData.documentElement();
+ if (!rootElem || !rootElem.isElement() || rootElem.tagName() != "manifest")
+ throw "No manifest tag found in '" + input.filePath + "'.";
+ rootElem.setAttribute("package", product.Android.sdk.packageName);
+ manifestData.save(output.filePath, 4);
+ }
+ return cmd;
+ }
+ }
+
+ Rule {
+ condition: _enableRules
multiplex: true
- inputs: ["android.resources", "android.assets", "android.manifest"]
+ inputs: ["android.resources", "android.assets", "android.manifest_final"]
outputFileTags: ["java.java"]
outputArtifacts: {
@@ -181,9 +275,8 @@ Module {
var resources = inputs["android.resources"];
if (resources && resources.length) {
artifacts.push({
- filePath: FileInfo.joinPaths(
- ModUtils.moduleProperty(product, "generatedJavaFilesDir"),
- "R.java"),
+ filePath: FileInfo.joinPaths(product.Android.sdk.generatedJavaFilesDir,
+ "R.java"),
fileTags: ["java.java"]
});
}
@@ -195,11 +288,11 @@ Module {
}
Rule {
+ condition: _enableRules
multiplex: true
- condition: !!product.packageName
Artifact {
- filePath: FileInfo.joinPaths(ModUtils.moduleProperty(product, "generatedJavaFilesDir"),
+ filePath: FileInfo.joinPaths(product.Android.sdk.generatedJavaFilesDir,
"BuildConfig.java")
fileTags: ["java.java"]
}
@@ -208,10 +301,9 @@ Module {
var cmd = new JavaScriptCommand();
cmd.description = "Generating BuildConfig.java";
cmd.sourceCode = function() {
- var debugValue = product.moduleProperty("qbs", "buildVariant") === "debug"
- ? "true" : "false";
+ var debugValue = product.qbs.buildVariant === "debug" ? "true" : "false";
var ofile = new TextFile(output.filePath, TextFile.WriteOnly);
- ofile.writeLine("package " + product.packageName + ";")
+ ofile.writeLine("package " + product.Android.sdk.packageName + ";")
ofile.writeLine("public final class BuildConfig {");
ofile.writeLine(" public final static boolean DEBUG = " + debugValue + ";");
ofile.writeLine("}");
@@ -222,6 +314,7 @@ Module {
}
Rule {
+ condition: _enableRules
multiplex: true
inputs: ["java.class"]
inputsFromDependencies: ["java.jar"]
@@ -233,71 +326,97 @@ Module {
}
Rule {
+ condition: _enableRules
+ property stringList inputTags: "android.nativelibrary"
+ inputsFromDependencies: inputTags
+ inputs: product.aggregate ? [] : inputTags
+ Artifact {
+ filePath: FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib",
+ input.Android.ndk.abi, input.fileName)
+ fileTags: "android.nativelibrary_deployed"
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "copying " + input.fileName + " for packaging";
+ cmd.sourceCode = function() { File.copy(input.filePath, output.filePath); };
+ return cmd;
+ }
+ }
+
+ Rule {
+ condition: _enableRules
multiplex: true
- inputsFromDependencies: [
- "android.gdbserver-info", "android.stl-info", "android.nativelibrary"
- ]
- outputFileTags: ["android.gdbserver", "android.stl", "android.nativelibrary-deployed"]
+ property stringList inputTags: "android.gdbserver"
+ inputsFromDependencies: inputTags
+ inputs: product.aggregate ? [] : inputTags
+ outputFileTags: "android.gdbserver_deployed"
outputArtifacts: {
- var libArtifacts = [];
- if (inputs["android.nativelibrary"]) {
- for (var i = 0; i < inputs["android.nativelibrary"].length; ++i) {
- var inp = inputs["android.nativelibrary"][i];
- var destDir = FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib",
- inp.moduleProperty("Android.ndk", "abi"));
- libArtifacts.push({
- filePath: FileInfo.joinPaths(destDir, inp.fileName),
- fileTags: ["android.nativelibrary-deployed"]
- });
- }
+ var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs,
+ "gdbserver");
+ var outputs = [];
+ for (i = 0; i < deploymentData.outputFilePaths.length; ++i) {
+ outputs.push({filePath: deploymentData.outputFilePaths[i],
+ fileTags: "android.gdbserver_deployed"});
}
- var gdbServerArtifacts = SdkUtils.outputArtifactsFromInfoFiles(inputs,
- product, "android.gdbserver-info", "android.gdbserver");
- var stlArtifacts = SdkUtils.outputArtifactsFromInfoFiles(inputs, product,
- "android.stl-info", "android.deployed-stl");
- return libArtifacts.concat(gdbServerArtifacts).concat(stlArtifacts);
+ return outputs;
}
prepare: {
- var cmd = new JavaScriptCommand();
- cmd.description = "Pre-packaging native binaries";
+ var cmd = new JavaScriptCommand;
+ cmd.description = "deploying gdbserver binaries";
cmd.sourceCode = function() {
- if (inputs["android.nativelibrary"]) {
- for (var i = 0; i < inputs["android.nativelibrary"].length; ++i) {
- for (var j = 0; j < outputs["android.nativelibrary-deployed"].length; ++j) {
- var inp = inputs["android.nativelibrary"][i];
- var outp = outputs["android.nativelibrary-deployed"][j];
- var inpAbi = inp.moduleProperty("Android.ndk", "abi");
- var outpAbi = FileInfo.fileName(outp.baseDir);
- if (inp.fileName === outp.fileName && inpAbi === outpAbi) {
- File.copy(inp.filePath, outp.filePath);
- break;
- }
- }
- }
+ var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs,
+ "gdbserver");
+ for (var i = 0; i < deploymentData.uniqueInputs.length; ++i) {
+ File.copy(deploymentData.uniqueInputs[i].filePath,
+ deploymentData.outputFilePaths[i]);
}
- var pathsSpecs = SdkUtils.sourceAndTargetFilePathsFromInfoFiles(inputs, product,
- "android.gdbserver-info");
- for (i = 0; i < pathsSpecs.sourcePaths.length; ++i)
- File.copy(pathsSpecs.sourcePaths[i], pathsSpecs.targetPaths[i]);
- pathsSpecs = SdkUtils.sourceAndTargetFilePathsFromInfoFiles(inputs, product,
- "android.stl-info");
- for (i = 0; i < pathsSpecs.sourcePaths.length; ++i)
- File.copy(pathsSpecs.sourcePaths[i], pathsSpecs.targetPaths[i]);
};
- return [cmd];
+ return cmd;
+ }
+ }
+
+ Rule {
+ condition: _enableRules
+ multiplex: true
+ property stringList inputTags: "android.stl"
+ inputsFromDependencies: inputTags
+ inputs: product.aggregate ? [] : inputTags
+ outputFileTags: "android.stl_deployed"
+ outputArtifacts: {
+ var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs, "stl");
+ var outputs = [];
+ for (i = 0; i < deploymentData.outputFilePaths.length; ++i) {
+ outputs.push({filePath: deploymentData.outputFilePaths[i],
+ fileTags: "android.stl_deployed"});
+ }
+ return outputs;
+ }
+ prepare: {
+ var cmds = [];
+ var deploymentData = SdkUtils.gdbserverOrStlDeploymentData(product, inputs);
+ for (var i = 0; i < deploymentData.uniqueInputs.length; ++i) {
+ var input = deploymentData.uniqueInputs[i];
+ var stripArgs = ["--strip-unneeded", "-o", deploymentData.outputFilePaths[i],
+ input.filePath];
+ var cmd = new Command(input.cpp.stripPath, stripArgs);
+ cmd.description = "deploying " + input.fileName;
+ cmds.push(cmd);
+ }
+ return cmds;
}
}
Rule {
+ condition: _enableRules
multiplex: true
inputs: [
- "android.resources", "android.assets", "android.manifest",
- "android.dex", "android.gdbserver", "android.stl",
- "android.nativelibrary-deployed", "android.keystore"
+ "android.resources", "android.assets", "android.manifest_final",
+ "android.dex", "android.gdbserver_deployed", "android.stl_deployed",
+ "android.nativelibrary_deployed", "android.keystore"
]
Artifact {
- filePath: product.targetName + ".apk"
- fileTags: ["android.apk"]
+ filePath: product.Android.sdk.apkBaseName + ".apk"
+ fileTags: "android.apk"
}
prepare: SdkUtils.prepareAaptPackage.apply(SdkUtils, arguments)
}
diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js
index 6d9fff65c..6a89fd5f2 100644
--- a/share/qbs/modules/Android/sdk/utils.js
+++ b/share/qbs/modules/Android/sdk/utils.js
@@ -34,34 +34,6 @@ var Process = require("qbs.Process");
var TextFile = require("qbs.TextFile");
var Utilities = require("qbs.Utilities");
-function sourceAndTargetFilePathsFromInfoFiles(inputs, product, inputTag)
-{
- var sourceFilePaths = [];
- var targetFilePaths = [];
- var inputsLength = inputs[inputTag] ? inputs[inputTag].length : 0;
- for (var i = 0; i < inputsLength; ++i) {
- var infoFile = new TextFile(inputs[inputTag][i].filePath, TextFile.ReadOnly);
- var sourceFilePath = infoFile.readLine();
- var targetFilePath = FileInfo.joinPaths(product.Android.sdk.apkContentsDir,
- infoFile.readLine());
- if (!targetFilePaths.contains(targetFilePath)) {
- sourceFilePaths.push(sourceFilePath);
- targetFilePaths.push(targetFilePath);
- }
- infoFile.close();
- }
- return { sourcePaths: sourceFilePaths, targetPaths: targetFilePaths };
-}
-
-function outputArtifactsFromInfoFiles(inputs, product, inputTag, outputTag)
-{
- var pathSpecs = sourceAndTargetFilePathsFromInfoFiles(inputs, product, inputTag)
- var artifacts = [];
- for (i = 0; i < pathSpecs.targetPaths.length; ++i)
- artifacts.push({filePath: pathSpecs.targetPaths[i], fileTags: [outputTag]});
- return artifacts;
-}
-
function availableSdkPlatforms(sdkDir) {
var re = /^android-([0-9]+)$/;
var platforms = File.directoryEntries(FileInfo.joinPaths(sdkDir, "platforms"),
@@ -129,19 +101,56 @@ function prepareDex(project, product, inputs, outputs, input, output, explicitly
return [cmd];
}
+function findParentDir(filePath, parentDirName)
+{
+ var lastDir;
+ var currentDir = FileInfo.path(filePath);
+ while (lastDir !== currentDir) {
+ if (FileInfo.fileName(currentDir) === parentDirName)
+ return currentDir;
+ lastDir = currentDir;
+ currentDir = FileInfo.path(currentDir);
+ }
+}
+
function commonAaptPackageArgs(project, product, inputs, outputs, input, output,
explicitlyDependsOn) {
- var manifestFilePath = inputs["android.manifest"][0].filePath;
+ var manifestFilePath = inputs["android.manifest_final"][0].filePath;
var args = ["package", "-f",
"-M", manifestFilePath,
"-I", product.Android.sdk.androidJarFilePath];
var resources = inputs["android.resources"];
- if (resources && resources.length)
- args.push("-S", product.resourcesDir);
+ var resourceDirs = [];
+ if (resources) {
+ for (var i = 0; i < resources.length; ++i) {
+ var resDir = findParentDir(resources[i].filePath, "res");
+ if (!resDir) {
+ throw "File '" + resources[i].filePath + "' is tagged as an Android resource, "
+ + "but is not located under a directory called 'res'.";
+ }
+ if (!resourceDirs.contains(resDir))
+ resourceDirs.push(resDir);
+ }
+ }
+ for (i = 0; i < resourceDirs.length; ++i)
+ args.push("-S", resourceDirs[i]);
+ var assets = inputs["android.assets"];
+ var assetDirs = [];
+ if (assets) {
+ for (i = 0; i < assets.length; ++i) {
+ var assetDir = findParentDir(assets[i].filePath, "assets");
+ if (!assetDir) {
+ throw "File '" + assets[i].filePath + "' is tagged as an Android asset, "
+ + "but is not located under a directory called 'assets'.";
+ }
+ if (!assetDirs.contains(assetDir))
+ assetDirs.push(assetDir);
+ }
+ }
+ for (i = 0; i < assetDirs.length; ++i)
+ args.push("-A", assetDirs[i]);
if (product.qbs.buildVariant === "debug")
args.push("--debug-mode");
- if (File.exists(product.assetsDir))
- args.push("-A", product.assetsDir);
return args;
}
@@ -210,3 +219,24 @@ function createDebugKeyStoreCommandString(keytoolFilePath, keystoreFilePath) {
"CN=Android Debug,O=Android,C=US"];
return Process.shellQuote(keytoolFilePath, args);
}
+
+function gdbserverOrStlDeploymentData(product, inputs, type)
+{
+ var data = { uniqueInputs: [], outputFilePaths: []};
+ var uniqueFilePaths = [];
+ var theInputs = inputs[type === "gdbserver" ? "android.gdbserver" : "android.stl"];
+ if (!theInputs)
+ return data;
+ for (var i = 0; i < theInputs.length; ++i) {
+ var currentInput = theInputs[i];
+ if (uniqueFilePaths.contains(currentInput.filePath))
+ continue;
+ uniqueFilePaths.push(currentInput.filePath);
+ data.uniqueInputs.push(currentInput);
+ var outputFileName = type === "gdbserver" ? "libgdbserver.so" : currentInput.fileName;
+ data.outputFilePaths.push(FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib",
+ currentInput.Android.ndk.abi,
+ outputFileName));
+ }
+ return data;
+}
diff --git a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs
index aecad6126..8cc55f885 100644
--- a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs
+++ b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.FileInfo
import qbs.TextFile
diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs
index 351edfefe..861483ef0 100644
--- a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs
+++ b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.FileInfo
import qbs.TextFile
diff --git a/share/qbs/modules/archiver/archiver.qbs b/share/qbs/modules/archiver/archiver.qbs
index c70b57bf4..6ae53dd37 100644
--- a/share/qbs/modules/archiver/archiver.qbs
+++ b/share/qbs/modules/archiver/archiver.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.Environment
import qbs.File
import qbs.FileInfo
@@ -52,7 +51,7 @@ Module {
Probes.BinaryProbe {
id: sevenZipProbe
names: ["7z"]
- platformPaths: {
+ platformSearchPaths: {
var paths = base;
if (qbs.hostOS.contains("windows")) {
var env32 = Environment.getEnv("PROGRAMFILES(X86)");
diff --git a/share/qbs/modules/autotest/autotest.qbs b/share/qbs/modules/autotest/autotest.qbs
new file mode 100644
index 000000000..ba280169e
--- /dev/null
+++ b/share/qbs/modules/autotest/autotest.qbs
@@ -0,0 +1,5 @@
+Module {
+ property stringList arguments
+ property bool allowFailure: false
+ property string workingDir
+}
diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs
index 7752ee65e..ec0062347 100644
--- a/share/qbs/modules/bundle/BundleModule.qbs
+++ b/share/qbs/modules/bundle/BundleModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.BundleTools
import qbs.DarwinTools
import qbs.Environment
@@ -264,7 +263,8 @@ Module {
Rule {
condition: qbs.targetOS.contains("darwin")
multiplex: true
- inputs: ["qbs", "infoplist", "partial_infoplist"]
+ requiresInputs: false // TODO: The resources property should probably be a tag instead.
+ inputs: ["infoplist", "partial_infoplist"]
outputFileTags: ["bundle.input", "aggregate_infoplist"]
outputArtifacts: {
@@ -518,7 +518,7 @@ Module {
"bundle.symlink.headers", "bundle.symlink.private-headers",
"bundle.symlink.resources", "bundle.symlink.executable",
"bundle.symlink.version", "bundle.hpp", "bundle.resource",
- "bundle.provisioningprofile"]
+ "bundle.provisioningprofile", "bundle.content.copied", "bundle.application-executable"]
outputArtifacts: {
var i, artifacts = [];
if (ModUtils.moduleProperty(product, "isBundle")) {
diff --git a/share/qbs/modules/cli/CLIModule.qbs b/share/qbs/modules/cli/CLIModule.qbs
index 866580029..d0ca120ef 100644
--- a/share/qbs/modules/cli/CLIModule.qbs
+++ b/share/qbs/modules/cli/CLIModule.qbs
@@ -1,5 +1,4 @@
// base for Common Language Infrastructure modules
-import qbs
import qbs.FileInfo
import qbs.ModUtils
import "cli.js" as CLI
diff --git a/share/qbs/modules/cli/mono.qbs b/share/qbs/modules/cli/mono.qbs
index c679c4bf0..f04956a5e 100644
--- a/share/qbs/modules/cli/mono.qbs
+++ b/share/qbs/modules/cli/mono.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.File
import qbs.Probes
@@ -13,7 +12,7 @@ CLIModule {
Probes.PathProbe {
id: monoProbe
names: ["mono"]
- platformPaths: {
+ platformSearchPaths: {
var paths = [];
if (qbs.hostOS.contains("macos"))
paths.push("/Library/Frameworks/Mono.framework/Commands");
diff --git a/share/qbs/modules/cli/windows-dotnet.qbs b/share/qbs/modules/cli/windows-dotnet.qbs
index b1b29d7a9..6fde50b85 100644
--- a/share/qbs/modules/cli/windows-dotnet.qbs
+++ b/share/qbs/modules/cli/windows-dotnet.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.Utilities
CLIModule {
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index c26be036d..01b0f8af9 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -178,6 +178,7 @@ Module {
property string debugInfoSuffix: ""
property string debugInfoBundleSuffix: ""
property string variantSuffix: ""
+ property string dynamicLibraryImportSuffix: ".lib"
property bool createSymlinks: true
property stringList dynamicLibraries // list of names, will be linked with -lname
property stringList staticLibraries // list of static library files
@@ -353,7 +354,7 @@ Module {
property stringList targetDriverFlags
property stringList targetLinkerFlags
- property bool _skipAllChecks: false // Internal, for testing only.
+ property bool _skipAllChecks: false // Internal
property bool validateTargetTriple: true
diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs
index 16176b4eb..0bd294fb4 100644
--- a/share/qbs/modules/cpp/DarwinGCC.qbs
+++ b/share/qbs/modules/cpp/DarwinGCC.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.DarwinTools
import qbs.File
import qbs.FileInfo
@@ -50,7 +49,7 @@ UnixGCC {
id: lipoProbe
condition: !_skipAllChecks
names: [lipoName]
- platformPaths: {
+ platformSearchPaths: {
var paths = (xcode.present && xcode.devicePlatformPath)
? [xcode.devicePlatformPath + "/Developer/usr/bin"]
: [];
@@ -211,7 +210,8 @@ UnixGCC {
inputsFromDependencies: ["application"]
multiplex: true
- outputFileTags: ["bundle.input", "application", "primary", "debuginfo_app"]
+ outputFileTags: ["bundle.input", "application", "primary", "debuginfo_app",
+ "debuginfo_bundle", "bundle.variant_symlink", "debuginfo_plist"]
outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "application", "app")
prepare: Darwin.prepareLipo.apply(Darwin, arguments)
@@ -235,7 +235,8 @@ UnixGCC {
multiplex: true
outputFileTags: ["bundle.input", "dynamiclibrary", "dynamiclibrary_symbols", "primary",
- "debuginfo_dll"]
+ "debuginfo_dll","debuginfo_bundle","bundle.variant_symlink",
+ "debuginfo_plist"]
outputArtifacts: Darwin.lipoOutputArtifacts(product, inputs, "dynamiclibrary", "dll")
prepare: Darwin.prepareLipo.apply(Darwin, arguments)
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index 4e68dc267..972555ed7 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
@@ -389,7 +388,7 @@ CppModule {
|| product.multiplexConfigurationId
Rule {
- id: dynamicLibraryLinker
+ name: "dynamicLibraryLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: {
@@ -400,11 +399,12 @@ CppModule {
}
return tags;
}
- inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"]
+ inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary", "dynamiclibrary_import"]
outputFileTags: [
"bundle.input",
- "dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll"
+ "dynamiclibrary", "dynamiclibrary_symlink", "dynamiclibrary_symbols", "debuginfo_dll",
+ "debuginfo_bundle","dynamiclibrary_import", "debuginfo_plist",
]
outputArtifacts: {
var artifacts = [{
@@ -416,7 +416,14 @@ CppModule {
+ PathTools.bundleExecutableFilePath(product)
}
}];
- if (!product.qbs.toolchain.contains("mingw")) {
+ if (product.qbs.toolchain.contains("mingw")) {
+ artifacts.push({
+ fileTags: ["dynamiclibrary_import"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.importLibraryFilePath(product)),
+ alwaysUpdated: false
+ });
+ } else {
// List of libfoo's public symbols for smart re-linking.
artifacts.push({
filePath: product.destinationDirectory + "/.sosymbols/"
@@ -451,11 +458,11 @@ CppModule {
}
Rule {
- id: staticLibraryLinker
+ name: "staticLibraryLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: ["obj", "linkerscript"]
- inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"]
+ inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
outputFileTags: ["bundle.input", "staticlibrary", "c_staticlibrary", "cpp_staticlibrary"]
outputArtifacts: {
@@ -487,13 +494,14 @@ CppModule {
var cmd = new Command(product.cpp.archiverPath, args);
cmd.description = 'creating ' + output.fileName;
cmd.highlight = 'linker'
+ cmd.jobPool = "linker";
cmd.responseFileUsagePrefix = '@';
return cmd;
}
}
Rule {
- id: loadableModuleLinker
+ name: "loadableModuleLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: {
@@ -504,9 +512,10 @@ CppModule {
}
return tags;
}
- inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"]
+ inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
- outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule"]
+ outputFileTags: ["bundle.input", "loadablemodule", "debuginfo_loadablemodule",
+ "debuginfo_bundle","debuginfo_plist"]
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
@@ -530,7 +539,7 @@ CppModule {
}
Rule {
- id: applicationLinker
+ name: "applicationLinker"
condition: product.cpp.shouldLink
multiplex: true
inputs: {
@@ -541,9 +550,10 @@ CppModule {
}
return tags;
}
- inputsFromDependencies: ["dynamiclibrary_symbols", "staticlibrary"]
+ inputsFromDependencies: ["dynamiclibrary_symbols", "dynamiclibrary_import", "staticlibrary"]
- outputFileTags: ["bundle.input", "application", "debuginfo_app"]
+ outputFileTags: ["bundle.input", "application", "debuginfo_app","debuginfo_bundle",
+ "debuginfo_plist"]
outputArtifacts: {
var app = {
filePath: FileInfo.joinPaths(product.destinationDirectory,
@@ -566,14 +576,18 @@ CppModule {
}
Rule {
- id: compiler
+ name: "compiler"
inputs: ["cpp", "c", "objcpp", "objc", "asm_cpp"]
auxiliaryInputs: ["hpp"]
explicitlyDependsOn: ["c_pch", "cpp_pch", "objc_pch", "objcpp_pch"]
- outputFileTags: ["obj", "c_obj", "cpp_obj"]
+ outputFileTags: ["obj", "c_obj", "cpp_obj", "intermediate_obj"]
outputArtifacts: {
- var tags = ["obj"];
+ var tags;
+ if (input.fileTags.contains("cpp_intermediate_object"))
+ tags = ["intermediate_obj"];
+ else
+ tags = ["obj"];
if (inputs.c || inputs.objc)
tags.push("c_obj");
if (inputs.cpp || inputs.objcpp)
@@ -591,7 +605,7 @@ CppModule {
}
Rule {
- id: assembler
+ name: "assembler"
inputs: ["asm"]
Artifact {
diff --git a/share/qbs/modules/cpp/LinuxGCC.qbs b/share/qbs/modules/cpp/LinuxGCC.qbs
index 6af648c40..14fb0a7e9 100644
--- a/share/qbs/modules/cpp/LinuxGCC.qbs
+++ b/share/qbs/modules/cpp/LinuxGCC.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.Process
UnixGCC {
diff --git a/share/qbs/modules/cpp/UnixGCC.qbs b/share/qbs/modules/cpp/UnixGCC.qbs
index ec26cffb6..e5b99cd98 100644
--- a/share/qbs/modules/cpp/UnixGCC.qbs
+++ b/share/qbs/modules/cpp/UnixGCC.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.File
GenericGCC {
diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs
index b5dc367ee..e20f1e198 100644
--- a/share/qbs/modules/cpp/android-gcc.qbs
+++ b/share/qbs/modules/cpp/android-gcc.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
@@ -90,9 +89,18 @@ LinuxGCC {
Group {
name: "Android STL"
- condition: product.cpp.sharedStlFilePath
+ condition: product.cpp.sharedStlFilePath && product.cpp.shouldLink
files: product.cpp.sharedStlFilePath ? [product.cpp.sharedStlFilePath] : []
- fileTags: ["android.unstripped-stl"]
+ fileTags: "android.stl"
+ }
+
+ Group {
+ name: "gdbserver"
+ condition: qbs.buildVariant !== "release" && product.cpp.shouldLink
+ files: FileInfo.joinPaths(Android.ndk.ndkDir, "prebuilt",
+ "android-" + NdkUtils.abiNameToDirName(Android.ndk.abi),
+ "gdbserver", "gdbserver")
+ fileTags: "android.gdbserver"
}
toolchainInstallPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains",
@@ -222,82 +230,24 @@ LinuxGCC {
endianness: "little"
Rule {
- inputs: ["android.unstripped-stl"]
+ condition: shouldLink
+ inputs: "dynamiclibrary"
Artifact {
- filePath: FileInfo.joinPaths("stripped-libs", input.fileName);
- fileTags: ["android.stripped-stl"]
+ filePath: FileInfo.joinPaths("stripped-libs", input.fileName)
+ fileTags: "android.nativelibrary"
}
prepare: {
- var args = ["--strip-unneeded", "-o", output.filePath, input.filePath];
- var cmd = new Command(product.cpp.stripPath, args);
- cmd.description = "stripping " + input.fileName;
- return [cmd];
+ var stripArgs = ["--strip-unneeded", "-o", output.filePath, input.filePath];
+ var stripCmd = new Command(product.cpp.stripPath, stripArgs);
+ stripCmd.description = "Stripping unneeded symbols from " + input.fileName;
+ return stripCmd;
}
}
- Rule {
- inputs: ["dynamiclibrary"]
- explicitlyDependsOn: ["android.stripped-stl"];
- outputFileTags: ["android.nativelibrary", "android.gdbserver-info", "android.stl-info"]
- outputArtifacts: {
- var artifacts = [{
- filePath: FileInfo.joinPaths("stripped-libs",
- inputs["dynamiclibrary"][0].fileName),
- fileTags: ["android.nativelibrary"]
- }];
- if (product.moduleProperty("qbs", "buildVariant") === "debug") {
- artifacts.push({
- filePath: "android.gdbserver-info.txt",
- fileTags: ["android.gdbserver-info"]
- });
- }
- if (explicitlyDependsOn["android.stripped-stl"])
- artifacts.push({filePath: "android.stl-info.txt", fileTags: ["android.stl-info"]});
- return artifacts;
- }
-
- prepare: {
- var copyCmd = new JavaScriptCommand();
- copyCmd.silent = true;
- copyCmd.sourceCode = function() {
- File.copy(inputs["dynamiclibrary"][0].filePath,
- outputs["android.nativelibrary"][0].filePath);
- var arch = product.moduleProperty("Android.ndk", "abi");
- var destDir = FileInfo.joinPaths("lib", arch);
- if (product.moduleProperty("qbs", "buildVariant") === "debug") {
- arch = NdkUtils.abiNameToDirName(arch);
- var srcPath = FileInfo.joinPaths(
- product.moduleProperty("Android.ndk", "ndkDir"),
- "prebuilt/android-" + arch, "gdbserver/gdbserver");
- var targetPath = FileInfo.joinPaths(destDir,
- product.moduleProperty("Android.ndk", "gdbserverFileName"));
- var infoFile = new TextFile(outputs["android.gdbserver-info"][0].filePath,
- TextFile.WriteOnly);
- infoFile.writeLine(srcPath);
- infoFile.writeLine(targetPath);
- infoFile.close();
- }
- var strippedStlList = explicitlyDependsOn["android.stripped-stl"];
- if (strippedStlList) {
- var srcPath = strippedStlList[0].filePath;
- var targetPath = FileInfo.joinPaths(destDir, FileInfo.fileName(srcPath));
- var infoFile = new TextFile(outputs["android.stl-info"][0].filePath,
- TextFile.WriteOnly);
- infoFile.writeLine(srcPath);
- infoFile.writeLine(targetPath);
- infoFile.close();
- }
- }
- var stripArgs = ["--strip-unneeded", outputs["android.nativelibrary"][0].filePath];
- var stripCmd = new Command(product.moduleProperty("cpp", "stripPath"), stripArgs);
- stripCmd.description = "Stripping unneeded symbols from "
- + outputs["android.nativelibrary"][0].fileName;
- return [copyCmd, stripCmd];
- }
- }
+ _skipAllChecks: !shouldLink
validate: {
- if (!_skipAllChecks)
+ if (_skipAllChecks)
return;
var baseValidator = new ModUtils.PropertyValidator("qbs");
baseValidator.addCustomValidator("architecture", targetArch, function (value) {
diff --git a/share/qbs/modules/cpp/freebsd-gcc.qbs b/share/qbs/modules/cpp/freebsd-gcc.qbs
index 724f242ff..b5a4b89f3 100644
--- a/share/qbs/modules/cpp/freebsd-gcc.qbs
+++ b/share/qbs/modules/cpp/freebsd-gcc.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import "freebsd.js" as FreeBSD
UnixGCC {
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 452d7a4d1..7e25fa402 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -78,6 +78,8 @@ function collectLibraryDependencies(product, isDarwin) {
var publicDeps = {};
var objects = [];
var objectByFilePath = {};
+ var tagForLinkingAgainstSharedLib = product.qbs.toolchain.contains("mingw")
+ ? "dynamiclibrary_import" : "dynamiclibrary";
function addObject(obj, addFunc) {
addFunc.call(objects, obj);
@@ -151,7 +153,7 @@ function collectLibraryDependencies(product, isDarwin) {
var isStaticLibrary = typeof dep.artifacts["staticlibrary"] !== "undefined";
var isDynamicLibrary = !isStaticLibrary
- && typeof dep.artifacts["dynamiclibrary"] !== "undefined";
+ && typeof dep.artifacts[tagForLinkingAgainstSharedLib] !== "undefined";
if (!isStaticLibrary && !isDynamicLibrary)
return;
@@ -173,10 +175,10 @@ function collectLibraryDependencies(product, isDarwin) {
}
} else if (isDynamicLibrary) {
if (!isBelowIndirectDynamicLib) {
- addArtifactFilePaths(dep, "dynamiclibrary", addPublicFilePath);
+ addArtifactFilePaths(dep, tagForLinkingAgainstSharedLib, addPublicFilePath);
publicDeps[dep.name] = true;
} else {
- addArtifactFilePaths(dep, "dynamiclibrary", addPrivateFilePath);
+ addArtifactFilePaths(dep, tagForLinkingAgainstSharedLib, addPrivateFilePath);
}
}
}
@@ -245,7 +247,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
return linkerFlags;
}
-function linkerFlags(project, product, inputs, output, linkerPath) {
+function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPath) {
var libraryPaths = product.cpp.libraryPaths;
var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
var isDarwin = product.qbs.targetOS.contains("darwin");
@@ -261,7 +263,7 @@ function linkerFlags(project, product, inputs, output, linkerPath) {
var escapableLinkerFlags = [];
- if (output.fileTags.contains("dynamiclibrary")) {
+ if (primaryOutput.fileTags.contains("dynamiclibrary")) {
if (isDarwin) {
args.push((function () {
var tags = ["c", "cpp", "objc", "objcpp", "asm_cpp"];
@@ -279,16 +281,18 @@ function linkerFlags(project, product, inputs, output, linkerPath) {
var internalVersion = product.cpp.internalVersion;
if (internalVersion && isNumericProductVersion(internalVersion))
args.push("-current_version", internalVersion);
- escapableLinkerFlags.push("-install_name", UnixUtils.soname(product, output.fileName));
+ escapableLinkerFlags.push("-install_name", UnixUtils.soname(product,
+ primaryOutput.fileName));
} else {
- escapableLinkerFlags.push("-soname=" + UnixUtils.soname(product, output.fileName));
+ escapableLinkerFlags.push("-soname=" + UnixUtils.soname(product,
+ primaryOutput.fileName));
}
}
- if (output.fileTags.contains("loadablemodule"))
+ if (primaryOutput.fileTags.contains("loadablemodule"))
args.push(isDarwin ? "-bundle" : "-shared");
- if (output.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) {
+ if (primaryOutput.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) {
if (isDarwin)
escapableLinkerFlags.push("-headerpad_max_install_names");
else
@@ -414,7 +418,7 @@ function linkerFlags(project, product, inputs, output, linkerPath) {
// Note: due to the QCC response files hack in prepareLinker(), at least one object file or
// library file must follow the output file path so that QCC has something to process before
// sending the rest of the arguments through the response file.
- args.push("-o", output.filePath);
+ args.push("-o", primaryOutput.filePath);
if (inputs.obj)
args = args.concat(inputs.obj.map(function (obj) { return obj.filePath }));
@@ -501,6 +505,10 @@ function linkerFlags(project, product, inputs, output, linkerPath) {
}));
}
+ var importLibs = outputs.dynamiclibrary_import;
+ if (importLibs)
+ escapableLinkerFlags.push("--out-implib", importLibs[0].filePath);
+
var escapedLinkerFlags = escapeLinkerFlags(product, inputs, escapableLinkerFlags);
Array.prototype.push.apply(escapedLinkerFlags, args);
var driverLinkerFlags = useCompilerDriver ? product.cpp.driverLinkerFlags : undefined;
@@ -976,6 +984,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output) {
var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
return cmd;
}
@@ -1035,7 +1044,25 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var args = compilerFlags(project, product, input, output, explicitlyDependsOn);
var wrapperArgsLength = 0;
var wrapperArgs = product.cpp.compilerWrapper;
+ var extraEnv;
if (wrapperArgs && wrapperArgs.length > 0) {
+
+ // distcc cannot deal with absolute compiler paths (QBS-1336).
+ for (var i = 0; i < wrapperArgs.length; ++i) {
+ if (FileInfo.baseName(wrapperArgs[i]) !== "distcc")
+ continue;
+ if (i === wrapperArgs.length - 1) {
+ if (FileInfo.isAbsolutePath(compilerPath)) {
+ extraEnv = ["PATH=" + FileInfo.path(compilerPath)];
+ compilerPath = FileInfo.fileName(compilerPath);
+ }
+ } else if (FileInfo.isAbsolutePath(wrapperArgs[i + 1])) {
+ extraEnv = ["PATH=" + FileInfo.path(FileInfo.path(wrapperArgs[i + 1]))];
+ wrapperArgs[i + 1] = FileInfo.fileName(wrapperArgs[i + 1]);
+ }
+ break;
+ }
+
wrapperArgsLength = wrapperArgs.length;
args.unshift(compilerPath);
compilerPath = wrapperArgs.shift();
@@ -1047,7 +1074,10 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
if (pchOutput)
cmd.description += ' (' + compilerInfo.tag + ')';
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
cmd.relevantEnvironmentVariables = compilerEnvVars(input, compilerInfo);
+ if (extraEnv)
+ cmd.environment = extraEnv;
cmd.responseFileArgumentIndex = wrapperArgsLength;
cmd.responseFileUsagePrefix = '@';
setResponseFileThreshold(cmd, product);
@@ -1240,7 +1270,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var linkerPath = effectiveLinkerPath(product, inputs)
- var args = linkerFlags(project, product, inputs, primaryOutput, linkerPath);
+ var args = linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPath);
var wrapperArgsLength = 0;
var wrapperArgs = product.cpp.linkerWrapper;
if (wrapperArgs && wrapperArgs.length > 0) {
@@ -1266,6 +1296,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
cmd = new Command(linkerPath, args);
cmd.description = 'linking ' + primaryOutput.fileName;
cmd.highlight = 'linker';
+ cmd.jobPool = "linker";
cmd.relevantEnvironmentVariables = linkerEnvVars(product, inputs);
cmd.responseFileArgumentIndex = responseFileArgumentIndex;
cmd.responseFileUsagePrefix = useQnxResponseFileHack ? "-Wl,@" : "@";
diff --git a/share/qbs/modules/cpp/ios-gcc.qbs b/share/qbs/modules/cpp/ios-gcc.qbs
index 408bc3aec..735766650 100644
--- a/share/qbs/modules/cpp/ios-gcc.qbs
+++ b/share/qbs/modules/cpp/ios-gcc.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.DarwinTools
import qbs.File
import qbs.FileInfo
diff --git a/share/qbs/modules/cpp/macos-gcc.qbs b/share/qbs/modules/cpp/macos-gcc.qbs
index e2c930c80..612b46ae8 100644
--- a/share/qbs/modules/cpp/macos-gcc.qbs
+++ b/share/qbs/modules/cpp/macos-gcc.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.ModUtils
import qbs.Utilities
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index d6df99dc2..1864c40e1 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -188,7 +188,8 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
if (product.cpp.debugInformation && product.cpp.separateDebugInformation)
args.push("/Fd" + product.targetName + ".cl" + product.cpp.debugInfoSuffix);
- var objOutput = outputs.obj ? outputs.obj[0] : undefined
+ var objectMap = outputs.obj || outputs.intermediate_obj
+ var objOutput = objectMap ? objectMap[0] : undefined
args.push('/Fo' + FileInfo.toWindowsSeparators(objOutput.filePath))
args.push(FileInfo.toWindowsSeparators(input.filePath))
@@ -246,6 +247,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
if (pchOutput)
cmd.description += ' (' + tag + ')';
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
cmd.workingDirectory = product.buildDirectory;
cmd.responseFileUsagePrefix = '@';
// cl.exe outputs the cpp file name. We filter that out.
@@ -261,8 +263,8 @@ function collectLibraryDependencies(product) {
var seen = {};
var result = [];
- function addFilePath(filePath, wholeArchive) {
- result.push({ filePath: filePath, wholeArchive: wholeArchive });
+ function addFilePath(filePath, wholeArchive, productName) {
+ result.push({ filePath: filePath, wholeArchive: wholeArchive, productName: productName });
}
function addArtifactFilePaths(dep, artifacts) {
@@ -270,8 +272,12 @@ function collectLibraryDependencies(product) {
return;
var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
var wholeArchive = dep.parameters.cpp && dep.parameters.cpp.linkWholeArchive;
- for (var i = 0; i < artifactFilePaths.length; ++i)
- addFilePath(artifactFilePaths[i], wholeArchive);
+ var artifactsAreImportLibs = artifacts.length > 0
+ && artifacts[0].fileTags.contains("dynamiclibrary_import");
+ for (var i = 0; i < artifactFilePaths.length; ++i) {
+ addFilePath(artifactFilePaths[i], wholeArchive,
+ artifactsAreImportLibs ? dep.name : undefined);
+ }
}
function addExternalLibs(obj) {
@@ -466,14 +472,31 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
args = wrapperArgs.concat(args);
}
var commands = [];
+ var warningCmd = new JavaScriptCommand();
+ warningCmd.silent = true;
+ warningCmd.libDeps = libDeps;
+ warningCmd.sourceCode = function() {
+ for (var i = 0; i < libDeps.length; ++i) {
+ if (!libDeps[i].productName || File.exists(libDeps[i].filePath))
+ continue;
+ console.warn("Import library '" + FileInfo.toNativeSeparators(libDeps[i].filePath)
+ + "' does not exist. This typically happens when a DLL does not "
+ + "export any symbols. Please make sure the '" + libDeps[i].productName
+ + "' library exports symbols, or, if you do not intend to actually "
+ + "link against it, specify \"cpp.link: false\" in the Depends item.");
+ }
+ };
+ commands.push(warningCmd);
var cmd = new Command(linkerPath, args)
cmd.description = 'linking ' + primaryOutput.fileName;
cmd.highlight = 'linker';
+ cmd.jobPool = "linker";
cmd.relevantEnvironmentVariables = ["LINK", "_LINK_", "LIB", "TMP"];
cmd.workingDirectory = FileInfo.path(primaryOutput.filePath)
cmd.responseFileUsagePrefix = '@';
cmd.stdoutFilterFunction = function(output) {
- return output.replace(/^(.*performing full link.*\r\n)? +Creating library.*\r\n$/, "");
+ res = output.replace(/^.*performing full link.*\s*/, "");
+ return res.replace(/^ *Creating library.*\r\n$/, "");
};
commands.push(cmd);
diff --git a/share/qbs/modules/cpp/qnx-qcc.qbs b/share/qbs/modules/cpp/qnx-qcc.qbs
index 28c9ce266..a39a6a998 100644
--- a/share/qbs/modules/cpp/qnx-qcc.qbs
+++ b/share/qbs/modules/cpp/qnx-qcc.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.FileInfo
UnixGCC {
diff --git a/share/qbs/modules/cpp/tvos-gcc.qbs b/share/qbs/modules/cpp/tvos-gcc.qbs
index ae4dd5c5b..19bc9b787 100644
--- a/share/qbs/modules/cpp/tvos-gcc.qbs
+++ b/share/qbs/modules/cpp/tvos-gcc.qbs
@@ -28,8 +28,6 @@
**
****************************************************************************/
-import qbs
-
DarwinGCC {
priority: 1
condition: qbs.targetOS.contains('tvos') &&
diff --git a/share/qbs/modules/cpp/watchos-gcc.qbs b/share/qbs/modules/cpp/watchos-gcc.qbs
index c8bd0a55d..46e4bf874 100644
--- a/share/qbs/modules/cpp/watchos-gcc.qbs
+++ b/share/qbs/modules/cpp/watchos-gcc.qbs
@@ -29,8 +29,6 @@
**
****************************************************************************/
-import qbs
-
DarwinGCC {
priority: 1
condition: qbs.targetOS.contains('watchos') &&
diff --git a/share/qbs/modules/cpp/windows-mingw.qbs b/share/qbs/modules/cpp/windows-mingw.qbs
index 3e3ba409d..27382742f 100644
--- a/share/qbs/modules/cpp/windows-mingw.qbs
+++ b/share/qbs/modules/cpp/windows-mingw.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.ModUtils
import qbs.TextFile
import qbs.Utilities
diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs
index 3164e08b5..8dd6dd2c0 100644
--- a/share/qbs/modules/cpp/windows-msvc.qbs
+++ b/share/qbs/modules/cpp/windows-msvc.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
@@ -114,7 +113,6 @@ CppModule {
dynamicLibrarySuffix: ".dll"
executableSuffix: ".exe"
debugInfoSuffix: ".pdb"
- property string dynamicLibraryImportSuffix: ".lib"
imageFormat: "pe"
Properties {
condition: product.multiplexByQbsProperties.contains("buildVariants")
@@ -170,14 +168,20 @@ CppModule {
}
Rule {
- id: compiler
+ name: "compiler"
inputs: ["cpp", "c"]
auxiliaryInputs: ["hpp"]
explicitlyDependsOn: ["c_pch", "cpp_pch"]
- Artifact {
- fileTags: ['obj']
- filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj"
+ 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: {
@@ -191,7 +195,7 @@ CppModule {
}
Rule {
- id: applicationLinker
+ name: "applicationLinker"
multiplex: true
inputs: ['obj', 'native.pe.manifest']
inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
@@ -221,7 +225,7 @@ CppModule {
}
Rule {
- id: dynamicLibraryLinker
+ name: "dynamicLibraryLinker"
multiplex: true
inputs: ['obj', 'native.pe.manifest']
inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"]
@@ -256,7 +260,7 @@ CppModule {
}
Rule {
- id: libtool
+ name: "libtool"
multiplex: true
inputs: ["obj"]
inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
@@ -289,6 +293,7 @@ CppModule {
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;
@@ -341,6 +346,7 @@ CppModule {
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.
@@ -377,6 +383,7 @@ CppModule {
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) {
diff --git a/share/qbs/modules/cpufeatures/cpufeatures.qbs b/share/qbs/modules/cpufeatures/cpufeatures.qbs
index a7ef95193..17e6b851e 100644
--- a/share/qbs/modules/cpufeatures/cpufeatures.qbs
+++ b/share/qbs/modules/cpufeatures/cpufeatures.qbs
@@ -1,5 +1,3 @@
-import qbs
-
Module {
property bool arm_neon
property bool arm_vfpv4
diff --git a/share/qbs/modules/dmg/DMGModule.qbs b/share/qbs/modules/dmg/DMGModule.qbs
index 09e31f696..c5d097a0b 100644
--- a/share/qbs/modules/dmg/DMGModule.qbs
+++ b/share/qbs/modules/dmg/DMGModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.DarwinTools
import qbs.File
import qbs.FileInfo
@@ -140,7 +139,7 @@ Module {
Rule {
multiplex: true
- inputs: ["qbs", "dmg.input", "dmg.license", "icns", "tiff"]
+ inputs: ["dmg.input", "dmg.license", "icns", "tiff"]
Artifact {
fileTags: ["dmg.dmg"]
diff --git a/share/qbs/modules/ib/IBModule.qbs b/share/qbs/modules/ib/IBModule.qbs
index 66d76aede..6af5e94e4 100644
--- a/share/qbs/modules/ib/IBModule.qbs
+++ b/share/qbs/modules/ib/IBModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.BundleTools
import qbs.DarwinTools
import qbs.File
@@ -175,7 +174,7 @@ Module {
inputs: ["nib", "storyboard"]
outputFileTags: {
- var tags = [];
+ var tags = ["partial_infoplist"];
for (var i = 0; i < inputs.length; ++i)
tags = tags.uniqueConcat(ModUtils.allFileTags(Ib.ibtoolFileTaggers(inputs[i])));
return tags;
diff --git a/share/qbs/modules/ico/IcoModule.qbs b/share/qbs/modules/ico/IcoModule.qbs
index 444fcd597..7157aab09 100644
--- a/share/qbs/modules/ico/IcoModule.qbs
+++ b/share/qbs/modules/ico/IcoModule.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
diff --git a/share/qbs/modules/innosetup/InnoSetupModule.qbs b/share/qbs/modules/innosetup/InnoSetupModule.qbs
index bc5b74460..1caf39dc8 100644
--- a/share/qbs/modules/innosetup/InnoSetupModule.qbs
+++ b/share/qbs/modules/innosetup/InnoSetupModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.FileInfo
import qbs.ModUtils
import qbs.Probes
diff --git a/share/qbs/modules/java/JavaModule.qbs b/share/qbs/modules/java/JavaModule.qbs
index 928684a4f..5191d6497 100644
--- a/share/qbs/modules/java/JavaModule.qbs
+++ b/share/qbs/modules/java/JavaModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.FileInfo
import qbs.ModUtils
import qbs.Probes
@@ -65,6 +64,8 @@ Module {
property string keytoolFilePath: FileInfo.joinPaths(jdkPath, "bin", keytoolName)
property string keytoolName: "keytool"
+ property bool _tagJniHeaders: true
+
property string jdkPath: jdk.path
version: [compilerVersionMajor, compilerVersionMinor, compilerVersionPatch].join(".")
@@ -233,9 +234,17 @@ Module {
inputsFromDependencies: ["java.jar"]
explicitlyDependsOn: ["java.class-internal"]
- outputFileTags: ["java.class", "hpp"] // Annotations can produce additional java source files. Ignored for now.
+ outputFileTags: ["java.class"].concat(_tagJniHeaders ? ["hpp"] : []) // Annotations can produce additional java source files. Ignored for now.
outputArtifacts: {
- return JavaUtils.outputArtifacts(product, inputs);
+ var artifacts = JavaUtils.outputArtifacts(product, inputs);
+ if (!product.java._tagJniHeaders) {
+ for (var i = 0; i < artifacts.length; ++i) {
+ var a = artifacts[i];
+ if (Array.isArray(a.fileTags))
+ a.fileTags = a.fileTags.filter(function(tag) { return tag != "hpp"; });
+ }
+ }
+ return artifacts;
}
prepare: {
var cmd = new Command(ModUtils.moduleProperty(product, "compilerFilePath"),
diff --git a/share/qbs/modules/lex_yacc/lexyacc.qbs b/share/qbs/modules/lex_yacc/lexyacc.qbs
index 20982f7aa..48af1d793 100644
--- a/share/qbs/modules/lex_yacc/lexyacc.qbs
+++ b/share/qbs/modules/lex_yacc/lexyacc.qbs
@@ -1,4 +1,3 @@
-import qbs
import "lexyacc.js" as HelperFunctions
Module {
diff --git a/share/qbs/modules/nodejs/NodeJS.qbs b/share/qbs/modules/nodejs/NodeJS.qbs
index b40ea2d9e..7fd992fdb 100644
--- a/share/qbs/modules/nodejs/NodeJS.qbs
+++ b/share/qbs/modules/nodejs/NodeJS.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.Environment
import qbs.File
import qbs.FileInfo
@@ -42,12 +41,12 @@ Module {
Probes.NodeJsProbe {
id: nodejs
- pathPrefixes: toolchainInstallPath ? [toolchainInstallPath] : []
+ searchPaths: toolchainInstallPath ? [toolchainInstallPath] : []
}
Probes.NpmProbe {
id: npm
- pathPrefixes: toolchainInstallPath ? [toolchainInstallPath] : []
+ searchPaths: toolchainInstallPath ? [toolchainInstallPath] : []
interpreterPath: FileInfo.path(nodejs.filePath)
}
diff --git a/share/qbs/modules/nsis/NSISModule.qbs b/share/qbs/modules/nsis/NSISModule.qbs
index ef1d5b0e1..e426aee56 100644
--- a/share/qbs/modules/nsis/NSISModule.qbs
+++ b/share/qbs/modules/nsis/NSISModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
new file mode 100644
index 000000000..5cb3257d4
--- /dev/null
+++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
@@ -0,0 +1,48 @@
+import qbs
+import qbs.File
+import qbs.FileInfo
+import qbs.Probes
+import "../protobufbase.qbs" as ProtobufBase
+import "../protobuf.js" as HelperFunctions
+
+ProtobufBase {
+ property string includePath: includeProbe.path
+ property string libraryPath: libraryProbe.path
+
+ Depends { name: "cpp" }
+
+ cpp.libraryPaths: [libraryPath]
+ cpp.dynamicLibraries: qbs.targetOS.contains("unix") ? ["protobuf", "pthread"] : ["protobuf"]
+ cpp.includePaths: [outputDir, includePath]
+
+ Rule {
+ inputs: ["protobuf.input"]
+ outputFileTags: ["hpp", "cpp"]
+ outputArtifacts: {
+ return [
+ HelperFunctions.cppArtifact(input.protobuf.cpp, product, input, "hpp", ".pb.h"),
+ HelperFunctions.cppArtifact(input.protobuf.cpp, product, input, "cpp", ".pb.cc")
+ ];
+ }
+
+ 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.";
+ }
+
+ Probes.IncludeProbe {
+ id: includeProbe
+ names: "google/protobuf/message.h"
+ }
+
+ Probes.LibraryProbe {
+ id: libraryProbe
+ names: "protobuf"
+ }
+}
diff --git a/share/qbs/modules/protobuf/objc/protobufobjc.qbs b/share/qbs/modules/protobuf/objc/protobufobjc.qbs
new file mode 100644
index 000000000..c252d9949
--- /dev/null
+++ b/share/qbs/modules/protobuf/objc/protobufobjc.qbs
@@ -0,0 +1,70 @@
+import qbs
+import qbs.File
+import qbs.FileInfo
+import qbs.Probes
+import "../protobufbase.qbs" as ProtobufBase
+import "../protobuf.js" as HelperFunctions
+
+ProtobufBase {
+ property string includePath: includeProbe.path
+ property string libraryPath: libraryProbe.path
+ property string frameworkPath: frameworkProbe.path
+
+ Depends { name: "cpp" }
+
+ // library build
+ Properties {
+ condition: !frameworkPath
+ cpp.includePaths: [outputDir, includePath]
+ cpp.libraryPaths: [libraryPath]
+ cpp.frameworks: ["Foundation"]
+ cpp.dynamicLibraries: ["ProtocolBuffers"]
+ }
+
+ // framework build
+ Properties {
+ condition: frameworkPath
+ cpp.includePaths: [outputDir]
+ cpp.frameworkPaths: [frameworkPath]
+ cpp.frameworks: ["Foundation", "Protobuf"]
+ cpp.defines: ["GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS"]
+ }
+
+ Rule {
+ inputs: ["protobuf.input"]
+ outputFileTags: ["hpp", "objc"]
+ outputArtifacts: {
+ return [
+ HelperFunctions.objcArtifact(input.protobuf.objc, product, input, "hpp", ".pbobjc.h"),
+ HelperFunctions.objcArtifact(input.protobuf.objc, product, input, "objc", ".pbobjc.m")
+ ];
+ }
+
+ 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.";
+ }
+ }
+
+ Probes.IncludeProbe {
+ id: includeProbe
+ names: "GPBMessage.h"
+ }
+
+ Probes.LibraryProbe {
+ id: libraryProbe
+ names: "ProtocolBuffers"
+ }
+
+ Probes.FrameworkProbe {
+ id: frameworkProbe
+ names: ["Protobuf"]
+ }
+}
diff --git a/share/qbs/modules/protobuf/protobuf.js b/share/qbs/modules/protobuf/protobuf.js
new file mode 100644
index 000000000..576a5ec07
--- /dev/null
+++ b/share/qbs/modules/protobuf/protobuf.js
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Ivan Komissarov
+** Contact: abbapoh@gmail.com
+**
+** 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 File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+
+var checkPath = function(path) {
+ return path && File.exists(path)
+};
+
+function toCamelCase(str){
+ return str.split('_').map(function(word, index) {
+ // If it is the first word make sure to lowercase all the chars.
+ if (index === 0) {
+ return word.toLowerCase();
+ }
+ // If it is not the first word only upper case the first char and lowercase the rest.
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+ }).join('');
+}
+
+function getOutputDir(module, product, input) {
+ var outputDir = module.outputDir;
+ var importPaths = module.importPaths;
+ if (importPaths.length !== 0) {
+ var canonicalInput = File.canonicalFilePath(FileInfo.path(input.filePath));
+ for (var i = 0; i < importPaths.length; ++i) {
+ path = File.canonicalFilePath(importPaths[i]);
+
+ if (canonicalInput.startsWith(path)) {
+ return outputDir + "/" + FileInfo.relativePath(path, canonicalInput);
+ }
+ }
+ }
+ return outputDir;
+}
+
+function cppArtifact(module, product, input, tag, suffix) {
+ var outputDir = getOutputDir(module, product, input);
+ return {
+ fileTags: [tag],
+ filePath: outputDir + "/" + FileInfo.baseName(input.fileName) + suffix,
+ cpp: {
+ includePaths: [].concat(input.cpp.includePaths, outputDir),
+ warningLevel: "none",
+ }
+ };
+}
+
+function objcArtifact(module, product, input, tag, suffix) {
+ var outputDir = getOutputDir(module, product, input);
+ return {
+ fileTags: [tag],
+ filePath: outputDir + "/" + toCamelCase(FileInfo.baseName(input.fileName)) + suffix,
+ cpp: {
+ includePaths: [].concat(input.cpp.includePaths, outputDir),
+ warningLevel: "none",
+ }
+ }
+}
+
+function doPrepare(module, product, input, outputs, lang)
+{
+ var outputDir = module.outputDir;
+ var args = [];
+
+ args.push("--" + lang + "_out", outputDir);
+
+ var importPaths = module.importPaths;
+ if (importPaths.length === 0)
+ importPaths = [FileInfo.path(input.filePath)];
+ importPaths.forEach(function(path) {
+ if (!FileInfo.isAbsolutePath(path))
+ path = FileInfo.joinPaths(product.sourceDirectory, path);
+ args.push("--proto_path", path);
+ });
+
+ args.push(input.filePath);
+
+ var cmd = new Command(module.protocBinary, args);
+ cmd.highlight = "codegen";
+ cmd.description = "generating " + lang + " files for " + input.fileName;
+ return [cmd];
+}
diff --git a/share/qbs/modules/protobuf/protobufbase.qbs b/share/qbs/modules/protobuf/protobufbase.qbs
new file mode 100644
index 000000000..1c2e68800
--- /dev/null
+++ b/share/qbs/modules/protobuf/protobufbase.qbs
@@ -0,0 +1,30 @@
+import qbs
+import qbs.File
+import qbs.FileInfo
+import qbs.Probes
+import "protobuf.js" as HelperFunctions
+
+Module {
+ property string protocBinary: protocProbe.filePath
+ property pathList importPaths: []
+
+ property string outputDir: product.buildDirectory + "/protobuf"
+ readonly property string protobufRoot: FileInfo.path(FileInfo.path(protocBinary))
+
+ readonly property var baseValidate: {
+ 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";
+ }
+ }
+
+ FileTagger {
+ patterns: ["*.proto"]
+ fileTags: ["protobuf.input"];
+ }
+
+ Probes.BinaryProbe {
+ id: protocProbe
+ names: ["protoc"]
+ }
+}
diff --git a/share/qbs/modules/qbs/common.qbs b/share/qbs/modules/qbs/common.qbs
index 86ce27c59..63bc29f8e 100644
--- a/share/qbs/modules/qbs/common.qbs
+++ b/share/qbs/modules/qbs/common.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs 1.0
import qbs.Environment
import qbs.FileInfo
import qbs.ModUtils
@@ -102,7 +101,7 @@ Module {
property path installSourceBase
property string installRoot: project.buildDirectory + "/install-root"
property string installDir
- property string installPrefix: ""
+ property string installPrefix: qbs.targetOS.contains("unix") ? "/usr/local" : ""
property path sysroot
PropertyOptions {
@@ -196,28 +195,9 @@ Module {
}
// Properties that can be set for multiplexing products.
- property stringList profiles
- property stringList architectures: {
- if (targetOS.contains("android"))
- return ["armv7a"]; // default should be armv5te for NDK < r16, but we can't check here
- if (targetOS.contains("ios-simulator"))
- return ["x86", "x86_64"];
- if (targetOS.contains("ios"))
- return ["armv7a", "arm64"];
- if (targetOS.contains("macos"))
- return ["x86_64"];
- if (targetOS.contains("tvos-simulator"))
- return ["x86_64"];
- if (targetOS.contains("tvos"))
- return ["arm64"];
- if (targetOS.contains("watchos-simulator"))
- return ["x86"];
- if (targetOS.contains("watchos"))
- return ["armv7k"];
- return architecture ? [architecture] : undefined;
- }
-
- property stringList buildVariants: [buildVariant]
+ property stringList profiles: []
+ property stringList architectures: []
+ property stringList buildVariants: []
// internal properties
readonly property string version: [versionMajor, versionMinor, versionPatch].join(".")
diff --git a/share/qbs/modules/qnx/qnx.qbs b/share/qbs/modules/qnx/qnx.qbs
index 49ebc36b6..9cab5abb6 100644
--- a/share/qbs/modules/qnx/qnx.qbs
+++ b/share/qbs/modules/qnx/qnx.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.Environment
import qbs.File
import qbs.FileInfo
@@ -40,7 +39,7 @@ Module {
Probes.PathProbe {
id: qnxSdkProbe
names: ["qnx700", "qnx660", "qnx650"]
- pathPrefixes: qbs.hostOS.contains("windows")
+ searchPaths: qbs.hostOS.contains("windows")
? [Environment.getEnv("USERPROFILE"), Environment.getEnv("SystemDrive")]
: [Environment.getEnv("HOME"), "/opt"]
}
diff --git a/share/qbs/modules/texttemplate/texttemplate.qbs b/share/qbs/modules/texttemplate/texttemplate.qbs
new file mode 100644
index 000000000..c72929660
--- /dev/null
+++ b/share/qbs/modules/texttemplate/texttemplate.qbs
@@ -0,0 +1,64 @@
+import qbs.TextFile
+
+Module {
+ property var dict: ({})
+ property string outputTag: "text"
+ property string outputFileName
+ FileTagger {
+ patterns: ["*.in"]
+ fileTags: ["texttemplate.input"]
+ }
+ Rule {
+ inputs: ["texttemplate.input"]
+ outputFileTags: [product.texttemplate.outputTag]
+ outputArtifacts: [
+ {
+ fileTags: [product.texttemplate.outputTag],
+ filePath: input.texttemplate.outputFileName || input.completeBaseName
+ }
+ ]
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.sourceCode = function() {
+ try {
+ var src = new TextFile(input.filePath, TextFile.ReadOnly);
+ var dst = new TextFile(output.filePath, TextFile.WriteOnly);
+ var rex = /\${(\$|\w+)}/g;
+ var match;
+ while (!src.atEof()) {
+ rex.lastIndex = 0;
+ var line = src.readLine();
+ var matches = [];
+ while (match = rex.exec(line))
+ matches.push(match);
+ for (var i = matches.length; --i >= 0;) {
+ match = matches[i];
+ var replacement;
+ if (match[1] === "$") {
+ replacement = "$";
+ } else {
+ replacement = input.texttemplate.dict[match[1]];
+ if (typeof replacement === "undefined") {
+ throw new Error("Placeholder '" + match[1]
+ + "' is not defined in textemplate.dict for '"
+ + input.fileName + "'.");
+ }
+ }
+ line = line.substr(0, match.index)
+ + replacement
+ + line.substr(match.index + match[0].length);
+ }
+ dst.writeLine(line);
+ }
+ } finally {
+ if (src)
+ src.close();
+ if (dst)
+ dst.close();
+ }
+ };
+ return [cmd];
+ }
+ }
+}
diff --git a/share/qbs/modules/typescript/TypeScriptModule.qbs b/share/qbs/modules/typescript/TypeScriptModule.qbs
index 7cbd02265..d8e61b17f 100644
--- a/share/qbs/modules/typescript/TypeScriptModule.qbs
+++ b/share/qbs/modules/typescript/TypeScriptModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
diff --git a/share/qbs/modules/vcs/vcs-module.qbs b/share/qbs/modules/vcs/vcs-module.qbs
index ee7a34582..f3a47d2a6 100644
--- a/share/qbs/modules/vcs/vcs-module.qbs
+++ b/share/qbs/modules/vcs/vcs-module.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.File
import qbs.FileInfo
import qbs.Process
diff --git a/share/qbs/modules/wix/WiXModule.qbs b/share/qbs/modules/wix/WiXModule.qbs
index 3159822de..ad8586da1 100644
--- a/share/qbs/modules/wix/WiXModule.qbs
+++ b/share/qbs/modules/wix/WiXModule.qbs
@@ -28,7 +28,6 @@
**
****************************************************************************/
-import qbs
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs
index 0df7f5204..922580505 100644
--- a/share/qbs/modules/xcode/xcode.qbs
+++ b/share/qbs/modules/xcode/xcode.qbs
@@ -1,4 +1,3 @@
-import qbs
import qbs.BundleTools
import qbs.Environment
import qbs.File