From 5271fea26cab1d1487af84e6c3947260b0a7d2cf Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 27 Apr 2021 13:06:04 -0700 Subject: [PATCH] Remove global state from vendor public libraries Remove the global list of vendor public library modules used to rewrite dependencies from the vendor module to the stubs for system modules, and replace it with building the stubs directly in the system variant of the vendor module. Bug: 178231622 Test: vendor_public_library_test.go Change-Id: I826e69ffd507d7e85fa3d4d85b5157428c642143 --- cc/androidmk.go | 14 ---- cc/cc.go | 39 +++++----- cc/image.go | 16 ++++ cc/library.go | 34 ++++++++- cc/linkable.go | 3 + cc/makevars.go | 4 +- cc/testing.go | 2 - cc/vendor_public_library.go | 122 ++----------------------------- cc/vendor_public_library_test.go | 14 ++-- rust/rust.go | 4 + 10 files changed, 89 insertions(+), 163 deletions(-) diff --git a/cc/androidmk.go b/cc/androidmk.go index 70b52597b..e58d166a3 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -580,20 +580,6 @@ func (c *ndkPrebuiltStlLinker) AndroidMkEntries(ctx AndroidMkContext, entries *a entries.Class = "SHARED_LIBRARIES" } -func (c *vendorPublicLibraryStubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { - entries.Class = "SHARED_LIBRARIES" - entries.SubName = vendorPublicLibrarySuffix - - entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - c.libraryDecorator.androidMkWriteExportedFlags(entries) - _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base()) - - entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) - entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) - entries.SetBool("LOCAL_NO_NOTICE_FILE", true) - }) -} - func (p *prebuiltLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { if p.properties.Check_elf_files != nil { diff --git a/cc/cc.go b/cc/cc.go index 3ba5366d5..16a49d343 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -447,6 +447,10 @@ type VendorProperties struct { // IsVNDKProduct is set if a VNDK module sets the product_available property. IsVNDKProduct bool `blueprint:"mutated"` + + // IsVendorPublicLibrary is set for the core and product variants of a library that has + // vendor_public_library stubs. + IsVendorPublicLibrary bool `blueprint:"mutated"` } // ModuleContextIntf is an interface (on a module context helper) consisting of functions related @@ -475,6 +479,7 @@ type ModuleContextIntf interface { isVndk() bool isVndkSp() bool IsVndkExt() bool + IsVendorPublicLibrary() bool inProduct() bool inVendor() bool inRamdisk() bool @@ -1126,6 +1131,16 @@ func (m *Module) NeedsLlndkVariants() bool { return lib != nil && (lib.hasLLNDKStubs() || lib.hasLLNDKHeaders()) } +func (m *Module) NeedsVendorPublicLibraryVariants() bool { + lib := moduleLibraryInterface(m) + return lib != nil && (lib.hasVendorPublicLibrary()) +} + +// IsVendorPublicLibrary returns true for vendor public libraries. +func (c *Module) IsVendorPublicLibrary() bool { + return c.VendorProperties.IsVendorPublicLibrary +} + // isImplementationForLLNDKPublic returns true for any variant of a cc_library that has LLNDK stubs // and does not set llndk.vendor_available: false. func (c *Module) isImplementationForLLNDKPublic() bool { @@ -1437,6 +1452,10 @@ func (ctx *moduleContextImpl) IsVndkExt() bool { return ctx.mod.IsVndkExt() } +func (ctx *moduleContextImpl) IsVendorPublicLibrary() bool { + return ctx.mod.IsVendorPublicLibrary() +} + func (ctx *moduleContextImpl) mustUseVendorVariant() bool { return ctx.mod.MustUseVendorVariant() } @@ -1599,6 +1618,8 @@ func (c *Module) setSubnameProperty(actx android.ModuleContext) { // added for product variant only when we have vendor and product variants with core // variant. The suffix is not added for vendor-only or product-only module. c.Properties.SubName += c.getNameSuffixWithVndkVersion(actx) + } else if c.IsVendorPublicLibrary() { + c.Properties.SubName += vendorPublicLibrarySuffix } else if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok { // .vendor suffix is added for backward compatibility with VNDK snapshot whose names with // such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp. @@ -2043,8 +2064,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { // The caller can then know to add the variantLibs dependencies differently from the // nonvariantLibs - vendorPublicLibraries := vendorPublicLibraries(actx.Config()) - rewriteLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) { variantLibs = []string{} nonvariantLibs = []string{} @@ -2055,16 +2074,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { nonvariantLibs = append(nonvariantLibs, rewriteSnapshotLib(entry, getSnapshot().SharedLibs)) } else if ctx.useSdk() && inList(name, *getNDKKnownLibs(ctx.Config())) { variantLibs = append(variantLibs, name+ndkLibrarySuffix) - } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, *vendorPublicLibraries) { - vendorPublicLib := name + vendorPublicLibrarySuffix - if actx.OtherModuleExists(vendorPublicLib) { - nonvariantLibs = append(nonvariantLibs, vendorPublicLib) - } else { - // This can happen if vendor_public_library module is defined in a - // namespace that isn't visible to the current module. In that case, - // link to the original library. - nonvariantLibs = append(nonvariantLibs, name) - } } else if ctx.useVndk() { nonvariantLibs = append(nonvariantLibs, rewriteSnapshotLib(entry, getSnapshot().SharedLibs)) } else { @@ -2921,13 +2930,9 @@ func baseLibName(depName string) string { } func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableInterface, depName string) string { - - vendorPublicLibraries := vendorPublicLibraries(ctx.Config()) - libName := baseLibName(depName) ccDepModule, _ := ccDep.(*Module) isLLndk := ccDepModule != nil && ccDepModule.IsLlndk() - isVendorPublicLib := inList(libName, *vendorPublicLibraries) nonSystemVariantsExist := ccDep.HasNonSystemVariants() || isLLndk if ccDepModule != nil { @@ -2949,8 +2954,6 @@ func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableI // The vendor and product modules in Make will have been renamed to not conflict with the // core module, so update the dependency name here accordingly. return libName + ccDep.SubName() - } else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib { - return libName + vendorPublicLibrarySuffix } else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() { return libName + ramdiskSuffix } else if ccDep.InVendorRamdisk() && !ccDep.OnlyInVendorRamdisk() { diff --git a/cc/image.go b/cc/image.go index 5593afce1..1a67731ac 100644 --- a/cc/image.go +++ b/cc/image.go @@ -452,6 +452,17 @@ func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) { if productVndkVersion != "" { productVariants = append(productVariants, productVndkVersion) } + } else if m.NeedsVendorPublicLibraryVariants() { + // A vendor public library has the implementation on /vendor, with stub variants + // for system and product. + coreVariantNeeded = true + vendorVariants = append(vendorVariants, boardVndkVersion) + if platformVndkVersion != "" { + productVariants = append(productVariants, platformVndkVersion) + } + if productVndkVersion != "" { + productVariants = append(productVariants, productVndkVersion) + } } else if boardVndkVersion == "" { // If the device isn't compiling against the VNDK, we always // use the core mode. @@ -677,4 +688,9 @@ func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix) squashProductSrcs(m) } + + if c.NeedsVendorPublicLibraryVariants() && + (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) { + c.VendorProperties.IsVendorPublicLibrary = true + } } diff --git a/cc/library.go b/cc/library.go index b2f33a00e..7ea12c99e 100644 --- a/cc/library.go +++ b/cc/library.go @@ -120,6 +120,9 @@ type LibraryProperties struct { // If this is an LLNDK library, properties to describe the LLNDK stubs. Will be copied from // the module pointed to by llndk_stubs if it is set. Llndk llndkLibraryProperties + + // If this is a vendor public library, properties to describe the vendor public library stubs. + Vendor_public_library vendorPublicLibraryProperties } // StaticProperties is a properties stanza to affect only attributes of the "static" variants of a @@ -770,6 +773,13 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa } return objs } + if ctx.IsVendorPublicLibrary() { + objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Vendor_public_library.Symbol_file), "current", "") + if !Bool(library.Properties.Vendor_public_library.Unversioned) { + library.versionScriptPath = android.OptionalPathForPath(versionScript) + } + return objs + } if library.buildStubs() { symbolFile := String(library.Properties.Stubs.Symbol_file) if symbolFile != "" && !strings.HasSuffix(symbolFile, ".map.txt") { @@ -867,6 +877,7 @@ type versionedInterface interface { implementationModuleName(name string) string hasLLNDKStubs() bool hasLLNDKHeaders() bool + hasVendorPublicLibrary() bool } var _ libraryInterface = (*libraryDecorator)(nil) @@ -962,6 +973,12 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.ReexportHeaderLibHeaders = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...) return deps } + if ctx.IsVendorPublicLibrary() { + headers := library.Properties.Vendor_public_library.Export_public_headers + deps.HeaderLibs = append([]string(nil), headers...) + deps.ReexportHeaderLibHeaders = append([]string(nil), headers...) + return deps + } if library.static() { // Compare with nil because an empty list needs to be propagated. @@ -1418,6 +1435,14 @@ func (library *libraryDecorator) link(ctx ModuleContext, } } + if ctx.IsVendorPublicLibrary() { + // override the module's export_include_dirs with vendor_public_library.override_export_include_dirs + // if it is set. + if override := library.Properties.Vendor_public_library.Override_export_include_dirs; override != nil { + library.flagExporter.Properties.Export_include_dirs = override + } + } + // Linking this library consists of linking `deps.Objs` (.o files in dependencies // of this library), together with `objs` (.o files created by compiling this // library). @@ -1679,6 +1704,12 @@ func (library *libraryDecorator) hasLLNDKHeaders() bool { return Bool(library.Properties.Llndk.Llndk_headers) } +// hasVendorPublicLibrary returns true if this cc_library module has a variant that will build +// vendor public library stubs. +func (library *libraryDecorator) hasVendorPublicLibrary() bool { + return String(library.Properties.Vendor_public_library.Symbol_file) != "" +} + func (library *libraryDecorator) implementationModuleName(name string) string { return name } @@ -1978,11 +2009,12 @@ func createVersionVariations(mctx android.BottomUpMutatorContext, versions []str m := mctx.Module().(*Module) isLLNDK := m.IsLlndk() + isVendorPublicLibrary := m.IsVendorPublicLibrary() modules := mctx.CreateLocalVariations(variants...) for i, m := range modules { - if variants[i] != "" || isLLNDK { + if variants[i] != "" || isLLNDK || isVendorPublicLibrary { // A stubs or LLNDK stubs variant. c := m.(*Module) c.sanitize = nil diff --git a/cc/linkable.go b/cc/linkable.go index 6f6410a5b..338137b9f 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -109,6 +109,9 @@ type LinkableInterface interface { // NeedsLlndkVariants returns true if this module has LLNDK stubs or provides LLNDK headers. NeedsLlndkVariants() bool + // NeedsVendorPublicLibraryVariants returns true if this module has vendor public library stubs. + NeedsVendorPublicLibraryVariants() bool + UseVndk() bool MustUseVendorVariant() bool IsVndk() bool diff --git a/cc/makevars.go b/cc/makevars.go index 923472a13..fa0b2ccce 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -71,8 +71,6 @@ func (c *notOnHostContext) Host() bool { } func makeVarsProvider(ctx android.MakeVarsContext) { - vendorPublicLibraries := vendorPublicLibraries(ctx.Config()) - ctx.Strict("LLVM_RELEASE_VERSION", "${config.ClangShortVersion}") ctx.Strict("LLVM_PREBUILTS_VERSION", "${config.ClangVersion}") ctx.Strict("LLVM_PREBUILTS_BASE", "${config.ClangBase}") @@ -106,7 +104,7 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.VisitAllModules(func(module android.Module) { if ccModule, ok := module.(*Module); ok { baseName := ccModule.BaseModuleName() - if inList(baseName, *vendorPublicLibraries) && module.ExportedToMake() { + if ccModule.IsVendorPublicLibrary() && module.ExportedToMake() { if !inList(baseName, exportedVendorPublicLibraries) { exportedVendorPublicLibraries = append(exportedVendorPublicLibraries, baseName) } diff --git a/cc/testing.go b/cc/testing.go index ca6a0fade..15f7ebb0d 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -556,7 +556,6 @@ var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers( ctx.RegisterModuleType("cc_fuzz", FuzzFactory) ctx.RegisterModuleType("cc_test", TestFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) - ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) RegisterVndkLibraryTxtTypes(ctx) @@ -672,7 +671,6 @@ func CreateTestContext(config android.Config) *android.TestContext { ctx.RegisterModuleType("cc_fuzz", FuzzFactory) ctx.RegisterModuleType("cc_test", TestFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) - ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) diff --git a/cc/vendor_public_library.go b/cc/vendor_public_library.go index 394e32229..65a2b0c9e 100644 --- a/cc/vendor_public_library.go +++ b/cc/vendor_public_library.go @@ -14,26 +14,10 @@ package cc -import ( - "strings" - "sync" - - "android/soong/android" -) - var ( vendorPublicLibrarySuffix = ".vendorpublic" - - vendorPublicLibrariesKey = android.NewOnceKey("vendorPublicLibraries") - vendorPublicLibrariesLock sync.Mutex ) -func vendorPublicLibraries(config android.Config) *[]string { - return config.Once(vendorPublicLibrariesKey, func() interface{} { - return &[]string{} - }).(*[]string) -} - // Creates a stub shared library for a vendor public library. Vendor public libraries // are vendor libraries (owned by them and installed to /vendor partition) that are // exposed to Android apps via JNI. The libraries are made public by being listed in @@ -64,105 +48,9 @@ type vendorPublicLibraryProperties struct { // list of header libs to re-export include directories from. Export_public_headers []string `android:"arch_variant"` -} - -type vendorPublicLibraryStubDecorator struct { - *libraryDecorator - - Properties vendorPublicLibraryProperties - - versionScriptPath android.ModuleGenPath -} - -func (stub *vendorPublicLibraryStubDecorator) Name(name string) string { - return name + vendorPublicLibrarySuffix -} - -func (stub *vendorPublicLibraryStubDecorator) compilerInit(ctx BaseModuleContext) { - stub.baseCompiler.compilerInit(ctx) - - name := ctx.baseModuleName() - if strings.HasSuffix(name, vendorPublicLibrarySuffix) { - ctx.PropertyErrorf("name", "Do not append %q manually, just use the base name", vendorPublicLibrarySuffix) - } - - vendorPublicLibrariesLock.Lock() - defer vendorPublicLibrariesLock.Unlock() - vendorPublicLibraries := vendorPublicLibraries(ctx.Config()) - for _, lib := range *vendorPublicLibraries { - if lib == name { - return - } - } - *vendorPublicLibraries = append(*vendorPublicLibraries, name) -} - -func (stub *vendorPublicLibraryStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags { - flags = stub.baseCompiler.compilerFlags(ctx, flags, deps) - return addStubLibraryCompilerFlags(flags) -} - -func (stub *vendorPublicLibraryStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { - objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), "current", "") - stub.versionScriptPath = versionScript - return objs -} - -func (stub *vendorPublicLibraryStubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { - headers := stub.Properties.Export_public_headers - deps.HeaderLibs = append(deps.HeaderLibs, headers...) - deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, headers...) - return deps -} - -func (stub *vendorPublicLibraryStubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { - stub.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), vendorPublicLibrarySuffix) - return stub.libraryDecorator.linkerFlags(ctx, flags) -} - -func (stub *vendorPublicLibraryStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, - objs Objects) android.Path { - if !Bool(stub.Properties.Unversioned) { - linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String() - flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag) - flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath) - } - return stub.libraryDecorator.link(ctx, flags, deps, objs) -} - -// vendor_public_library creates a stub shared library for a vendor public -// library. This stub library is a build-time only artifact that provides -// symbols that are exposed from a vendor public library. Example: -// -// vendor_public_library { -// name: "libfoo", -// symbol_file: "libfoo.map.txt", -// export_public_headers: ["libfoo_headers"], -// } -func vendorPublicLibraryFactory() android.Module { - module, library := NewLibrary(android.DeviceSupported) - library.BuildOnlyShared() - module.stl = nil - module.sanitize = nil - library.disableStripping() - - stub := &vendorPublicLibraryStubDecorator{ - libraryDecorator: library, - } - module.compiler = stub - module.linker = stub - module.installer = nil - - module.AddProperties( - &stub.Properties, - &module.VendorProperties, - &library.MutatedProperties, - &library.flagExporter.Properties) - - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth) - return module -} - -func init() { - android.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory) + + // list of directories relative to the Blueprints file that willbe added to the include path + // (using -I) for any module that links against the LLNDK variant of this module, replacing + // any that were listed outside the llndk clause. + Override_export_include_dirs []string } diff --git a/cc/vendor_public_library_test.go b/cc/vendor_public_library_test.go index 9f2accf4b..01959b40c 100644 --- a/cc/vendor_public_library_test.go +++ b/cc/vendor_public_library_test.go @@ -26,18 +26,16 @@ func TestVendorPublicLibraries(t *testing.T) { product_available: true, export_include_dirs: ["my_include"], } - vendor_public_library { - name: "libvendorpublic", - product_available: true, - symbol_file: "", - export_public_headers: ["libvendorpublic_headers"], - } cc_library { name: "libvendorpublic", srcs: ["foo.c"], vendor: true, no_libcrt: true, nocrt: true, + vendor_public_library: { + symbol_file: "libvendorpublic.map.txt", + export_public_headers: ["libvendorpublic_headers"], + }, } cc_library { @@ -81,7 +79,7 @@ func TestVendorPublicLibraries(t *testing.T) { // test if libsystem is linked to the stub ld := ctx.ModuleForTests("libsystem", coreVariant).Rule("ld") libflags := ld.Args["libFlags"] - stubPaths := getOutputPaths(ctx, coreVariant, []string{"libvendorpublic" + vendorPublicLibrarySuffix}) + stubPaths := getOutputPaths(ctx, coreVariant, []string{"libvendorpublic"}) if !strings.Contains(libflags, stubPaths[0].String()) { t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags) } @@ -89,7 +87,7 @@ func TestVendorPublicLibraries(t *testing.T) { // test if libsystem is linked to the stub ld = ctx.ModuleForTests("libproduct", productVariant).Rule("ld") libflags = ld.Args["libFlags"] - stubPaths = getOutputPaths(ctx, productVariant, []string{"libvendorpublic" + vendorPublicLibrarySuffix}) + stubPaths = getOutputPaths(ctx, productVariant, []string{"libvendorpublic"}) if !strings.Contains(libflags, stubPaths[0].String()) { t.Errorf("libflags for libproduct must contain %#v, but was %#v", stubPaths[0], libflags) } diff --git a/rust/rust.go b/rust/rust.go index 3dcd45910..bb971420e 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -270,6 +270,10 @@ func (m *Module) NeedsLlndkVariants() bool { return false } +func (m *Module) NeedsVendorPublicLibraryVariants() bool { + return false +} + func (mod *Module) SdkVersion() string { return "" }