From 31656958d6c536a9716e7c2d544db3748d55da2a Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 24 May 2018 16:11:20 -0700 Subject: [PATCH] Use manifest merger in Soong Move the manifest merger config to Soong, and use it to merge manifests of static dependencies of android_library and android_app modules. Bug: 110848854 Test: m checkbuild Change-Id: Ib89e1f1a52a8b76157e4e0348baf42800412df0d Merged-In: Ib89e1f1a52a8b76157e4e0348baf42800412df0d Merged-In: I5d055ce63b8371db500f8868fb73ab3604b8c24a --- Android.bp | 1 + android/makevars.go | 11 ++++++- java/aar.go | 49 +++++++++++++++++---------- java/android_manifest.go | 71 ++++++++++++++++++++++++++++++++++++++++ java/app.go | 4 +++ java/app_test.go | 5 ++- java/config/config.go | 13 ++++++++ java/config/makevars.go | 4 +++ 8 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 java/android_manifest.go diff --git a/Android.bp b/Android.bp index 2daa958de..26aeac23d 100644 --- a/Android.bp +++ b/Android.bp @@ -221,6 +221,7 @@ bootstrap_go_package { srcs: [ "java/aapt2.go", "java/aar.go", + "java/android_manifest.go", "java/android_resources.go", "java/androidmk.go", "java/app_builder.go", diff --git a/android/makevars.go b/android/makevars.go index 3094a48e2..accc4d3ca 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "os" "strconv" + "strings" "github.com/google/blueprint/proptools" ) @@ -240,8 +241,16 @@ func (c *makeVarsContext) SingletonContext() SingletonContext { return c.ctx } +var ninjaDescaper = strings.NewReplacer("$$", "$") + func (c *makeVarsContext) Eval(ninjaStr string) (string, error) { - return c.ctx.Eval(c.pctx, ninjaStr) + s, err := c.ctx.Eval(c.pctx, ninjaStr) + if err != nil { + return "", err + } + // SingletonContext.Eval returns an exapnded string that is valid for a ninja file, de-escape $$ to $ for use + // in a Makefile + return ninjaDescaper.Replace(s), nil } func (c *makeVarsContext) addVariableRaw(name, value string, strict, sort bool) { diff --git a/java/aar.go b/java/aar.go index 91e2f7f01..0cfc585e8 100644 --- a/java/aar.go +++ b/java/aar.go @@ -27,6 +27,7 @@ type AndroidLibraryDependency interface { ExportPackage() android.Path ExportedProguardFlagFiles() android.Paths ExportedStaticPackages() android.Paths + ExportedManifest() android.Path } func init() { @@ -74,8 +75,8 @@ func (a *aapt) ExportPackage() android.Path { return a.exportPackage } -func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext) (flags []string, deps android.Paths, - resDirs, overlayDirs []globbedResourceDir, overlayFiles, rroDirs android.Paths, manifestPath android.Path) { +func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, manifestPath android.Path) (flags []string, + deps android.Paths, resDirs, overlayDirs []globbedResourceDir, rroDirs android.Paths) { hasVersionCode := false hasVersionName := false @@ -116,21 +117,12 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext) (fla assetFiles = append(assetFiles, androidResourceGlob(ctx, dir)...) } - // App manifest file - manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") - manifestPath = android.PathForModuleSrc(ctx, manifestFile) linkFlags = append(linkFlags, "--manifest "+manifestPath.String()) linkDeps = append(linkDeps, manifestPath) linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A ")) linkDeps = append(linkDeps, assetFiles...) - transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkContext) - - overlayFiles = append(overlayFiles, transitiveStaticLibs...) - linkDeps = append(linkDeps, libDeps...) - linkFlags = append(linkFlags, libFlags...) - // SDK version flags minSdkVersion := sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()) @@ -156,7 +148,7 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext) (fla linkFlags = append(linkFlags, "--version-name ", versionName) } - return linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath + return linkFlags, linkDeps, resDirs, overlayDirs, rroDirs } func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkContext sdkContext) { @@ -169,8 +161,18 @@ func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkContext sdkContext) { } func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, extraLinkFlags ...string) { - linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath := a.aapt2Flags(ctx, sdkContext) + transitiveStaticLibs, staticLibManifests, libDeps, libFlags := aaptLibs(ctx, sdkContext) + // App manifest file + manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") + manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) + + manifestPath := manifestMerger(ctx, manifestSrcPath, sdkContext, staticLibManifests) + + linkFlags, linkDeps, resDirs, overlayDirs, rroDirs := a.aapt2Flags(ctx, sdkContext, manifestPath) + + linkFlags = append(linkFlags, libFlags...) + linkDeps = append(linkDeps, libDeps...) linkFlags = append(linkFlags, extraLinkFlags...) packageRes := android.PathForModuleOut(ctx, "package-res.apk") @@ -188,7 +190,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...) } - compiledOverlay = append(compiledOverlay, overlayFiles...) + compiledOverlay = append(compiledOverlay, transitiveStaticLibs...) aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages, linkFlags, linkDeps, compiledRes, compiledOverlay) @@ -203,8 +205,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex } // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths -func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, deps android.Paths, - flags []string) { +func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, staticLibManifests, + deps android.Paths, flags []string) { var sharedLibs android.Paths @@ -229,6 +231,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati if exportPackage != nil { transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...) + staticLibManifests = append(staticLibManifests, aarDep.ExportedManifest()) } } }) @@ -246,7 +249,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs) - return transitiveStaticLibs, deps, flags + return transitiveStaticLibs, staticLibManifests, deps, flags } type AndroidLibrary struct { @@ -269,6 +272,10 @@ func (a *AndroidLibrary) ExportedStaticPackages() android.Paths { return a.exportedStaticPackages } +func (a *AndroidLibrary) ExportedManifest() android.Path { + return a.manifestPath +} + var _ AndroidLibraryDependency = (*AndroidLibrary)(nil) func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -382,6 +389,10 @@ func (a *AARImport) ExportedStaticPackages() android.Paths { return a.exportedStaticPackages } +func (a *AARImport) ExportedManifest() android.Path { + return a.manifest +} + func (a *AARImport) Prebuilt() *android.Prebuilt { return &a.prebuilt } @@ -459,7 +470,9 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { linkFlags = append(linkFlags, "--manifest "+a.manifest.String()) linkDeps = append(linkDeps, a.manifest) - transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkContext(a)) + transitiveStaticLibs, staticLibManifests, libDeps, libFlags := aaptLibs(ctx, sdkContext(a)) + + _ = staticLibManifests linkDeps = append(linkDeps, libDeps...) linkFlags = append(linkFlags, libFlags...) diff --git a/java/android_manifest.go b/java/android_manifest.go new file mode 100644 index 000000000..8fcdcbac1 --- /dev/null +++ b/java/android_manifest.go @@ -0,0 +1,71 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package java + +import ( + "android/soong/java/config" + + "github.com/google/blueprint" + + "android/soong/android" +) + +var manifestFixerRule = pctx.AndroidStaticRule("manifestFixer", + blueprint.RuleParams{ + Command: `${config.ManifestFixerCmd} --minSdkVersion ${minSdkVersion} $usesLibraries $in $out`, + CommandDeps: []string{"${config.ManifestFixerCmd}"}, + }, + "minSdkVersion", "usesLibraries") + +var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger", + blueprint.RuleParams{ + Command: `${config.JavaCmd} -classpath ${config.ManifestMergerClasspath} com.android.manifmerger.Merger ` + + `--main $in $libs --out $out`, + CommandDeps: config.ManifestMergerClasspath, + }, + "libs") + +func manifestMerger(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext, + staticLibManifests android.Paths) android.Path { + + // Inject minSdkVersion into the manifest + fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml") + ctx.Build(pctx, android.BuildParams{ + Rule: manifestFixerRule, + Input: manifest, + Output: fixedManifest, + Args: map[string]string{ + "minSdkVersion": sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()), + }, + }) + manifest = fixedManifest + + // Merge static aar dependency manifests if necessary + if len(staticLibManifests) > 0 { + mergedManifest := android.PathForModuleOut(ctx, "manifest_merger", "AndroidManifest.xml") + ctx.Build(pctx, android.BuildParams{ + Rule: manifestMergerRule, + Input: manifest, + Implicits: staticLibManifests, + Output: mergedManifest, + Args: map[string]string{ + "libs": android.JoinWithPrefix(staticLibManifests.Strings(), "--uses-library "), + }, + }) + manifest = mergedManifest + } + + return manifest +} diff --git a/java/app.go b/java/app.go index a6a06fd34..7ad525d19 100644 --- a/java/app.go +++ b/java/app.go @@ -72,6 +72,10 @@ func (a *AndroidApp) ExportedStaticPackages() android.Paths { return nil } +func (a *AndroidApp) ExportedManifest() android.Path { + return a.manifestPath +} + var _ AndroidLibraryDependency = (*AndroidApp)(nil) type certificate struct { diff --git a/java/app_test.go b/java/app_test.go index 6770119ef..c7c94ece6 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -71,7 +71,10 @@ func TestApp(t *testing.T) { foo := ctx.ModuleForTests("foo", "android_common") - expectedLinkImplicits := []string{"AndroidManifest.xml"} + var expectedLinkImplicits []string + + manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml") + expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String()) frameworkRes := ctx.ModuleForTests("framework-res", "android_common") expectedLinkImplicits = append(expectedLinkImplicits, diff --git a/java/config/config.go b/java/config/config.go index 2fa48cb8f..ae497a6b6 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -42,6 +42,16 @@ var ( "android.car", "android.car7", } + + ManifestMergerClasspath = []string{ + "prebuilts/gradle-plugin/com/android/tools/build/manifest-merger/26.1.0/manifest-merger-26.1.0.jar", + "prebuilts/gradle-plugin/com/android/tools/common/26.1.0/common-26.1.0.jar", + "prebuilts/gradle-plugin/com/android/tools/sdk-common/26.1.0/sdk-common-26.1.0.jar", + "prebuilts/gradle-plugin/com/android/tools/sdklib/26.1.0/sdklib-26.1.0.jar", + "prebuilts/gradle-plugin/org/jetbrains/kotlin/kotlin-runtime/1.0.5/kotlin-runtime-1.0.5.jar", + "prebuilts/gradle-plugin/org/jetbrains/kotlin/kotlin-stdlib/1.1.3/kotlin-stdlib-1.1.3.jar", + "prebuilts/misc/common/guava/guava-21.0.jar", + } ) func init() { @@ -134,4 +144,7 @@ func init() { hostBinToolVariableWithPrebuilt("Aapt2Cmd", "prebuilts/sdk/tools", "aapt2") pctx.SourcePathVariable("ManifestFixerCmd", "build/soong/scripts/manifest_fixer.py") + + pctx.SourcePathsVariable("ManifestMergerJars", " ", ManifestMergerClasspath...) + pctx.SourcePathsVariable("ManifestMergerClasspath", ":", ManifestMergerClasspath...) } diff --git a/java/config/makevars.go b/java/config/makevars.go index d3788774c..275f4966e 100644 --- a/java/config/makevars.go +++ b/java/config/makevars.go @@ -73,4 +73,8 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.Strict("EXTRACT_JAR_PACKAGES", "${ExtractJarPackagesCmd}") ctx.Strict("MANIFEST_FIXER", "${ManifestFixerCmd}") + + ctx.Strict("ANDROID_MANIFEST_MERGER_DEPS", "${ManifestMergerJars}") + ctx.Strict("ANDROID_MANIFEST_MERGER", + "${JavaCmd} -classpath ${ManifestMergerClasspath} com.android.manifmerger.Merger") }