aboutsummaryrefslogtreecommitdiffstats
path: root/share/qbs
diff options
context:
space:
mode:
Diffstat (limited to 'share/qbs')
-rw-r--r--share/qbs/imports/qbs/base/AndroidApk.qbs2
-rw-r--r--share/qbs/imports/qbs/base/Application.qbs2
-rw-r--r--share/qbs/module-providers/Qt/templates/android_support.qbs6
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs65
-rw-r--r--share/qbs/modules/Android/sdk/utils.js90
5 files changed, 130 insertions, 35 deletions
diff --git a/share/qbs/imports/qbs/base/AndroidApk.qbs b/share/qbs/imports/qbs/base/AndroidApk.qbs
index 5f86d8457..70cf6aa93 100644
--- a/share/qbs/imports/qbs/base/AndroidApk.qbs
+++ b/share/qbs/imports/qbs/base/AndroidApk.qbs
@@ -32,7 +32,7 @@ import qbs.File
import qbs.FileInfo
Product {
- type: ["android.apk"]
+ type: ["android.package"]
qbs.targetPlatform: "android"
Depends { name: "Android.sdk" }
}
diff --git a/share/qbs/imports/qbs/base/Application.qbs b/share/qbs/imports/qbs/base/Application.qbs
index 63ffc6283..1e4f805a8 100644
--- a/share/qbs/imports/qbs/base/Application.qbs
+++ b/share/qbs/imports/qbs/base/Application.qbs
@@ -29,7 +29,7 @@
****************************************************************************/
NativeBinary {
- type: isForAndroid && !consoleApplication ? ["android.apk"] : ["application"]
+ type: isForAndroid && !consoleApplication ? ["android.package"] : ["application"]
property bool usesNativeCode
diff --git a/share/qbs/module-providers/Qt/templates/android_support.qbs b/share/qbs/module-providers/Qt/templates/android_support.qbs
index 342018321..2835a9336 100644
--- a/share/qbs/module-providers/Qt/templates/android_support.qbs
+++ b/share/qbs/module-providers/Qt/templates/android_support.qbs
@@ -18,7 +18,7 @@ Module {
property string _androidDeployQtFilePath: FileInfo.joinPaths(_qtInstallDir, "bin",
"androiddeployqt")
property string _qtInstallDir
- property bool _enableSdkSupport: product.type && product.type.contains("android.apk")
+ property bool _enableSdkSupport: product.type && product.type.contains("android.package")
&& !consoleApplication
property bool _enableNdkSupport: !product.aggregate || product.multiplexConfigurationId
property string _templatesBaseDir: FileInfo.joinPaths(_qtInstallDir, "src", "android")
@@ -312,7 +312,7 @@ Module {
File.move(product.Qt.android_support._deployQtOutDir + "/AndroidManifest.xml",
outputs["android.manifest_final"][0].filePath);
var libsDir = product.Qt.android_support._deployQtOutDir + "/libs";
- var libDir = product.Android.sdk.apkContentsDir + "/lib";
+ var libDir = product.Android.sdk.packageContentsDir + "/lib";
var listFilePath = outputs["android.deployqt_list"][0].filePath;
var oldLibs = [];
try {
@@ -364,7 +364,7 @@ Module {
for (var i in inputs["android.nativelibrary"])
architectures.push(inputs["android.nativelibrary"][i].Android.ndk.abi);
for (var i in architectures) {
- var abiDirPath = FileInfo.joinPaths(product.Android.sdk.apkContentsDir,
+ var abiDirPath = FileInfo.joinPaths(product.Android.sdk.packageContentsDir,
"lib", architectures[i]);
var files = File.directoryEntries(abiDirPath, File.Files);
for (var i = 0; i < files.length; ++i) {
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index 681b3da94..31f3ed465 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -50,6 +50,14 @@ Module {
environmentPaths: (ndkDir ? [ndkDir] : []).concat(base)
}
+ Probes.PathProbe {
+ id: bundletoolProbe
+ platformSearchPaths: [Android.sdk.sdkDir]
+ names: ["bundletool-all"]
+ nameSuffixes: ["-0.11.0.jar", "-0.12.0.jar", "-0.13.0.jar", "-0.13.3.jar", "-0.13.4.jar",
+ "-0.14.0.jar", "-0.15.0.jar"]
+ }
+
property path sdkDir: sdkProbe.path
property path ndkDir: ndkProbe.path
property path ndkSamplesDir: ndkProbe.samplesDir
@@ -60,6 +68,8 @@ Module {
property int buildToolsVersionPatch: buildToolsVersionParts[2]
property string platform: sdkProbe.platform
+ property path bundletoolFilePath: bundletoolProbe.filePath
+
// Product-specific properties and files
property string packageName: {
var idx = product.name.indexOf(".")
@@ -146,6 +156,12 @@ Module {
}
property path aaptFilePath: FileInfo.joinPaths(buildToolsDir, aaptName)
readonly property bool _enableAapt2: aaptName === "aapt2"
+ property string packageType: "apk"
+ PropertyOptions {
+ name: "packageType"
+ allowedValues: ["apk", "aab"]
+ }
+ readonly property bool _generateAab: packageType == "aab"
property path apksignerFilePath: FileInfo.joinPaths(buildToolsDir, "apksigner")
property path aidlFilePath: FileInfo.joinPaths(buildToolsDir, "aidl")
@@ -160,7 +176,7 @@ Module {
(packageName || "").split('.').join('/'))
property path compiledResourcesDir: FileInfo.joinPaths(product.buildDirectory,
"compiled_resources")
- property string apkContentsDir: FileInfo.joinPaths(product.buildDirectory, "bin")
+ property string packageContentsDir: FileInfo.joinPaths(product.buildDirectory, packageType)
property string debugKeyStorePath: FileInfo.joinPaths(
Environment.getEnv(qbs.hostOS.contains("windows")
? "USERPROFILE" : "HOME"),
@@ -186,6 +202,14 @@ Module {
+ "ANDROID_HOME environment variable to a valid "
+ "Android SDK location.");
}
+ if (!bundletoolFilePath && _generateAab) {
+ throw ModUtils.ModuleError("Could not find Android bundletool at the following "
+ + "location:\n\t" + Android.sdk.sdkDir
+ + "\nInstall the Android bundletool to the above location, "
+ + "or set the Android.sdk.bundletoolFilePath property.\n"
+ + "Android bundletool can be downloaded from "
+ + "https://github.com/google/bundletool");
+ }
}
FileTagger {
@@ -366,12 +390,13 @@ Module {
condition: _enableRules && _enableAapt2
multiplex: true
inputs: ["android.resources_compiled", "android.assets", "android.manifest_final"]
- outputFileTags: ["java.java", "android.apk_base"]
+ outputFileTags: ["java.java", "android.apk_resources"]
outputArtifacts: {
var artifacts = [];
artifacts.push({
- filePath: product.Android.sdk.apkBaseName + ".apk_base",
- fileTags: ["android.apk_base"]
+ filePath: product.Android.sdk.apkBaseName + (product.Android.sdk._generateAab ?
+ ".apk_aab" : ".apk_apk"),
+ fileTags: ["android.apk_resources"]
});
var resources = inputs["android.resources_compiled"];
if (resources && resources.length) {
@@ -419,7 +444,10 @@ Module {
inputs: ["java.class"]
inputsFromDependencies: ["java.jar"]
Artifact {
- filePath: FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "classes.dex")
+ filePath: product.Android.sdk._generateAab ?
+ FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "dex",
+ "classes.dex") :
+ FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "classes.dex")
fileTags: ["android.dex"]
}
prepare: SdkUtils.prepareDex.apply(SdkUtils, arguments)
@@ -431,7 +459,7 @@ Module {
inputsFromDependencies: inputTags
inputs: product.aggregate ? [] : inputTags
Artifact {
- filePath: FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib",
+ filePath: FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "lib",
input.Android.ndk.abi, input.fileName)
fileTags: "android.nativelibrary_deployed"
}
@@ -475,7 +503,7 @@ Module {
}
Rule {
- condition: _enableRules && !_enableAapt2
+ condition: _enableRules && !_enableAapt2 && !_generateAab
multiplex: true
inputs: [
"android.resources", "android.assets", "android.manifest_final",
@@ -484,23 +512,38 @@ Module {
]
Artifact {
filePath: product.Android.sdk.apkBaseName + ".apk"
- fileTags: "android.apk"
+ fileTags: "android.package"
}
prepare: SdkUtils.prepareAaptPackage.apply(SdkUtils, arguments)
}
Rule {
- condition: _enableRules && _enableAapt2
+ condition: _enableRules && _enableAapt2 && !_generateAab
multiplex: true
inputs: [
- "android.apk_base", "android.manifest_final",
+ "android.apk_resources", "android.manifest_final",
"android.dex", "android.stl_deployed",
"android.nativelibrary_deployed", "android.keystore"
]
Artifact {
filePath: product.Android.sdk.apkBaseName + ".apk"
- fileTags: "android.apk"
+ fileTags: "android.package"
}
prepare: SdkUtils.prepareApkPackage.apply(SdkUtils, arguments)
}
+
+ Rule {
+ condition: _enableRules && _enableAapt2 && _generateAab
+ multiplex: true
+ inputs: [
+ "android.apk_resources", "android.manifest_final",
+ "android.dex", "android.stl_deployed",
+ "android.nativelibrary_deployed"
+ ]
+ Artifact {
+ filePath: product.Android.sdk.apkBaseName + ".aab"
+ fileTags: "android.package"
+ }
+ prepare: SdkUtils.prepareBundletoolPackage.apply(SdkUtils, arguments)
+ }
}
diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js
index b1c929e68..63bf1f5c4 100644
--- a/share/qbs/modules/Android/sdk/utils.js
+++ b/share/qbs/modules/Android/sdk/utils.js
@@ -79,7 +79,7 @@ function prepareDex(project, product, inputs, outputs, input, output, explicitly
args = args.concat(jarFiles);
var cmd = new Command(dxFilePath, args);
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
return [cmd];
}
@@ -183,13 +183,12 @@ function prepareAapt2CompileResource(project, product, inputs, outputs, input, o
function prepareAapt2Link(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var cmds = [];
+ var baseOutputFilePath = outputs["android.apk_resources"][0].filePath;
var manifestFilePath = inputs["android.manifest_final"][0].filePath;
var compilesResourcesDir = product.Android.sdk.compiledResourcesDir;
- var apkOutputFilePath = outputs["android.apk_base"][0].filePath;
var compiledResources = inputs["android.resources_compiled"];
- var args = ["link", "-o", apkOutputFilePath, "-I", product.Android.sdk.androidJarFilePath];
- //For aab: args.push("link", "--proto-format");
+ var args = ["link", "-o", baseOutputFilePath, "-I", product.Android.sdk.androidJarFilePath];
var i = 0;
if (compiledResources) {
for (i = 0; i < compiledResources.length; ++i)
@@ -217,9 +216,10 @@ function prepareAapt2Link(project, product, inputs, outputs, input, output, expl
args.push("-A", assetDirs[i]);
if (product.qbs.buildVariant === "debug")
args.push("-v");
-
+ if (product.Android.sdk._generateAab)
+ args.push("--proto-format");
var cmd = new Command(product.Android.sdk.aaptFilePath, args);
- cmd.description = "Linking resources";
+ cmd.description = "linking resources";
cmd.workingDirectory = product.buildDirectory;
cmds.push(cmd);
@@ -234,18 +234,18 @@ function prepareAaptGenerate(project, product, inputs, outputs, input, output,
if (resources && resources.length)
args.push("-J", ModUtils.moduleProperty(product, "generatedJavaFilesBaseDir"));
var cmd = new Command(product.Android.sdk.aaptFilePath, args);
- cmd.description = "Processing resources";
+ cmd.description = "processing resources";
return [cmd];
}
function prepareAaptPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var cmds = [];
- var apkOutput = outputs["android.apk"][0];
+ var apkOutput = outputs["android.package"][0];
var args = commonAaptPackageArgs.apply(this, arguments);
args.push("-F", apkOutput.filePath + ".unaligned");
- args.push(product.Android.sdk.apkContentsDir);
+ args.push(product.Android.sdk.packageContentsDir);
var cmd = new Command(product.Android.sdk.aaptFilePath, args);
- cmd.description = "Generating " + apkOutput.filePath;
+ cmd.description = "generating " + apkOutput.fileName;
cmds.push(cmd);
if (!product.Android.sdk.useApksigner) {
@@ -255,7 +255,7 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex
apkOutput.filePath + ".unaligned",
"androiddebugkey"];
cmd = new Command(product.java.jarsignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
@@ -277,7 +277,7 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex
"--ks-pass", "pass:android",
apkOutput.filePath];
cmd = new Command(product.Android.sdk.apksignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
@@ -286,9 +286,9 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex
function prepareApkPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var cmds = [];
- var apkInputFilePath = inputs["android.apk_base"][0].filePath;
- var apkOutput = outputs["android.apk"][0];
- var apkOutputFilePathUnaligned = outputs["android.apk"][0].filePath + ".unaligned";
+ var apkInputFilePath = inputs["android.apk_resources"][0].filePath;
+ var apkOutput = outputs["android.package"][0];
+ var apkOutputFilePathUnaligned = outputs["android.package"][0].filePath + ".unaligned";
var dexFilePath = inputs["android.dex"][0].filePath;
var copyCmd = new JavaScriptCommand();
@@ -301,7 +301,7 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp
cmds.push(copyCmd);
var jarArgs = ["-uvf", apkOutputFilePathUnaligned, "."];
- var libPath = FileInfo.joinPaths(product.Android.sdk.apkContentsDir);
+ var libPath = FileInfo.joinPaths(product.Android.sdk.packageContentsDir);
var jarCmd = new Command(product.java.jarFilePath, jarArgs);
jarCmd.description = "packaging files";
jarCmd.workingDirectory = libPath;
@@ -314,7 +314,7 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp
apkOutputFilePathUnaligned,
"androiddebugkey"];
cmd = new Command(product.java.jarsignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
@@ -336,13 +336,65 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp
"--ks-pass", "pass:android",
apkOutput.filePath];
cmd = new Command(product.Android.sdk.apksignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
return cmds;
}
+function prepareBundletoolPackage(project, product, inputs, outputs, input, output,
+ explicitlyDependsOn) {
+ var cmds = [];
+ var baseModuleDir = product.Android.sdk.packageContentsDir;
+ var manifestDirName = FileInfo.joinPaths(baseModuleDir, "manifest");
+ var pkgBaseFileName = inputs["android.apk_resources"][0].filePath;
+
+ var jarResourcesArgs = ["xf", pkgBaseFileName];
+ var jarResourcesCmd = new Command(product.java.jarFilePath, jarResourcesArgs);
+ jarResourcesCmd.description = "extracting resources apk";
+ jarResourcesCmd.workingDirectory = baseModuleDir;
+ cmds.push(jarResourcesCmd);
+
+ var moveManifestCmd = new JavaScriptCommand();
+ moveManifestCmd.description = "moving manifest in manifest directory";
+ moveManifestCmd.path = manifestDirName;
+ moveManifestCmd.manifestFilePath = baseModuleDir + "/AndroidManifest.xml";
+ moveManifestCmd.sourceCode = function() {
+ if (!File.exists(path))
+ File.makePath(path);
+ if (File.exists(manifestFilePath))
+ File.move(manifestFilePath, path + "/AndroidManifest.xml");
+ }
+ cmds.push(moveManifestCmd);
+
+ var baseFilePath = FileInfo.joinPaths(product.buildDirectory, "base.zip");
+ var jarBaseArgs = ["cfM", baseFilePath, "."];
+ var jarBaseCmd = new Command(product.java.jarFilePath, jarBaseArgs);
+ jarBaseCmd.description = "compressing base module";
+ jarBaseCmd.workingDirectory = baseModuleDir;
+ cmds.push(jarBaseCmd);
+
+ var aabFilePath = outputs["android.package"][0].filePath;
+ var removeCmd = new JavaScriptCommand();
+ removeCmd.description = "removing previous aab";
+ removeCmd.filePath = aabFilePath;
+ removeCmd.sourceCode = function() {
+ if (File.exists(filePath))
+ File.remove(filePath);
+ }
+ cmds.push(removeCmd);
+
+ var args = ["-jar", product.Android.sdk.bundletoolFilePath, "build-bundle"];
+ args.push("--modules=" + baseFilePath);
+ args.push("--output=" + aabFilePath);
+ var cmd = new Command(product.java.interpreterFilePath, args);
+ cmd.description = "generating " + outputs["android.package"][0].fileName;
+ cmds.push(cmd);
+
+ return cmds;
+}
+
function createDebugKeyStoreCommandString(keytoolFilePath, keystoreFilePath) {
var args = ["-genkey", "-keystore", keystoreFilePath, "-alias", "androiddebugkey",
"-storepass", "android", "-keypass", "android", "-keyalg", "RSA",
@@ -365,7 +417,7 @@ function stlDeploymentData(product, inputs, type)
uniqueFilePaths.push(currentInput.filePath);
data.uniqueInputs.push(currentInput);
var outputFileName = currentInput.fileName;
- data.outputFilePaths.push(FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib",
+ data.outputFilePaths.push(FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "lib",
currentInput.Android.ndk.abi,
outputFileName));
}