From 344d5439c145baddbe85297a5c435da28ee6fcff Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 23 Aug 2019 11:17:39 +0900 Subject: [PATCH] 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 --- android/module.go | 5 + apex/apex.go | 116 +++++++++++++-- apex/apex_test.go | 336 +++++++++++++++++++++++++++++++++++++++++--- cc/cc.go | 13 ++ cc/prebuilt.go | 8 +- cc/prebuilt_test.go | 4 +- cc/testing.go | 2 +- cc/vndk_prebuilt.go | 4 +- 8 files changed, 450 insertions(+), 38 deletions(-) diff --git a/android/module.go b/android/module.go index dda526f09..8076a99ff 100644 --- a/android/module.go +++ b/android/module.go @@ -1495,6 +1495,11 @@ func (m *ModuleBase) EnableNativeBridgeSupportByDefault() { m.commonProperties.Native_bridge_supported = boolPtr(true) } +// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true" +func (m *ModuleBase) IsNativeBridgeSupported() bool { + return proptools.Bool(m.commonProperties.Native_bridge_supported) +} + func (m *moduleContext) InstallInData() bool { return m.module.InstallInData() } diff --git a/apex/apex.go b/apex/apex.go index 1e99ff807..0186b8575 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -21,6 +21,7 @@ import ( "runtime" "sort" "strings" + "sync" "android/soong/android" "android/soong/cc" @@ -152,6 +153,7 @@ var ( "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 @@ func init() { 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 @@ func init() { }) } +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 @@ func apexUsesMutator(mctx android.BottomUpMutatorContext) { 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 @@ type apexTargetBundleProperties struct { 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 apexTargetBundleProperties struct { } } +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 @@ type apexBundle struct { properties apexBundleProperties targetProperties apexTargetBundleProperties + vndkProperties apexVndkProperties apexTypes apexPackaging @@ -483,6 +547,7 @@ type apexBundle struct { flattened bool testApex bool + vndkApex bool // intermediate path for apex_manifest.json manifestOut android.WritablePath @@ -1063,11 +1128,12 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // 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 (a *apexBundle) androidMkForType(apexType apexPackaging) android.AndroidMkD }} } -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 @@ func ApexBundleFactory(testApex bool) android.Module { 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 // diff --git a/apex/apex_test.go b/apex/apex_test.go index e2d85aea0..7f36f51e1 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -40,8 +40,9 @@ func names(s string) (ns []string) { 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 @@ func testApexError(t *testing.T, pattern, bp string) { 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 @@ func testApex(t *testing.T, bp string) (*android.TestContext, android.Config) { 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 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con 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 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con 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 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con src: "", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } toolchain_library { @@ -146,6 +174,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con src: "", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } toolchain_library { @@ -153,6 +182,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con src: "", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } toolchain_library { @@ -160,6 +190,23 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con 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 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con stl: "none", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } cc_object { @@ -174,6 +222,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con stl: "none", vendor_available: true, recovery_available: true, + native_bridge_supported: true, } cc_object { @@ -189,20 +238,23 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con 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 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con "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 @@ func TestHeaderLibsDependency(t *testing.T) { 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 { diff --git a/cc/cc.go b/cc/cc.go index 2ff343413..cd832cb0c 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -478,6 +478,19 @@ func (c *Module) RelativeInstallPath() string { return "" } +// IsVndkOnSystem returns true if a module is supposed to be a vndk library provided by system to vendor +func (c *Module) IsVndkOnSystem() bool { + if linker, ok := c.linker.(libraryInterface); ok { + return linker.shared() && c.isVndk() && c.useVndk() && !c.isVndkExt() + } + + return false +} + +func (c *Module) VndkVersion() string { + return c.vndkVersion() +} + func (c *Module) Init() android.Module { c.AddProperties(&c.Properties, &c.VendorProperties) if c.compiler != nil { diff --git a/cc/prebuilt.go b/cc/prebuilt.go index dc6c43a7c..34556919d 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -19,8 +19,8 @@ import ( ) func init() { - android.RegisterModuleType("cc_prebuilt_library_shared", prebuiltSharedLibraryFactory) - android.RegisterModuleType("cc_prebuilt_library_static", prebuiltStaticLibraryFactory) + android.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory) + android.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory) android.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory) } @@ -131,7 +131,7 @@ func (p *prebuiltLibraryLinker) disablePrebuilt() { // cc_prebuilt_library_shared installs a precompiled shared library that are // listed in the srcs property in the device's directory. -func prebuiltSharedLibraryFactory() android.Module { +func PrebuiltSharedLibraryFactory() android.Module { module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported) return module.Init() } @@ -158,7 +158,7 @@ func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libr // cc_prebuilt_library_static installs a precompiled static library that are // listed in the srcs property in the device's directory. -func prebuiltStaticLibraryFactory() android.Module { +func PrebuiltStaticLibraryFactory() android.Module { module, _ := NewPrebuiltStaticLibrary(android.HostAndDeviceSupported) return module.Init() } diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go index 98d78e816..edcd26eff 100644 --- a/cc/prebuilt_test.go +++ b/cc/prebuilt_test.go @@ -72,8 +72,8 @@ func TestPrebuilt(t *testing.T) { ctx := CreateTestContext(bp, fs, android.Android) - ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(prebuiltSharedLibraryFactory)) - ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(prebuiltStaticLibraryFactory)) + ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(PrebuiltSharedLibraryFactory)) + ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(PrebuiltStaticLibraryFactory)) ctx.RegisterModuleType("cc_prebuilt_binary", android.ModuleFactoryAdaptor(prebuiltBinaryFactory)) ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators) diff --git a/cc/testing.go b/cc/testing.go index 5a3993c0e..a0b163498 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -253,7 +253,7 @@ func CreateTestContext(bp string, fs map[string][]byte, ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory)) ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory)) ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory)) - ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(vndkPrebuiltSharedFactory)) + ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(VndkPrebuiltSharedFactory)) ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("image", ImageMutator).Parallel() ctx.BottomUp("link", LinkageMutator).Parallel() diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go index c8ff87f04..1dfe8eaa0 100644 --- a/cc/vndk_prebuilt.go +++ b/cc/vndk_prebuilt.go @@ -202,11 +202,11 @@ func vndkPrebuiltSharedLibrary() *Module { // }, // }, // } -func vndkPrebuiltSharedFactory() android.Module { +func VndkPrebuiltSharedFactory() android.Module { module := vndkPrebuiltSharedLibrary() return module.Init() } func init() { - android.RegisterModuleType("vndk_prebuilt_shared", vndkPrebuiltSharedFactory) + android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) }