aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Mortimer <sam@mortimer.me.uk>2019-10-07 11:41:14 -0700
committerMichael Bestas <mkbestas@lineageos.org>2019-12-11 19:03:43 +0200
commitefa6a129b0954708e575069bef56fce1e234f0da (patch)
treeb3d135cc5e3da7b5cc8f1886ce3765028367c796
parent094c1b049a74506798c33d023a2a0df3506947c9 (diff)
downloadbuild_soong-efa6a129b0954708e575069bef56fce1e234f0da.tar.gz
build_soong-efa6a129b0954708e575069bef56fce1e234f0da.tar.bz2
build_soong-efa6a129b0954708e575069bef56fce1e234f0da.zip
soong: Give priority to modules in exported namespaces for bootjars
* Looking for modules that provide a boot jar is currently done by module name match only. This breaks when you have multiple copies of the same module in your build tree (eg in another device). * Add a new mutator that marks the modules that should be used for bootjar content. * The logic is simple: give priority to modules that are in exported soong namespace. Change-Id: I2476174b892475c14a9f10b5e66b8496186f81c0
-rw-r--r--Android.bp1
-rw-r--r--android/bootjar.go117
-rw-r--r--android/module.go7
-rw-r--r--java/dexpreopt_bootjars.go4
-rw-r--r--java/dexpreopt_bootjars_test.go2
-rw-r--r--java/hiddenapi.go9
6 files changed, 139 insertions, 1 deletions
diff --git a/Android.bp b/Android.bp
index 3ade619a..e8d132dc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -44,6 +44,7 @@ bootstrap_go_package {
"android/apex.go",
"android/api_levels.go",
"android/arch.go",
+ "android/bootjar.go",
"android/config.go",
"android/defaults.go",
"android/defs.go",
diff --git a/android/bootjar.go b/android/bootjar.go
new file mode 100644
index 00000000..ea04dc8f
--- /dev/null
+++ b/android/bootjar.go
@@ -0,0 +1,117 @@
+// Copyright (C) 2019 The LineageOS Project
+//
+// 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 android
+
+import (
+ "strings"
+)
+
+// Keys are bootjar name, value is whether or not
+// we've marked a module as being a provider for it.
+var jarMap map[string]bool
+
+func init() {
+ PreArchMutators(RegisterBootJarMutators)
+}
+
+// Note: registration function is structured this way so that it can be included
+// from soong module tests.
+func RegisterBootJarMutators(ctx RegisterMutatorsContext) {
+ // Note: can't use Parallel() since we touch global jarMap
+ ctx.TopDown("bootjar_exportednamespace", bootJarMutatorExportedNamespace)
+ ctx.TopDown("bootjar_anynamespace", bootJarMutatorAnyNamespace)
+}
+
+func mutatorInit(mctx TopDownMutatorContext) {
+ // Did we init already ?
+ if jarMap != nil {
+ return
+ }
+
+ jarMap = make(map[string]bool)
+ for _, moduleName := range mctx.Config().BootJars() {
+ jarMap[moduleName] = false
+ }
+}
+
+// Mark modules in soong exported namespace as providing a boot jar.
+func bootJarMutatorExportedNamespace(mctx TopDownMutatorContext) {
+ bootJarMutator(mctx, true)
+}
+
+// Mark modules in any namespace (incl root) as providing a boot jar.
+func bootJarMutatorAnyNamespace(mctx TopDownMutatorContext) {
+ bootJarMutator(mctx, false)
+}
+
+func bootJarMutator(mctx TopDownMutatorContext, requireExportedNamespace bool) {
+ mutatorInit(mctx)
+
+ module, ok := mctx.Module().(Module)
+ if !ok {
+ // Not a proper module
+ return
+ }
+
+ // Does this module produce a dex jar ?
+ if _, ok := module.(interface{ DexJar() Path }); !ok {
+ // No
+ return
+ }
+
+ // If jarMap is empty we must be running in a test so
+ // set boot jar provide to true for all modules.
+ if len(jarMap) == 0 {
+ module.base().commonProperties.BootJarProvider = true
+ return
+ }
+
+ name := mctx.ModuleName()
+ dir := mctx.ModuleDir()
+
+ // Special treatment for hiddenapi modules - create extra
+ // jarMap entries if needed.
+ baseName := strings.TrimSuffix(name, "-hiddenapi")
+ if name != baseName {
+ _, baseIsBootJar := jarMap[baseName]
+ _, alreadyExists := jarMap[name]
+ if baseIsBootJar && !alreadyExists {
+ // This is a hidden api module whose base name exists in the boot jar list
+ // and we've not visited it before. Create a map entry for it.
+ jarMap[name] = false
+ }
+ }
+
+ // Does this module match the name of a boot jar ?
+ if found, exists := jarMap[name]; !exists || found {
+ // No
+ return
+ }
+
+ if requireExportedNamespace {
+ for _, n := range mctx.Config().ExportedNamespaces() {
+ if strings.HasPrefix(dir, n) {
+ jarMap[name] = true
+ module.base().commonProperties.BootJarProvider = true
+ break
+ }
+ }
+ } else {
+ jarMap[name] = true
+ module.base().commonProperties.BootJarProvider = true
+ }
+
+ return
+}
diff --git a/android/module.go b/android/module.go
index 495efbe1..17ddb050 100644
--- a/android/module.go
+++ b/android/module.go
@@ -304,6 +304,9 @@ type commonProperties struct {
SkipInstall bool `blueprint:"mutated"`
NamespaceExportedToMake bool `blueprint:"mutated"`
+
+ // Whether this module provides a boot jar
+ BootJarProvider bool `blueprint:"mutated"`
}
type hostAndDeviceProperties struct {
@@ -521,6 +524,10 @@ func (a *ModuleBase) Name() string {
return String(a.nameProperties.Name)
}
+func (a *ModuleBase) BootJarProvider() bool {
+ return a.commonProperties.BootJarProvider
+}
+
// BaseModuleName returns the name of the module as specified in the blueprints file.
func (a *ModuleBase) BaseModuleName() string {
return String(a.nameProperties.Name)
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 4d87b2f7..87d8428d 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -151,6 +151,10 @@ func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootI
bootDexJars := make(android.Paths, len(image.modules))
ctx.VisitAllModules(func(module android.Module) {
+ if m, ok := module.(interface{ BootJarProvider() bool }); !ok ||
+ !m.BootJarProvider() {
+ return
+ }
// Collect dex jar paths for the modules listed above.
if j, ok := module.(interface{ DexJar() android.Path }); ok {
name := ctx.ModuleName(module)
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index cbb52f15..d4f84914 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -53,6 +53,8 @@ func TestDexpreoptBootJars(t *testing.T) {
ctx := testContext(config, bp, nil)
+ ctx.PreArchMutators(android.RegisterBootJarMutators)
+
ctx.RegisterSingletonType("dex_bootjars", android.SingletonFactoryAdaptor(dexpreoptBootJarsFactory))
run(t, ctx, config)
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 6020aba6..28724f2a 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -73,7 +73,14 @@ func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOu
// to the hidden API for the bootclassloader. If information is gathered for modules
// not on the list then that will cause failures in the CtsHiddenApiBlacklist...
// tests.
- if inList(bootJarName, ctx.Config().BootJars()) {
+ isBootJarProvider := false
+ ctx.VisitAllModuleVariants(func(module android.Module) {
+ if m, ok := module.(interface{ BootJarProvider() bool }); ok &&
+ m.BootJarProvider() {
+ isBootJarProvider = true
+ }
+ })
+ if isBootJarProvider && inList(bootJarName, ctx.Config().BootJars()) {
// Derive the greylist from classes jar.
flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")