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_test.go b/apex/apex_test.go
index e2d85ae..7f36f51 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -40,8 +40,9 @@
return
}
-func testApexError(t *testing.T, pattern, bp string) {
- ctx, config := testApexContext(t, bp)
+func testApexError(t *testing.T, pattern, bp string, handlers ...testCustomizer) {
+ t.Helper()
+ ctx, config := testApexContext(t, bp, handlers...)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
@@ -56,8 +57,9 @@
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}
-func testApex(t *testing.T, bp string) (*android.TestContext, android.Config) {
- ctx, config := testApexContext(t, bp)
+func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
+ t.Helper()
+ ctx, config := testApexContext(t, bp, handlers...)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
@@ -65,37 +67,52 @@
return ctx, config
}
-func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
+type testCustomizer func(fs map[string][]byte, config android.Config)
+
+func withFiles(files map[string][]byte) testCustomizer {
+ return func(fs map[string][]byte, config android.Config) {
+ for k, v := range files {
+ fs[k] = v
+ }
+ }
+}
+
+func withTargets(targets map[android.OsType][]android.Target) testCustomizer {
+ return func(fs map[string][]byte, config android.Config) {
+ for k, v := range targets {
+ config.Targets[k] = v
+ }
+ }
+}
+
+func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
config := android.TestArchConfig(buildDir, nil)
config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q")
config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false)
+ config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apexBundleFactory))
ctx.RegisterModuleType("apex_test", android.ModuleFactoryAdaptor(testApexBundleFactory))
+ ctx.RegisterModuleType("apex_vndk", android.ModuleFactoryAdaptor(vndkApexBundleFactory))
ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory))
ctx.RegisterModuleType("apex_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
ctx.RegisterModuleType("prebuilt_apex", android.ModuleFactoryAdaptor(PrebuiltFactory))
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
-
- ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_deps", apexDepsMutator)
- ctx.BottomUp("apex", apexMutator)
- ctx.BottomUp("apex_uses", apexUsesMutator)
- ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
- ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
- })
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory))
ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(cc.LibraryHeaderFactory))
+ ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(cc.PrebuiltSharedLibraryFactory))
+ ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(cc.PrebuiltStaticLibraryFactory))
ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(cc.BinaryFactory))
ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
ctx.RegisterModuleType("cc_test", android.ModuleFactoryAdaptor(cc.TestFactory))
ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
+ ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(cc.VndkPrebuiltSharedFactory))
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory))
ctx.RegisterModuleType("sh_binary", android.ModuleFactoryAdaptor(android.ShBinaryFactory))
@@ -105,6 +122,7 @@
ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory))
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
})
@@ -115,6 +133,15 @@
ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
ctx.BottomUp("version", cc.VersionMutator).Parallel()
ctx.BottomUp("begin", cc.BeginMutator).Parallel()
+ ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator)
+ ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator)
+ })
+ ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("apex_deps", apexDepsMutator)
+ ctx.BottomUp("apex", apexMutator)
+ ctx.BottomUp("apex_uses", apexUsesMutator)
+ ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
+ ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
})
ctx.Register()
@@ -132,6 +159,7 @@
src: "",
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
}
toolchain_library {
@@ -146,6 +174,7 @@
src: "",
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
}
toolchain_library {
@@ -153,6 +182,7 @@
src: "",
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
}
toolchain_library {
@@ -160,6 +190,23 @@
src: "",
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
+ }
+
+ toolchain_library {
+ name: "libclang_rt.builtins-x86_64-android",
+ src: "",
+ vendor_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+ }
+
+ toolchain_library {
+ name: "libclang_rt.builtins-i686-android",
+ src: "",
+ vendor_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
}
cc_object {
@@ -167,6 +214,7 @@
stl: "none",
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
}
cc_object {
@@ -174,6 +222,7 @@
stl: "none",
vendor_available: true,
recovery_available: true,
+ native_bridge_supported: true,
}
cc_object {
@@ -189,20 +238,23 @@
llndk_library {
name: "libc",
symbol_file: "",
+ native_bridge_supported: true,
}
llndk_library {
name: "libm",
symbol_file: "",
+ native_bridge_supported: true,
}
llndk_library {
name: "libdl",
symbol_file: "",
+ native_bridge_supported: true,
}
`
- ctx.MockFileSystem(map[string][]byte{
+ fs := map[string][]byte{
"Android.bp": []byte(bp),
"build/make/target/product/security": nil,
"apex_manifest.json": nil,
@@ -238,7 +290,13 @@
"frameworks/base/api/current.txt": nil,
"build/make/core/proguard.flags": nil,
"build/make/core/proguard_basic_keeps.flags": nil,
- })
+ }
+
+ for _, handler := range handlers {
+ handler(fs, config)
+ }
+
+ ctx.MockFileSystem(fs)
return ctx, config
}
@@ -1210,6 +1268,252 @@
ensureContains(t, cFlags, "-Imy_include")
}
+func TestVndkApexCurrent(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex_vndk {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libvndk",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libvndksp",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+ ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
+ ensureContains(t, copyCmds, "image.apex/lib/libvndksp.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libvndksp.so")
+}
+
+func TestVndkApexWithPrebuilt(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex_vndk {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_prebuilt_library_shared {
+ name: "libvndkshared",
+ srcs: ["libvndkshared.so"],
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `, withFiles(map[string][]byte{
+ "libvndkshared.so": nil,
+ }))
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+ ensureContains(t, copyCmds, "image.apex/lib/libvndkshared.so")
+}
+
+func TestVndkApexVersion(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex_vndk {
+ name: "myapex_v27",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ vndk_version: "27",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libvndk",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ vndk_prebuilt_shared {
+ name: "libvndk27",
+ version: "27",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ srcs: ["libvndk27.so"],
+ }
+ `, withFiles(map[string][]byte{
+ "libvndk27.so": nil,
+ }))
+
+ apexRule := ctx.ModuleForTests("myapex_v27", "android_common_myapex_v27").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+ ensureContains(t, copyCmds, "image.apex/lib/libvndk27.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libvndk27.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib/libvndk.so")
+}
+
+func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
+ testApexError(t, `module "myapex_v27.*" .*: vndk_version: 27 is already defined in "myapex_v27.*"`, `
+ apex_vndk {
+ name: "myapex_v27",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ vndk_version: "27",
+ }
+ apex_vndk {
+ name: "myapex_v27_other",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ vndk_version: "27",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libvndk",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ vndk_prebuilt_shared {
+ name: "libvndk",
+ version: "27",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ srcs: ["libvndk.so"],
+ }
+ `, withFiles(map[string][]byte{
+ "libvndk.so": nil,
+ }))
+}
+
+func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex_vndk {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libvndk",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ native_bridge_supported: true,
+ host_supported: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `, withTargets(map[android.OsType][]android.Target{
+ android.Android: []android.Target{
+ {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+ {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+ {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm64", NativeBridgeRelativePath: "x86_64"},
+ {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm", NativeBridgeRelativePath: "x86"},
+ },
+ }))
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+ ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
+
+ // apex
+ ensureNotContains(t, copyCmds, "image.apex/lib/x86/libvndk.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/x86_64/libvndk.so")
+}
+
+func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
+ testApexError(t, `module "myapex" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
+ apex_vndk {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "myapex",
+ native_bridge_supported: true,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libvndk",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ native_bridge_supported: true,
+ host_supported: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+}
+
func TestDependenciesInApexManifest(t *testing.T) {
ctx, _ := testApex(t, `
apex {