aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2019-03-19 16:03:11 -0700
committerColin Cross <ccross@android.com>2019-03-19 23:33:47 +0000
commite560c4aabc9ef65ad10f6d795f56f2a1fbd8b3db (patch)
tree495f88e3db5e8aa9511a451a11bc2ec6f6c83353 /java
parent1b7a4b00742fe7bcd22ae04e1b9eae2c01b3677c (diff)
downloadbuild_soong-e560c4aabc9ef65ad10f6d795f56f2a1fbd8b3db.tar.gz
build_soong-e560c4aabc9ef65ad10f6d795f56f2a1fbd8b3db.tar.bz2
build_soong-e560c4aabc9ef65ad10f6d795f56f2a1fbd8b3db.zip
Support package_splits
Pass the package_splits list from the property to aapt2 as --split arguments, sign the extra outputs, install them, and add them as extra output files for SourceFileProducer. Bug: 127921149 Test: TestAppSplits Change-Id: Id94a53ae6a8a68ec81e98abba2fefc9c23feaa7a
Diffstat (limited to 'java')
-rw-r--r--java/aapt2.go6
-rw-r--r--java/aar.go29
-rw-r--r--java/androidmk.go4
-rw-r--r--java/app.go21
-rw-r--r--java/app_builder.go3
-rw-r--r--java/app_test.go24
-rw-r--r--java/java.go5
7 files changed, 82 insertions, 10 deletions
diff --git a/java/aapt2.go b/java/aapt2.go
index d217b9f5..bcc8e976 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -161,7 +161,7 @@ var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile",
func aapt2Link(ctx android.ModuleContext,
packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
flags []string, deps android.Paths,
- compiledRes, compiledOverlay android.Paths) {
+ compiledRes, compiledOverlay android.Paths, splitPackages android.WritablePaths) {
genDir := android.PathForModuleGen(ctx, "aapt2", "R")
@@ -196,12 +196,14 @@ func aapt2Link(ctx android.ModuleContext,
inFlags = append(inFlags, "-R", "@"+overlayFileList.String())
}
+ implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
+
ctx.Build(pctx, android.BuildParams{
Rule: aapt2LinkRule,
Description: "aapt2 link",
Implicits: deps,
Output: packageRes,
- ImplicitOutputs: android.WritablePaths{proguardOptions, genJar, rTxt, extraPackages},
+ ImplicitOutputs: implicitOutputs,
Args: map[string]string{
"flags": strings.Join(flags, " "),
"inFlags": strings.Join(inFlags, " "),
diff --git a/java/aar.go b/java/aar.go
index 3f13e59c..29578e21 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -83,9 +83,18 @@ type aapt struct {
useEmbeddedDex bool
usesNonSdkApis bool
+ splitNames []string
+ splits []split
+
aaptProperties aaptProperties
}
+type split struct {
+ name string
+ suffix string
+ path android.Path
+}
+
func (a *aapt) ExportPackage() android.Path {
return a.exportPackage
}
@@ -248,8 +257,23 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex
compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
}
+ var splitPackages android.WritablePaths
+ var splits []split
+
+ for _, s := range a.splitNames {
+ suffix := strings.Replace(s, ",", "_", -1)
+ path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
+ linkFlags = append(linkFlags, "--split", path.String()+":"+s)
+ splitPackages = append(splitPackages, path)
+ splits = append(splits, split{
+ name: s,
+ suffix: suffix,
+ path: path,
+ })
+ }
+
aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
- linkFlags, linkDeps, compiledRes, compiledOverlay)
+ linkFlags, linkDeps, compiledRes, compiledOverlay, splitPackages)
a.aaptSrcJar = srcJar
a.exportPackage = packageRes
@@ -258,6 +282,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex
a.rroDirs = rroDirs
a.extraAaptPackagesFile = extraPackages
a.rTxt = rTxt
+ a.splits = splits
}
// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
@@ -564,7 +589,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
- linkFlags, linkDeps, nil, overlayRes)
+ linkFlags, linkDeps, nil, overlayRes, nil)
}
var _ Dependency = (*AARImport)(nil)
diff --git a/java/androidmk.go b/java/androidmk.go
index 04b328dc..533b82e4 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -262,6 +262,10 @@ func (app *AndroidApp) AndroidMk() android.AndroidMkData {
if len(app.dexpreopter.builtInstalled) > 0 {
fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", app.dexpreopter.builtInstalled)
}
+ for _, split := range app.aapt.splits {
+ install := "$(LOCAL_MODULE_PATH)/" + strings.TrimSuffix(app.installApkName, ".apk") + split.suffix + ".apk"
+ fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED +=", split.path.String()+":"+install)
+ }
},
},
}
diff --git a/java/app.go b/java/app.go
index 8a422fc2..45e3a836 100644
--- a/java/app.go
+++ b/java/app.go
@@ -226,6 +226,8 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
+ a.aapt.splitNames = a.appProperties.Package_splits
+
a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
// apps manifests are handled by aapt, don't let Module see them
@@ -341,19 +343,32 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
a.outputFile = packageFile
+ for _, split := range a.aapt.splits {
+ // Sign the split APKs
+ packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"_"+split.suffix+".apk")
+ CreateAppPackage(ctx, packageFile, split.path, nil, nil, certificates)
+ a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
+ }
+
// Build an app bundle.
bundleFile := android.PathForModuleOut(ctx, "base.zip")
BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
a.bundleFile = bundleFile
// Install the app package.
+ var installDir android.OutputPath
if ctx.ModuleName() == "framework-res" {
// framework-res.apk is installed as system/framework/framework-res.apk
- ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
+ installDir = android.PathForModuleInstall(ctx, "framework")
} else if Bool(a.appProperties.Privileged) {
- ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", a.installApkName), a.installApkName+".apk", a.outputFile)
+ installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
} else {
- ctx.InstallFile(android.PathForModuleInstall(ctx, "app", a.installApkName), a.installApkName+".apk", a.outputFile)
+ installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
+ }
+
+ ctx.InstallFile(installDir, a.installApkName+".apk", a.outputFile)
+ for _, split := range a.aapt.splits {
+ ctx.InstallFile(installDir, a.installApkName+"_"+split.suffix+".apk", split.path)
}
}
diff --git a/java/app_builder.go b/java/app_builder.go
index bc91d55e..e5ccbbcd 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -65,7 +65,8 @@ var combineApk = pctx.AndroidStaticRule("combineApk",
func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {
- unsignedApk := android.PathForModuleOut(ctx, "unsigned.apk")
+ unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
+ unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
var inputs android.Paths
if dexJarFile != nil {
diff --git a/java/app_test.go b/java/app_test.go
index 1784fc3b..3942ecdb 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -106,6 +106,30 @@ func TestApp(t *testing.T) {
}
}
+func TestAppSplits(t *testing.T) {
+ ctx := testApp(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ package_splits: ["v4", "v7,hdpi"],
+ }`)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ expectedOutputs := []string{
+ filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
+ filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
+ filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
+ }
+ for _, expectedOutput := range expectedOutputs {
+ foo.Output(expectedOutput)
+ }
+
+ if g, w := foo.Module().(*AndroidApp).Srcs().Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
+ t.Errorf("want Srcs() = %q, got %q", w, g)
+ }
+}
+
func TestResourceDirs(t *testing.T) {
testCases := []struct {
name string
diff --git a/java/java.go b/java/java.go
index dcd6dbe9..f088d864 100644
--- a/java/java.go
+++ b/java/java.go
@@ -288,7 +288,8 @@ type Module struct {
proguardDictionary android.Path
// output file of the module, which may be a classes jar or a dex jar
- outputFile android.Path
+ outputFile android.Path
+ extraOutputFiles android.Paths
exportAidlIncludeDirs android.Paths
@@ -322,7 +323,7 @@ type Module struct {
}
func (j *Module) Srcs() android.Paths {
- return android.Paths{j.outputFile}
+ return append(android.Paths{j.outputFile}, j.extraOutputFiles...)
}
func (j *Module) DexJarFile() android.Path {