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
This commit is contained in:
Colin Cross 2021-04-27 13:06:04 -07:00
parent 203b421043
commit 5271fea26c
10 changed files with 89 additions and 163 deletions

View File

@ -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 {

View File

@ -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() {

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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)

View File

@ -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
}

View File

@ -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)
}

View File

@ -270,6 +270,10 @@ func (m *Module) NeedsLlndkVariants() bool {
return false
}
func (m *Module) NeedsVendorPublicLibraryVariants() bool {
return false
}
func (mod *Module) SdkVersion() string {
return ""
}