diff --git a/apex/apex.go b/apex/apex.go index c71477117..623023681 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -214,6 +214,10 @@ type apexBundleProperties struct { // Whether this APEX is installable to one of the partitions. Default: true. Installable *bool + // For native libraries and binaries, use the vendor variant instead of the core (platform) variant. + // Default is false. + Use_vendor *bool + Multilib struct { First struct { // List of native libraries whose compile_multilib is "first" @@ -350,21 +354,21 @@ type apexBundle struct { } func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, - native_shared_libs []string, binaries []string, arch string) { + native_shared_libs []string, binaries []string, arch string, imageVariation string) { // Use *FarVariation* to be able to depend on modules having // conflicting variations with this module. This is required since // arch variant of an APEX bundle is 'common' but it is 'arm' or 'arm64' // for native shared libs. ctx.AddFarVariationDependencies([]blueprint.Variation{ {Mutator: "arch", Variation: arch}, - {Mutator: "image", Variation: "core"}, + {Mutator: "image", Variation: imageVariation}, {Mutator: "link", Variation: "shared"}, {Mutator: "version", Variation: ""}, // "" is the non-stub variant }, sharedLibTag, native_shared_libs...) ctx.AddFarVariationDependencies([]blueprint.Variation{ {Mutator: "arch", Variation: arch}, - {Mutator: "image", Variation: "core"}, + {Mutator: "image", Variation: imageVariation}, }, executableTag, binaries...) } @@ -381,27 +385,29 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { // multilib.both. ctx.AddFarVariationDependencies([]blueprint.Variation{ {Mutator: "arch", Variation: target.String()}, - {Mutator: "image", Variation: "core"}, + {Mutator: "image", Variation: a.getImageVariation()}, {Mutator: "link", Variation: "shared"}, }, sharedLibTag, a.properties.Native_shared_libs...) // Add native modules targetting both ABIs addDependenciesForNativeModules(ctx, a.properties.Multilib.Both.Native_shared_libs, - a.properties.Multilib.Both.Binaries, target.String()) + a.properties.Multilib.Both.Binaries, target.String(), + a.getImageVariation()) if i == 0 { // When multilib.* is omitted for binaries, it implies // multilib.first. ctx.AddFarVariationDependencies([]blueprint.Variation{ {Mutator: "arch", Variation: target.String()}, - {Mutator: "image", Variation: "core"}, + {Mutator: "image", Variation: a.getImageVariation()}, }, executableTag, a.properties.Binaries...) // Add native modules targetting the first ABI addDependenciesForNativeModules(ctx, a.properties.Multilib.First.Native_shared_libs, - a.properties.Multilib.First.Binaries, target.String()) + a.properties.Multilib.First.Binaries, target.String(), + a.getImageVariation()) } switch target.Arch.ArchType.Multilib { @@ -409,21 +415,25 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { // Add native modules targetting 32-bit ABI addDependenciesForNativeModules(ctx, a.properties.Multilib.Lib32.Native_shared_libs, - a.properties.Multilib.Lib32.Binaries, target.String()) + a.properties.Multilib.Lib32.Binaries, target.String(), + a.getImageVariation()) addDependenciesForNativeModules(ctx, a.properties.Multilib.Prefer32.Native_shared_libs, - a.properties.Multilib.Prefer32.Binaries, target.String()) + a.properties.Multilib.Prefer32.Binaries, target.String(), + a.getImageVariation()) case "lib64": // Add native modules targetting 64-bit ABI addDependenciesForNativeModules(ctx, a.properties.Multilib.Lib64.Native_shared_libs, - a.properties.Multilib.Lib64.Binaries, target.String()) + a.properties.Multilib.Lib64.Binaries, target.String(), + a.getImageVariation()) if !has32BitTarget { addDependenciesForNativeModules(ctx, a.properties.Multilib.Prefer32.Native_shared_libs, - a.properties.Multilib.Prefer32.Binaries, target.String()) + a.properties.Multilib.Prefer32.Binaries, target.String(), + a.getImageVariation()) } } @@ -461,6 +471,14 @@ func (a *apexBundle) installable() bool { return a.properties.Installable == nil || proptools.Bool(a.properties.Installable) } +func (a *apexBundle) getImageVariation() string { + if proptools.Bool(a.properties.Use_vendor) { + return "vendor" + } else { + return "core" + } +} + func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, dirInApex string) { // Decide the APEX-local directory by the multilib of the library // In the future, we may query this to the module. diff --git a/apex/apex_test.go b/apex/apex_test.go index acc895fe9..77117c550 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -15,12 +15,15 @@ package apex import ( - "android/soong/android" - "android/soong/cc" "io/ioutil" "os" "strings" "testing" + + "github.com/google/blueprint/proptools" + + "android/soong/android" + "android/soong/cc" ) func testApex(t *testing.T, bp string) *android.TestContext { @@ -39,10 +42,13 @@ func testApex(t *testing.T, bp string) *android.TestContext { ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory)) ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory)) ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory)) + ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory)) ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory)) ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory)) ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.BottomUp("image", cc.ImageMutator).Parallel() ctx.BottomUp("link", cc.LinkageMutator).Parallel() + ctx.BottomUp("vndk", cc.VndkMutator).Parallel() ctx.BottomUp("version", cc.VersionMutator).Parallel() ctx.BottomUp("begin", cc.BeginMutator).Parallel() }) @@ -53,38 +59,66 @@ func testApex(t *testing.T, bp string) *android.TestContext { toolchain_library { name: "libcompiler_rt-extras", src: "", + vendor_available: true, + recovery_available: true, } toolchain_library { name: "libatomic", src: "", + vendor_available: true, + recovery_available: true, } toolchain_library { name: "libgcc", src: "", + vendor_available: true, + recovery_available: true, } toolchain_library { name: "libclang_rt.builtins-aarch64-android", src: "", + vendor_available: true, + recovery_available: true, } toolchain_library { name: "libclang_rt.builtins-arm-android", src: "", + vendor_available: true, + recovery_available: true, } cc_object { name: "crtbegin_so", stl: "none", + vendor_available: true, + recovery_available: true, } cc_object { name: "crtend_so", stl: "none", + vendor_available: true, + recovery_available: true, } + llndk_library { + name: "libc", + symbol_file: "", + } + + llndk_library { + name: "libm", + symbol_file: "", + } + + llndk_library { + name: "libdl", + symbol_file: "", + } ` ctx.MockFileSystem(map[string][]byte{ @@ -112,7 +146,7 @@ func setup(t *testing.T) (config android.Config, buildDir string) { } config = android.TestArchConfig(buildDir, nil) - + config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current") return } @@ -184,10 +218,10 @@ func TestBasicApex(t *testing.T) { ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") // Ensure that apex variant is created for the direct dep - ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex") + ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared_myapex") // Ensure that apex variant is created for the indirect dep - ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex") + ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared_myapex") // Ensure that both direct and indirect deps are copied into apex ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") @@ -232,10 +266,10 @@ func TestBasicZipApex(t *testing.T) { ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned") // Ensure that APEX variant is created for the direct dep - ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex") + ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared_myapex") // Ensure that APEX variant is created for the indirect dep - ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex") + ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared_myapex") // Ensure that both direct and indirect deps are copied into apex ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so") @@ -306,24 +340,24 @@ func TestApexWithStubs(t *testing.T) { // Ensure that direct stubs dep is included ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so") - mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"] + mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_shared_myapex").Rule("ld").Args["libFlags"] // Ensure that mylib is linking with the latest version of stubs for mylib2 - ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3_myapex/mylib2.so") + ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_core_shared_3_myapex/mylib2.so") // ... and not linking to the non-stub (impl) variant of mylib2 - ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_myapex/mylib2.so") + ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_core_shared_myapex/mylib2.so") // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex) - ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_myapex/mylib3.so") + ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_core_shared_myapex/mylib3.so") // .. and not linking to the stubs variant of mylib3 - ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12_myapex/mylib3.so") + ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_core_shared_12_myapex/mylib3.so") // Ensure that stubs libs are built without -include flags - mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"] + mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"] ensureNotContains(t, mylib2Cflags, "-include ") // Ensure that genstub is invoked with --apex - ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_3_myapex").Rule("genStubSrc").Args["flags"]) + ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_core_static_3_myapex").Rule("genStubSrc").Args["flags"]) } func TestApexWithExplicitStubsDependency(t *testing.T) { @@ -380,14 +414,14 @@ func TestApexWithExplicitStubsDependency(t *testing.T) { // Ensure that dependency of stubs is not included ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so") - mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"] + mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_shared_myapex").Rule("ld").Args["libFlags"] // Ensure that mylib is linking with version 10 of libfoo - ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10_myapex/libfoo.so") + ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_core_shared_10_myapex/libfoo.so") // ... and not linking to the non-stub (impl) variant of libfoo - ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_myapex/libfoo.so") + ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_core_shared_myapex/libfoo.so") - libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10_myapex").Rule("ld").Args["libFlags"] + libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_core_shared_10_myapex").Rule("ld").Args["libFlags"] // Ensure that libfoo stubs is not linking to libbar (since it is a stubs) ensureNotContains(t, libFooStubsLdFlags, "libbar.so") @@ -466,36 +500,36 @@ func TestApexWithSystemLibsStubs(t *testing.T) { // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs) ensureNotContains(t, copyCmds, "image.apex/lib64/libc.so") - mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"] - mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"] - mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_myapex").Rule("cc").Args["cFlags"] + mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_shared_myapex").Rule("ld").Args["libFlags"] + mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"] + mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_core_shared_myapex").Rule("cc").Args["cFlags"] // For dependency to libc // Ensure that mylib is linking with the latest version of stubs - ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_29_myapex/libc.so") + ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_core_shared_29_myapex/libc.so") // ... and not linking to the non-stub (impl) variant - ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_myapex/libc.so") + ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_core_shared_myapex/libc.so") // ... Cflags from stub is correctly exported to mylib ensureContains(t, mylibCFlags, "__LIBC_API__=29") ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29") // For dependency to libm // Ensure that mylib is linking with the non-stub (impl) variant - ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_myapex/libm.so") + ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_core_shared_myapex/libm.so") // ... and not linking to the stub variant - ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29_myapex/libm.so") + ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_core_shared_29_myapex/libm.so") // ... and is not compiling with the stub ensureNotContains(t, mylibCFlags, "__LIBM_API__=29") ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29") // For dependency to libdl // Ensure that mylib is linking with the specified version of stubs - ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27_myapex/libdl.so") + ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_27_myapex/libdl.so") // ... and not linking to the other versions of stubs - ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28_myapex/libdl.so") - ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29_myapex/libdl.so") + ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_28_myapex/libdl.so") + ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_29_myapex/libdl.so") // ... and not linking to the non-stub (impl) variant - ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_myapex/libdl.so") + ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_myapex/libdl.so") // ... Cflags from stub is correctly exported to mylib ensureContains(t, mylibCFlags, "__LIBDL_API__=27") ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27") @@ -530,3 +564,53 @@ func TestFilesInSubDir(t *testing.T) { ensureListContains(t, dirs, "etc/foo") ensureListContains(t, dirs, "etc/foo/bar") } + +func TestUseVendor(t *testing.T) { + ctx := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["mylib"], + use_vendor: true, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + shared_libs: ["mylib2"], + system_shared_libs: [], + vendor_available: true, + stl: "none", + } + + cc_library { + name: "mylib2", + srcs: ["mylib.cpp"], + system_shared_libs: [], + vendor_available: true, + stl: "none", + } + `) + + inputsList := []string{} + for _, i := range ctx.ModuleForTests("myapex", "android_common_myapex").Module().BuildParamsForTests() { + for _, implicit := range i.Implicits { + inputsList = append(inputsList, implicit.String()) + } + } + inputsString := strings.Join(inputsList, " ") + + // ensure that the apex includes vendor variants of the direct and indirect deps + ensureContains(t, inputsString, "android_arm64_armv8-a_vendor_shared_myapex/mylib.so") + ensureContains(t, inputsString, "android_arm64_armv8-a_vendor_shared_myapex/mylib2.so") + + // ensure that the apex does not include core variants + ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib.so") + ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib2.so") +} diff --git a/cc/cc.go b/cc/cc.go index 02fc23934..139e85feb 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -34,9 +34,9 @@ func init() { android.RegisterModuleType("cc_defaults", defaultsFactory) android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("image", imageMutator).Parallel() + ctx.BottomUp("image", ImageMutator).Parallel() ctx.BottomUp("link", LinkageMutator).Parallel() - ctx.BottomUp("vndk", vndkMutator).Parallel() + ctx.BottomUp("vndk", VndkMutator).Parallel() ctx.BottomUp("ndk_api", ndkApiMutator).Parallel() ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel() ctx.BottomUp("version", VersionMutator).Parallel() @@ -1792,7 +1792,7 @@ func squashRecoverySrcs(m *Module) { } } -func imageMutator(mctx android.BottomUpMutatorContext) { +func ImageMutator(mctx android.BottomUpMutatorContext) { if mctx.Os() != android.Android { return } diff --git a/cc/cc_test.go b/cc/cc_test.go index 33a90f270..29974c99a 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -58,15 +58,15 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android. ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory)) ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory)) ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory)) - ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory)) + ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(LlndkLibraryFactory)) ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory)) ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory)) ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory)) ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory)) ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("image", imageMutator).Parallel() + ctx.BottomUp("image", ImageMutator).Parallel() ctx.BottomUp("link", LinkageMutator).Parallel() - ctx.BottomUp("vndk", vndkMutator).Parallel() + ctx.BottomUp("vndk", VndkMutator).Parallel() ctx.BottomUp("version", VersionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() }) diff --git a/cc/llndk_library.go b/cc/llndk_library.go index 32da05946..cdd2c480a 100644 --- a/cc/llndk_library.go +++ b/cc/llndk_library.go @@ -185,7 +185,7 @@ func NewLLndkStubLibrary() *Module { return module } -func llndkLibraryFactory() android.Module { +func LlndkLibraryFactory() android.Module { module := NewLLndkStubLibrary() android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth) return module @@ -219,6 +219,6 @@ func llndkHeadersFactory() android.Module { } func init() { - android.RegisterModuleType("llndk_library", llndkLibraryFactory) + android.RegisterModuleType("llndk_library", LlndkLibraryFactory) android.RegisterModuleType("llndk_headers", llndkHeadersFactory) } diff --git a/cc/vndk.go b/cc/vndk.go index 1a9b77a2d..623097dad 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -199,7 +199,7 @@ var ( ) // gather list of vndk-core, vndk-sp, and ll-ndk libs -func vndkMutator(mctx android.BottomUpMutatorContext) { +func VndkMutator(mctx android.BottomUpMutatorContext) { if m, ok := mctx.Module().(*Module); ok && m.Enabled() { if lib, ok := m.linker.(*llndkStubDecorator); ok { vndkLibrariesLock.Lock()