Merge "Turn off dex actions for sourceless modules."
diff --git a/android/config.go b/android/config.go
index 15e2ad4..a18feb6 100644
--- a/android/config.go
+++ b/android/config.go
@@ -288,6 +288,10 @@
config.BuildOsVariant = config.Targets[BuildOs][0].String()
config.BuildOsCommonVariant = getCommonTargets(config.Targets[BuildOs])[0].String()
+ config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
+ config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a")
+ config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm")
+ config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
return testConfig
}
@@ -1100,3 +1104,23 @@
func (c *config) ProductCompatibleProperty() bool {
return Bool(c.productVariables.ProductCompatibleProperty)
}
+
+func (c *deviceConfig) BoardVndkRuntimeDisable() bool {
+ return Bool(c.config.productVariables.BoardVndkRuntimeDisable)
+}
+
+func (c *deviceConfig) DeviceArch() string {
+ return String(c.config.productVariables.DeviceArch)
+}
+
+func (c *deviceConfig) DeviceArchVariant() string {
+ return String(c.config.productVariables.DeviceArchVariant)
+}
+
+func (c *deviceConfig) DeviceSecondaryArch() string {
+ return String(c.config.productVariables.DeviceSecondaryArch)
+}
+
+func (c *deviceConfig) DeviceSecondaryArchVariant() string {
+ return String(c.config.productVariables.DeviceSecondaryArchVariant)
+}
diff --git a/android/mutator.go b/android/mutator.go
index 45954d3..085c055 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -77,7 +77,6 @@
RegisterNamespaceMutator,
RegisterPrebuiltsPreArchMutators,
RegisterDefaultsPreArchMutators,
- RegisterOverridePreArchMutators,
registerVisibilityRuleGatherer,
}
@@ -95,6 +94,7 @@
RegisterPrebuiltsPostDepsMutators,
registerVisibilityRuleEnforcer,
registerNeverallowMutator,
+ RegisterOverridePostDepsMutators,
}
func PreArchMutators(f RegisterMutatorFunc) {
diff --git a/android/onceper.go b/android/onceper.go
index 5ad17fa..ff865c2 100644
--- a/android/onceper.go
+++ b/android/onceper.go
@@ -40,7 +40,8 @@
}
// Once computes a value the first time it is called with a given key per OncePer, and returns the
-// value without recomputing when called with the same key. key must be hashable.
+// value without recomputing when called with the same key. key must be hashable. If value panics
+// the panic will be propagated but the next call to Once with the same key will return nil.
func (once *OncePer) Once(key OnceKey, value func() interface{}) interface{} {
// Fast path: check if the key is already in the map
if v, ok := once.values.Load(key); ok {
@@ -54,10 +55,15 @@
return once.maybeWaitFor(key, v)
}
- // The waiter is inserted, call the value constructor, store it, and signal the waiter
- v := value()
- once.values.Store(key, v)
- close(waiter)
+ // The waiter is inserted, call the value constructor, store it, and signal the waiter. Use defer in case
+ // the function panics.
+ var v interface{}
+ defer func() {
+ once.values.Store(key, v)
+ close(waiter)
+ }()
+
+ v = value()
return v
}
diff --git a/android/onceper_test.go b/android/onceper_test.go
index 95303ba..1a55ff4 100644
--- a/android/onceper_test.go
+++ b/android/onceper_test.go
@@ -175,3 +175,43 @@
t.Errorf(`reentrant Once should return "a": %q`, a)
}
}
+
+// Test that a recovered panic in a Once function doesn't deadlock
+func TestOncePerPanic(t *testing.T) {
+ once := OncePer{}
+ key := NewOnceKey("key")
+
+ ch := make(chan interface{})
+
+ var a interface{}
+
+ go func() {
+ defer func() {
+ ch <- recover()
+ }()
+
+ a = once.Once(key, func() interface{} {
+ panic("foo")
+ })
+ }()
+
+ p := <-ch
+
+ if p.(string) != "foo" {
+ t.Errorf(`expected panic with "foo", got %#v`, p)
+ }
+
+ if a != nil {
+ t.Errorf(`expected a to be nil, got %#v`, a)
+ }
+
+ // If the call to Once that panicked leaves the key in a bad state this will deadlock
+ b := once.Once(key, func() interface{} {
+ return "bar"
+ })
+
+ // The second call to Once should return nil inserted by the first call that panicked.
+ if b != nil {
+ t.Errorf(`expected b to be nil, got %#v`, b)
+ }
+}
diff --git a/android/override_module.go b/android/override_module.go
index 119bca1..5a57c93 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -84,8 +84,13 @@
getOverrides() []OverrideModule
override(ctx BaseModuleContext, o OverrideModule)
+ getOverriddenBy() string
setOverridesProperty(overridesProperties *[]string)
+
+ // Due to complications with incoming dependencies, overrides are processed after DepsMutator.
+ // So, overridable properties need to be handled in a separate, dedicated deps mutator.
+ OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext)
}
// Base module struct for overridable module types
@@ -106,6 +111,8 @@
// set this to a pointer to the property through the InitOverridableModule function, so that
// override information is propagated and aggregated correctly.
overridesProperty *[]string
+
+ overriddenBy string
}
func InitOverridableModule(m OverridableModule, overridesProperty *[]string) {
@@ -153,14 +160,23 @@
}
}
}
+ b.overriddenBy = o.Name()
+}
+
+func (b *OverridableModuleBase) getOverriddenBy() string {
+ return b.overriddenBy
+}
+
+func (b *OverridableModuleBase) OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
}
// Mutators for override/overridable modules. All the fun happens in these functions. It is critical
// to keep them in this order and not put any order mutators between them.
-func RegisterOverridePreArchMutators(ctx RegisterMutatorsContext) {
+func RegisterOverridePostDepsMutators(ctx RegisterMutatorsContext) {
ctx.BottomUp("override_deps", overrideModuleDepsMutator).Parallel()
ctx.TopDown("register_override", registerOverrideMutator).Parallel()
ctx.BottomUp("perform_override", performOverrideMutator).Parallel()
+ ctx.BottomUp("overridable_deps", overridableModuleDepsMutator).Parallel()
}
type overrideBaseDependencyTag struct {
@@ -207,5 +223,22 @@
for i, o := range overrides {
mods[i+1].(OverridableModule).override(ctx, o)
}
+ } else if o, ok := ctx.Module().(OverrideModule); ok {
+ // Create a variant of the overriding module with its own name. This matches the above local
+ // variant name rule for overridden modules, and thus allows ReplaceDependencies to match the
+ // two.
+ ctx.CreateLocalVariations(o.Name())
+ }
+}
+
+func overridableModuleDepsMutator(ctx BottomUpMutatorContext) {
+ if b, ok := ctx.Module().(OverridableModule); ok {
+ if o := b.getOverriddenBy(); o != "" {
+ // Redirect dependencies on the overriding module to this overridden module. Overriding
+ // modules are basically pseudo modules, and all build actions are associated to overridden
+ // modules. Therefore, dependencies on overriding modules need to be forwarded there as well.
+ ctx.ReplaceDependencies(o)
+ }
+ b.OverridablePropertiesDepsMutator(ctx)
}
}
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index bec24c7..b13ce2a 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -23,6 +23,7 @@
RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
+ RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
PreDepsMutators(func(ctx RegisterMutatorsContext) {
ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
@@ -240,3 +241,12 @@
}
}
}
+
+// prebuilt_font installs a font in <partition>/fonts directory.
+func PrebuiltFontFactory() Module {
+ module := &PrebuiltEtc{installDirBase: "fonts"}
+ InitPrebuiltEtcModule(module)
+ // This module is device-only
+ InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
+ return module
+}
diff --git a/android/prebuilt_etc_test.go b/android/prebuilt_etc_test.go
index 08700ae..a5c4480 100644
--- a/android/prebuilt_etc_test.go
+++ b/android/prebuilt_etc_test.go
@@ -30,6 +30,7 @@
ctx.RegisterModuleType("prebuilt_etc_host", ModuleFactoryAdaptor(PrebuiltEtcHostFactory))
ctx.RegisterModuleType("prebuilt_usr_share", ModuleFactoryAdaptor(PrebuiltUserShareFactory))
ctx.RegisterModuleType("prebuilt_usr_share_host", ModuleFactoryAdaptor(PrebuiltUserShareHostFactory))
+ ctx.RegisterModuleType("prebuilt_font", ModuleFactoryAdaptor(PrebuiltFontFactory))
ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
})
@@ -219,3 +220,18 @@
t.Errorf("expected %q, got %q", expected, p.installDirPath.RelPathString())
}
}
+
+func TestPrebuiltFontInstallDirPath(t *testing.T) {
+ ctx, _ := testPrebuiltEtc(t, `
+ prebuilt_font {
+ name: "foo.conf",
+ src: "foo.conf",
+ }
+ `)
+
+ p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a_core").Module().(*PrebuiltEtc)
+ expected := "target/product/test_device/system/fonts"
+ if p.installDirPath.RelPathString() != expected {
+ t.Errorf("expected %q, got %q", expected, p.installDirPath.RelPathString())
+ }
+}
diff --git a/android/util.go b/android/util.go
index f9dce6f..f7a3437 100644
--- a/android/util.go
+++ b/android/util.go
@@ -52,6 +52,31 @@
return string(ret)
}
+func JoinWithSuffix(strs []string, suffix string, separator string) string {
+ if len(strs) == 0 {
+ return ""
+ }
+
+ if len(strs) == 1 {
+ return strs[0] + suffix
+ }
+
+ n := len(" ") * (len(strs) - 1)
+ for _, s := range strs {
+ n += len(suffix) + len(s)
+ }
+
+ ret := make([]byte, 0, n)
+ for i, s := range strs {
+ if i != 0 {
+ ret = append(ret, separator...)
+ }
+ ret = append(ret, s...)
+ ret = append(ret, suffix...)
+ }
+ return string(ret)
+}
+
func sortedKeys(m map[string][]string) []string {
s := make([]string, 0, len(m))
for k := range m {
diff --git a/android/variable.go b/android/variable.go
index c500671..ff3ebaf 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -279,6 +279,8 @@
BoardPlatPrivateSepolicyDirs []string `json:",omitempty"`
BoardSepolicyM4Defs []string `json:",omitempty"`
+ BoardVndkRuntimeDisable *bool `json:",omitempty"`
+
VendorVars map[string]map[string]string `json:",omitempty"`
Ndk_abis *bool `json:",omitempty"`
diff --git a/cc/cc.go b/cc/cc.go
index eaf41d8..a3b9a92 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1011,7 +1011,7 @@
}
}
- if c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid() {
+ if c.installable() {
c.installer.install(ctx, c.outputFile.Path())
if ctx.Failed() {
return
@@ -1968,6 +1968,10 @@
return false
}
+func (c *Module) installable() bool {
+ return c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid()
+}
+
func (c *Module) imageVariation() string {
variation := "core"
if c.useVndk() {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index f3d5e60..36d8aa4 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -20,6 +20,7 @@
"fmt"
"io/ioutil"
"os"
+ "path/filepath"
"reflect"
"sort"
"strings"
@@ -75,6 +76,7 @@
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
})
+ ctx.RegisterSingletonType("vndk-snapshot", android.SingletonFactoryAdaptor(VndkSnapshotSingleton))
ctx.Register()
// add some modules that are required by the compiler and/or linker
@@ -286,8 +288,28 @@
}
}
+func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) {
+ vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
+
+ snapshotPath := filepath.Join(subDir, name+".so")
+ mod := ctx.ModuleForTests(name, variant).Module().(*Module)
+ if !mod.outputFile.Valid() {
+ t.Errorf("%q must have output\n", name)
+ return
+ }
+
+ out := vndkSnapshot.Output(snapshotPath)
+ if out.Input != mod.outputFile.Path() {
+ t.Errorf("The input of VNDK snapshot must be %q, but %q", out.Input.String(), mod.outputFile.String())
+ }
+}
+
func TestVndk(t *testing.T) {
- ctx := testCc(t, `
+ config := android.TestArchConfig(buildDir, nil)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+
+ ctx := testCcWithConfig(t, `
cc_library {
name: "libvndk",
vendor_available: true,
@@ -325,12 +347,35 @@
},
nocrt: true,
}
- `)
+ `, config)
checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
+
+ // Check VNDK snapshot output.
+
+ snapshotDir := "vndk-snapshot"
+ snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+
+ vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
+ "arm64", "armv8-a"))
+ vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
+ "arm", "armv7-a-neon"))
+
+ vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
+ vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
+ vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
+ vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
+
+ variant := "android_arm64_armv8-a_vendor_shared"
+ variant2nd := "android_arm_armv7-a-neon_vendor_shared"
+
+ checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
+ checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
+ checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
+ checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
}
func TestVndkDepError(t *testing.T) {
diff --git a/cc/vndk.go b/cc/vndk.go
index 7859fa2..a1d67af 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -16,6 +16,8 @@
import (
"errors"
+ "fmt"
+ "path/filepath"
"sort"
"strings"
"sync"
@@ -197,9 +199,20 @@
llndkLibrariesKey = android.NewOnceKey("llndkLibrarires")
vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires")
vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires")
+ modulePathsKey = android.NewOnceKey("modulePaths")
+ vndkSnapshotOutputsKey = android.NewOnceKey("vndkSnapshotOutputs")
vndkLibrariesLock sync.Mutex
)
+type vndkSnapshotOutputPaths struct {
+ configs android.Paths
+ notices android.Paths
+ vndkCoreLibs android.Paths
+ vndkCoreLibs2nd android.Paths
+ vndkSpLibs android.Paths
+ vndkSpLibs2nd android.Paths
+}
+
func vndkCoreLibraries(config android.Config) *[]string {
return config.Once(vndkCoreLibrariesKey, func() interface{} {
return &[]string{}
@@ -230,66 +243,296 @@
}).(*[]string)
}
-// gather list of vndk-core, vndk-sp, and ll-ndk libs
-func VndkMutator(mctx android.BottomUpMutatorContext) {
- if m, ok := mctx.Module().(*Module); ok && m.Enabled() {
- if lib, ok := m.linker.(*llndkStubDecorator); ok {
- vndkLibrariesLock.Lock()
- defer vndkLibrariesLock.Unlock()
+func modulePaths(config android.Config) map[string]string {
+ return config.Once(modulePathsKey, func() interface{} {
+ return make(map[string]string)
+ }).(map[string]string)
+}
- llndkLibraries := llndkLibraries(mctx.Config())
- vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
+func vndkSnapshotOutputs(config android.Config) *vndkSnapshotOutputPaths {
+ return config.Once(vndkSnapshotOutputsKey, func() interface{} {
+ return &vndkSnapshotOutputPaths{}
+ }).(*vndkSnapshotOutputPaths)
+}
- name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
- if !inList(name, *llndkLibraries) {
- *llndkLibraries = append(*llndkLibraries, name)
- sort.Strings(*llndkLibraries)
- }
- if !Bool(lib.Properties.Vendor_available) {
- if !inList(name, *vndkPrivateLibraries) {
- *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
- sort.Strings(*vndkPrivateLibraries)
- }
- }
- } else {
- lib, is_lib := m.linker.(*libraryDecorator)
- prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
- if (is_lib && lib.shared()) || (is_prebuilt_lib && prebuilt_lib.shared()) {
- name := strings.TrimPrefix(m.Name(), "prebuilt_")
- if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
- vndkLibrariesLock.Lock()
- defer vndkLibrariesLock.Unlock()
+func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
+ lib := m.linker.(*llndkStubDecorator)
+ name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
- vndkUsingCoreVariantLibraries := vndkUsingCoreVariantLibraries(mctx.Config())
- vndkSpLibraries := vndkSpLibraries(mctx.Config())
- vndkCoreLibraries := vndkCoreLibraries(mctx.Config())
- vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
+ vndkLibrariesLock.Lock()
+ defer vndkLibrariesLock.Unlock()
- if mctx.DeviceConfig().VndkUseCoreVariant() && !inList(name, config.VndkMustUseVendorVariantList) {
- if !inList(name, *vndkUsingCoreVariantLibraries) {
- *vndkUsingCoreVariantLibraries = append(*vndkUsingCoreVariantLibraries, name)
- sort.Strings(*vndkUsingCoreVariantLibraries)
- }
- }
- if m.vndkdep.isVndkSp() {
- if !inList(name, *vndkSpLibraries) {
- *vndkSpLibraries = append(*vndkSpLibraries, name)
- sort.Strings(*vndkSpLibraries)
- }
- } else {
- if !inList(name, *vndkCoreLibraries) {
- *vndkCoreLibraries = append(*vndkCoreLibraries, name)
- sort.Strings(*vndkCoreLibraries)
- }
- }
- if !Bool(m.VendorProperties.Vendor_available) {
- if !inList(name, *vndkPrivateLibraries) {
- *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
- sort.Strings(*vndkPrivateLibraries)
- }
- }
- }
- }
+ llndkLibraries := llndkLibraries(mctx.Config())
+ if !inList(name, *llndkLibraries) {
+ *llndkLibraries = append(*llndkLibraries, name)
+ sort.Strings(*llndkLibraries)
+ }
+ if !Bool(lib.Properties.Vendor_available) {
+ vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
+ if !inList(name, *vndkPrivateLibraries) {
+ *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
+ sort.Strings(*vndkPrivateLibraries)
}
}
}
+
+func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
+ name := strings.TrimPrefix(m.Name(), "prebuilt_")
+
+ vndkLibrariesLock.Lock()
+ defer vndkLibrariesLock.Unlock()
+
+ modulePaths := modulePaths(mctx.Config())
+ if mctx.DeviceConfig().VndkUseCoreVariant() && !inList(name, config.VndkMustUseVendorVariantList) {
+ vndkUsingCoreVariantLibraries := vndkUsingCoreVariantLibraries(mctx.Config())
+ if !inList(name, *vndkUsingCoreVariantLibraries) {
+ *vndkUsingCoreVariantLibraries = append(*vndkUsingCoreVariantLibraries, name)
+ sort.Strings(*vndkUsingCoreVariantLibraries)
+ }
+ }
+ if m.vndkdep.isVndkSp() {
+ vndkSpLibraries := vndkSpLibraries(mctx.Config())
+ if !inList(name, *vndkSpLibraries) {
+ *vndkSpLibraries = append(*vndkSpLibraries, name)
+ sort.Strings(*vndkSpLibraries)
+ modulePaths[name] = mctx.ModuleDir()
+ }
+ } else {
+ vndkCoreLibraries := vndkCoreLibraries(mctx.Config())
+ if !inList(name, *vndkCoreLibraries) {
+ *vndkCoreLibraries = append(*vndkCoreLibraries, name)
+ sort.Strings(*vndkCoreLibraries)
+ modulePaths[name] = mctx.ModuleDir()
+ }
+ }
+ if !Bool(m.VendorProperties.Vendor_available) {
+ vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
+ if !inList(name, *vndkPrivateLibraries) {
+ *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
+ sort.Strings(*vndkPrivateLibraries)
+ }
+ }
+}
+
+// gather list of vndk-core, vndk-sp, and ll-ndk libs
+func VndkMutator(mctx android.BottomUpMutatorContext) {
+ m, ok := mctx.Module().(*Module)
+ if !ok {
+ return
+ }
+
+ if !m.Enabled() {
+ return
+ }
+
+ if _, ok := m.linker.(*llndkStubDecorator); ok {
+ processLlndkLibrary(mctx, m)
+ return
+ }
+
+ lib, is_lib := m.linker.(*libraryDecorator)
+ prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
+
+ if (is_lib && lib.shared()) || (is_prebuilt_lib && prebuilt_lib.shared()) {
+ if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
+ processVndkLibrary(mctx, m)
+ return
+ }
+ }
+}
+
+func init() {
+ android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
+ android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
+ outputs := vndkSnapshotOutputs(ctx.Config())
+
+ ctx.Strict("SOONG_VNDK_SNAPSHOT_CONFIGS", strings.Join(outputs.configs.Strings(), " "))
+ ctx.Strict("SOONG_VNDK_SNAPSHOT_NOTICES", strings.Join(outputs.notices.Strings(), " "))
+ ctx.Strict("SOONG_VNDK_SNAPSHOT_CORE_LIBS", strings.Join(outputs.vndkCoreLibs.Strings(), " "))
+ ctx.Strict("SOONG_VNDK_SNAPSHOT_SP_LIBS", strings.Join(outputs.vndkSpLibs.Strings(), " "))
+ ctx.Strict("SOONG_VNDK_SNAPSHOT_CORE_LIBS_2ND", strings.Join(outputs.vndkCoreLibs2nd.Strings(), " "))
+ ctx.Strict("SOONG_VNDK_SNAPSHOT_SP_LIBS_2ND", strings.Join(outputs.vndkSpLibs2nd.Strings(), " "))
+ })
+}
+
+func VndkSnapshotSingleton() android.Singleton {
+ return &vndkSnapshotSingleton{}
+}
+
+type vndkSnapshotSingleton struct{}
+
+func installVndkSnapshotLib(ctx android.SingletonContext, name string, module *Module, dir string) android.Path {
+ if !module.outputFile.Valid() {
+ panic(fmt.Errorf("module %s has no outputFile\n", name))
+ }
+
+ out := android.PathForOutput(ctx, dir, name+".so")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: module.outputFile.Path(),
+ Output: out,
+ Description: "vndk snapshot " + dir + "/" + name + ".so",
+ Args: map[string]string{
+ "cpFlags": "-f -L",
+ },
+ })
+
+ return out
+}
+
+func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
+ if ctx.DeviceConfig().VndkVersion() != "current" {
+ return
+ }
+
+ if ctx.DeviceConfig().PlatformVndkVersion() == "" {
+ return
+ }
+
+ if ctx.DeviceConfig().BoardVndkRuntimeDisable() {
+ return
+ }
+
+ outputs := vndkSnapshotOutputs(ctx.Config())
+
+ snapshotDir := "vndk-snapshot"
+
+ var vndkLibPath, vndkLib2ndPath string
+
+ snapshotVariantPath := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
+ if ctx.DeviceConfig().BinderBitness() == "32" {
+ vndkLibPath = filepath.Join(snapshotVariantPath, "binder32", fmt.Sprintf(
+ "arch-%s-%s", ctx.DeviceConfig().DeviceArch(), ctx.DeviceConfig().DeviceArchVariant()))
+ vndkLib2ndPath = filepath.Join(snapshotVariantPath, "binder32", fmt.Sprintf(
+ "arch-%s-%s", ctx.DeviceConfig().DeviceSecondaryArch(), ctx.DeviceConfig().DeviceSecondaryArchVariant()))
+ } else {
+ vndkLibPath = filepath.Join(snapshotVariantPath, fmt.Sprintf(
+ "arch-%s-%s", ctx.DeviceConfig().DeviceArch(), ctx.DeviceConfig().DeviceArchVariant()))
+ vndkLib2ndPath = filepath.Join(snapshotVariantPath, fmt.Sprintf(
+ "arch-%s-%s", ctx.DeviceConfig().DeviceSecondaryArch(), ctx.DeviceConfig().DeviceSecondaryArchVariant()))
+ }
+
+ vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
+ vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
+ vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
+ vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
+ noticePath := filepath.Join(snapshotVariantPath, "NOTICE_FILES")
+ noticeBuilt := make(map[string]bool)
+
+ tryBuildNotice := func(m *Module) {
+ name := ctx.ModuleName(m)
+
+ if _, ok := noticeBuilt[name]; ok {
+ return
+ }
+
+ noticeBuilt[name] = true
+
+ if m.NoticeFile().Valid() {
+ out := android.PathForOutput(ctx, noticePath, name+".so.txt")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: m.NoticeFile().Path(),
+ Output: out,
+ Description: "vndk snapshot notice " + name + ".so.txt",
+ Args: map[string]string{
+ "cpFlags": "-f -L",
+ },
+ })
+ outputs.notices = append(outputs.notices, out)
+ }
+ }
+
+ vndkCoreLibraries := vndkCoreLibraries(ctx.Config())
+ vndkSpLibraries := vndkSpLibraries(ctx.Config())
+ vndkPrivateLibraries := vndkPrivateLibraries(ctx.Config())
+
+ ctx.VisitAllModules(func(module android.Module) {
+ m, ok := module.(*Module)
+ if !ok || !m.Enabled() || !m.useVndk() || !m.installable() {
+ return
+ }
+
+ lib, is_lib := m.linker.(*libraryDecorator)
+ prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
+
+ if !(is_lib && lib.shared()) && !(is_prebuilt_lib && prebuilt_lib.shared()) {
+ return
+ }
+
+ is_2nd := m.Target().Arch.ArchType != ctx.Config().DevicePrimaryArchType()
+
+ name := ctx.ModuleName(module)
+
+ if inList(name, *vndkCoreLibraries) {
+ if is_2nd {
+ out := installVndkSnapshotLib(ctx, name, m, vndkCoreLib2ndPath)
+ outputs.vndkCoreLibs2nd = append(outputs.vndkCoreLibs2nd, out)
+ } else {
+ out := installVndkSnapshotLib(ctx, name, m, vndkCoreLibPath)
+ outputs.vndkCoreLibs = append(outputs.vndkCoreLibs, out)
+ }
+ tryBuildNotice(m)
+ } else if inList(name, *vndkSpLibraries) {
+ if is_2nd {
+ out := installVndkSnapshotLib(ctx, name, m, vndkSpLib2ndPath)
+ outputs.vndkSpLibs2nd = append(outputs.vndkSpLibs2nd, out)
+ } else {
+ out := installVndkSnapshotLib(ctx, name, m, vndkSpLibPath)
+ outputs.vndkSpLibs = append(outputs.vndkSpLibs, out)
+ }
+ tryBuildNotice(m)
+ }
+ })
+
+ configsPath := filepath.Join(snapshotVariantPath, "configs")
+ vndkCoreTxt := android.PathForOutput(ctx, configsPath, "vndkcore.libraries.txt")
+ vndkPrivateTxt := android.PathForOutput(ctx, configsPath, "vndkprivate.libraries.txt")
+ modulePathTxt := android.PathForOutput(ctx, configsPath, "module_paths.txt")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Output: vndkCoreTxt,
+ Description: "vndk snapshot vndkcore.libraries.txt",
+ Args: map[string]string{
+ "content": android.JoinWithSuffix(*vndkCoreLibraries, ".so", "\\n"),
+ },
+ })
+ outputs.configs = append(outputs.configs, vndkCoreTxt)
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Output: vndkPrivateTxt,
+ Description: "vndk snapshot vndkprivate.libraries.txt",
+ Args: map[string]string{
+ "content": android.JoinWithSuffix(*vndkPrivateLibraries, ".so", "\\n"),
+ },
+ })
+ outputs.configs = append(outputs.configs, vndkPrivateTxt)
+
+ var modulePathTxtBuilder strings.Builder
+
+ first := true
+ for lib, dir := range modulePaths(ctx.Config()) {
+ if first {
+ first = false
+ } else {
+ modulePathTxtBuilder.WriteString("\\n")
+ }
+ modulePathTxtBuilder.WriteString(lib)
+ modulePathTxtBuilder.WriteString(".so ")
+ modulePathTxtBuilder.WriteString(dir)
+ }
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Output: modulePathTxt,
+ Description: "vndk snapshot module_paths.txt",
+ Args: map[string]string{
+ "content": modulePathTxtBuilder.String(),
+ },
+ })
+ outputs.configs = append(outputs.configs, modulePathTxt)
+}
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 7b378cd..5d3cfa5 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -66,7 +66,7 @@
}
if useEmbeddedDex {
- args = append(args, "--use-embedded-dex=true")
+ args = append(args, "--use-embedded-dex")
}
var deps android.Paths
diff --git a/java/app.go b/java/app.go
index db9c5dd..9f37836 100644
--- a/java/app.go
+++ b/java/app.go
@@ -163,7 +163,9 @@
}
ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
}
+}
+func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
cert := android.SrcIsModule(a.getCertString(ctx))
if cert != "" {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
@@ -632,7 +634,7 @@
m := &OverrideAndroidApp{}
m.AddProperties(&overridableAppProperties{})
- android.InitAndroidModule(m)
+ android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
android.InitOverrideModule(m)
return m
}
diff --git a/java/app_test.go b/java/app_test.go
index bc35e21..347139e 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -881,7 +881,7 @@
name: "foo",
srcs: ["a.java"],
certificate: "expiredkey",
- overrides: ["baz"],
+ overrides: ["qux"],
}
override_android_app {
@@ -903,6 +903,7 @@
`)
expectedVariants := []struct {
+ moduleName string
variantName string
apkName string
apkPath string
@@ -911,24 +912,27 @@
aaptFlag string
}{
{
+ moduleName: "foo",
variantName: "android_common",
apkPath: "/target/product/test_device/system/app/foo/foo.apk",
signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- overrides: []string{"baz"},
+ overrides: []string{"qux"},
aaptFlag: "",
},
{
- variantName: "bar_android_common",
+ moduleName: "bar",
+ variantName: "android_common_bar",
apkPath: "/target/product/test_device/system/app/bar/bar.apk",
signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
- overrides: []string{"baz", "foo"},
+ overrides: []string{"qux", "foo"},
aaptFlag: "",
},
{
- variantName: "baz_android_common",
+ moduleName: "baz",
+ variantName: "android_common_baz",
apkPath: "/target/product/test_device/system/app/baz/baz.apk",
signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- overrides: []string{"baz", "foo"},
+ overrides: []string{"qux", "foo"},
aaptFlag: "--rename-manifest-package org.dandroid.bp",
},
}
@@ -972,6 +976,47 @@
}
}
+func TestOverrideAndroidAppDependency(t *testing.T) {
+ ctx := testJava(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+
+ override_android_app {
+ name: "bar",
+ base: "foo",
+ package_name: "org.dandroid.bp",
+ }
+
+ android_test {
+ name: "baz",
+ srcs: ["b.java"],
+ instrumentation_for: "foo",
+ }
+
+ android_test {
+ name: "qux",
+ srcs: ["b.java"],
+ instrumentation_for: "bar",
+ }
+ `)
+
+ // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
+ javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
+ fooTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar")
+ if !strings.Contains(javac.Args["classpath"], fooTurbine) {
+ t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
+ }
+
+ // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
+ javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
+ barTurbine := filepath.Join(buildDir, ".intermediates", "foo", "android_common_bar", "turbine-combined", "foo.jar")
+ if !strings.Contains(javac.Args["classpath"], barTurbine) {
+ t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
+ }
+}
+
func TestAndroidAppImport(t *testing.T) {
ctx := testJava(t, `
android_app_import {
diff --git a/java/java_test.go b/java/java_test.go
index 370e796..50b1c34 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -93,10 +93,10 @@
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- ctx.PreArchMutators(android.RegisterOverridePreArchMutators)
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
})
+ ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 72c5cfc..5b65c0c 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -126,6 +126,9 @@
// If set to true, the path of dist files is apistubs/core. Defaults to false.
Core_lib *bool
+ // don't create dist rules.
+ No_dist *bool `blueprint:"mutated"`
+
// TODO: determines whether to create HTML doc or not
//Html_doc *bool
}
@@ -212,52 +215,54 @@
android.WriteAndroidMkData(w, data)
module.Library.AndroidMkHostDex(w, name, data)
- // Create a phony module that installs the impl library, for the case when this lib is
- // in PRODUCT_PACKAGES.
- owner := module.ModuleBase.Owner()
- if owner == "" {
- if Bool(module.sdkLibraryProperties.Core_lib) {
- owner = "core"
- } else {
- owner = "android"
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ // Create a phony module that installs the impl library, for the case when this lib is
+ // in PRODUCT_PACKAGES.
+ owner := module.ModuleBase.Owner()
+ if owner == "" {
+ if Bool(module.sdkLibraryProperties.Core_lib) {
+ owner = "core"
+ } else {
+ owner = "android"
+ }
}
- }
- // Create dist rules to install the stubs libs to the dist dir
- if len(module.publicApiStubsPath) == 1 {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- module.publicApiStubsImplPath.Strings()[0]+
- ":"+path.Join("apistubs", owner, "public",
- module.BaseModuleName()+".jar")+")")
- }
- if len(module.systemApiStubsPath) == 1 {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- module.systemApiStubsImplPath.Strings()[0]+
- ":"+path.Join("apistubs", owner, "system",
- module.BaseModuleName()+".jar")+")")
- }
- if len(module.testApiStubsPath) == 1 {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- module.testApiStubsImplPath.Strings()[0]+
- ":"+path.Join("apistubs", owner, "test",
- module.BaseModuleName()+".jar")+")")
- }
- if module.publicApiFilePath != nil {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- module.publicApiFilePath.String()+
- ":"+path.Join("apistubs", owner, "public", "api",
- module.BaseModuleName()+".txt")+")")
- }
- if module.systemApiFilePath != nil {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- module.systemApiFilePath.String()+
- ":"+path.Join("apistubs", owner, "system", "api",
- module.BaseModuleName()+".txt")+")")
- }
- if module.testApiFilePath != nil {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- module.testApiFilePath.String()+
- ":"+path.Join("apistubs", owner, "test", "api",
- module.BaseModuleName()+".txt")+")")
+ // Create dist rules to install the stubs libs to the dist dir
+ if len(module.publicApiStubsPath) == 1 {
+ fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+ module.publicApiStubsImplPath.Strings()[0]+
+ ":"+path.Join("apistubs", owner, "public",
+ module.BaseModuleName()+".jar")+")")
+ }
+ if len(module.systemApiStubsPath) == 1 {
+ fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+ module.systemApiStubsImplPath.Strings()[0]+
+ ":"+path.Join("apistubs", owner, "system",
+ module.BaseModuleName()+".jar")+")")
+ }
+ if len(module.testApiStubsPath) == 1 {
+ fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+ module.testApiStubsImplPath.Strings()[0]+
+ ":"+path.Join("apistubs", owner, "test",
+ module.BaseModuleName()+".jar")+")")
+ }
+ if module.publicApiFilePath != nil {
+ fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+ module.publicApiFilePath.String()+
+ ":"+path.Join("apistubs", owner, "public", "api",
+ module.BaseModuleName()+".txt")+")")
+ }
+ if module.systemApiFilePath != nil {
+ fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+ module.systemApiFilePath.String()+
+ ":"+path.Join("apistubs", owner, "system", "api",
+ module.BaseModuleName()+".txt")+")")
+ }
+ if module.testApiFilePath != nil {
+ fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+ module.testApiFilePath.String()+
+ ":"+path.Join("apistubs", owner, "test", "api",
+ module.BaseModuleName()+".txt")+")")
+ }
}
}
return data
@@ -641,6 +646,10 @@
}
}
+func (module *SdkLibrary) SetNoDist() {
+ module.sdkLibraryProperties.No_dist = proptools.BoolPtr(true)
+}
+
var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
func javaSdkLibraries(config android.Config) *[]string {
diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py
index 4ad9afa..7ec8999 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -231,7 +231,7 @@
def run_test(self, input_manifest, new_uses_libraries):
doc = minidom.parseString(input_manifest)
- manifest_fixer.add_uses_libraries(doc, new_uses_libraries)
+ manifest_fixer.add_uses_libraries(doc, new_uses_libraries, True)
output = StringIO.StringIO()
manifest_fixer.write_xml(output, doc)
return output.getvalue()
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 0313ecd..3f2709e 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -72,6 +72,7 @@
&m.syspropLibraryProperties,
)
m.InitSdkLibraryProperties()
+ m.SetNoDist()
android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, "common")
android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
android.AddLoadHook(m, func(ctx android.LoadHookContext) { m.SdkLibrary.CreateInternalModules(ctx) })