Add "apex_vndk" module type
"apex_vndk" is a variant of "apex" module.
apex_vndk {
name: "com.android.vndk",
..
}
This rule is used to produce a VNDK APEX per vndk version.
It supports automatic inclusion of vndk libs.
If "vndk_version" property is set, the prebuilt vndk libs of
the version will be included in the apex bundle.
apex_vndk {
name: "com.android.vndk.v29"
vndk_version: "29",
...
}
Otherwise, platform's vndk version is used.
This will replace /system/{lib}/vndk-{ver} and vndk-sp-{ver}.
Bug: 134357236
Bug: 139772411
Test: m com.android.vndk
Change-Id: Ib5c86e625839389670d13c683a7427198ef6852f
diff --git a/apex/apex.go b/apex/apex.go
index 1e99ff8..0186b85 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -21,6 +21,7 @@
"runtime"
"sort"
"strings"
+ "sync"
"android/soong/android"
"android/soong/cc"
@@ -152,6 +153,7 @@
"com.android.media": []string{"libbinder"},
"com.android.media.swcodec": []string{"libbinder"},
"test_com.android.media.swcodec": []string{"libbinder"},
+ "com.android.vndk": []string{"libbinder"},
}
)
@@ -184,9 +186,14 @@
android.RegisterModuleType("apex", apexBundleFactory)
android.RegisterModuleType("apex_test", testApexBundleFactory)
+ android.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
android.RegisterModuleType("apex_defaults", defaultsFactory)
android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
+ android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator).Parallel()
+ ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator).Parallel()
+ })
android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("apex_deps", apexDepsMutator)
ctx.BottomUp("apex", apexMutator).Parallel()
@@ -194,6 +201,51 @@
})
}
+var (
+ vndkApexListKey = android.NewOnceKey("vndkApexList")
+ vndkApexListMutex sync.Mutex
+)
+
+func vndkApexList(config android.Config) map[string]*apexBundle {
+ return config.Once(vndkApexListKey, func() interface{} {
+ return map[string]*apexBundle{}
+ }).(map[string]*apexBundle)
+}
+
+// apexVndkGatherMutator gathers "apex_vndk" modules and puts them in a map with vndk_version as a key.
+func apexVndkGatherMutator(mctx android.TopDownMutatorContext) {
+ if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
+ if ab.IsNativeBridgeSupported() {
+ mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
+ }
+ vndkVersion := proptools.StringDefault(ab.vndkProperties.Vndk_version, mctx.DeviceConfig().PlatformVndkVersion())
+ vndkApexListMutex.Lock()
+ defer vndkApexListMutex.Unlock()
+ vndkApexList := vndkApexList(mctx.Config())
+ if other, ok := vndkApexList[vndkVersion]; ok {
+ mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.Name())
+ }
+ vndkApexList[vndkVersion] = ab
+ }
+}
+
+// apexVndkAddDepsMutator adds (reverse) dependencies from vndk libs to apex_vndk modules.
+// It filters only libs with matching targets.
+func apexVndkAddDepsMutator(mctx android.BottomUpMutatorContext) {
+ if cc, ok := mctx.Module().(*cc.Module); ok && cc.IsVndkOnSystem() {
+ vndkApexList := vndkApexList(mctx.Config())
+ if ab, ok := vndkApexList[cc.VndkVersion()]; ok {
+ targetArch := cc.Target().String()
+ for _, target := range ab.MultiTargets() {
+ if target.String() == targetArch {
+ mctx.AddReverseDependency(mctx.Module(), sharedLibTag, ab.Name())
+ break
+ }
+ }
+ }
+ }
+}
+
// Mark the direct and transitive dependencies of apex bundles so that they
// can be built for the apex bundles.
func apexDepsMutator(mctx android.TopDownMutatorContext) {
@@ -240,11 +292,14 @@
type apexNativeDependencies struct {
// List of native libraries
Native_shared_libs []string
+
// List of native executables
Binaries []string
+
// List of native tests
Tests []string
}
+
type apexMultilibProperties struct {
// Native dependencies whose compile_multilib is "first"
First apexNativeDependencies
@@ -345,14 +400,17 @@
Android struct {
Multilib apexMultilibProperties
}
+
// Multilib properties only for host.
Host struct {
Multilib apexMultilibProperties
}
+
// Multilib properties only for host linux_bionic.
Linux_bionic struct {
Multilib apexMultilibProperties
}
+
// Multilib properties only for host linux_glibc.
Linux_glibc struct {
Multilib apexMultilibProperties
@@ -360,6 +418,11 @@
}
}
+type apexVndkProperties struct {
+ // Indicates VNDK version of which this VNDK APEX bundles VNDK libs. Default is Platform VNDK Version.
+ Vndk_version *string
+}
+
type apexFileClass int
const (
@@ -458,6 +521,7 @@
properties apexBundleProperties
targetProperties apexTargetBundleProperties
+ vndkProperties apexVndkProperties
apexTypes apexPackaging
@@ -483,6 +547,7 @@
flattened bool
testApex bool
+ vndkApex bool
// intermediate path for apex_manifest.json
manifestOut android.WritablePath
@@ -1063,11 +1128,12 @@
// remove duplicates in filesInfo
removeDup := func(filesInfo []apexFile) []apexFile {
- encountered := make(map[android.Path]bool)
+ encountered := make(map[string]bool)
result := []apexFile{}
for _, f := range filesInfo {
- if !encountered[f.builtFile] {
- encountered[f.builtFile] = true
+ dest := filepath.Join(f.installDir, f.builtFile.Base())
+ if !encountered[dest] {
+ encountered[dest] = true
result = append(result, f)
}
}
@@ -1590,18 +1656,9 @@
}}
}
-func testApexBundleFactory() android.Module {
- return ApexBundleFactory(true /*testApex*/)
-}
-
-func apexBundleFactory() android.Module {
- return ApexBundleFactory(false /*testApex*/)
-}
-
-func ApexBundleFactory(testApex bool) android.Module {
+func newApexBundle() *apexBundle {
module := &apexBundle{
outputFiles: map[apexPackaging]android.WritablePath{},
- testApex: testApex,
}
module.AddProperties(&module.properties)
module.AddProperties(&module.targetProperties)
@@ -1613,6 +1670,39 @@
return module
}
+func ApexBundleFactory(testApex bool) android.Module {
+ bundle := newApexBundle()
+ bundle.testApex = testApex
+ return bundle
+}
+
+func testApexBundleFactory() android.Module {
+ bundle := newApexBundle()
+ bundle.testApex = true
+ return bundle
+}
+
+func apexBundleFactory() android.Module {
+ return newApexBundle()
+}
+
+// apex_vndk creates a special variant of apex modules which contains only VNDK libraries.
+// If `vndk_version` is specified, the VNDK libraries of the specified VNDK version are gathered automatically.
+// If not specified, then the "current" versions are gathered.
+func vndkApexBundleFactory() android.Module {
+ bundle := newApexBundle()
+ bundle.vndkApex = true
+ bundle.AddProperties(&bundle.vndkProperties)
+ android.AddLoadHook(bundle, func(ctx android.LoadHookContext) {
+ ctx.AppendProperties(&struct {
+ Compile_multilib *string
+ }{
+ proptools.StringPtr("both"),
+ })
+ })
+ return bundle
+}
+
//
// Defaults
//