Don't rewrite LLNDK dependencies with .llndk suffix

Rewriting LLNDK dependencies with .llndk suffix requries referencing
a global data structure to determine if a given library is an LLNDK
library and therefore needs the .llndk suffix.  References to
global data structures from mutators must be removed to support
incremental Soong analysis.  Instead, move the LLNDK stubs rules
into the vendor variant of the implementing cc_library so that
the original name can be used.

As an incremental step, the llndk_library modules are left in
place, and the properties are copied into the cc_library via
the dependency specified by the llndk_stub property.  A followup
will move the LLNDK properties directly into the cc_library and
delete the llndk_library modules.

The global list of LLNDK libraries is kept for now as it is used
to generate the vndk.libraries.txt file.

Bug: 170784825
Test: m checkbuild
Test: compare Soong outputs
Test: all Soong tests
Change-Id: I2a942b21c162541a49e27b2e5833c9aebccff1d0
This commit is contained in:
Colin Cross 2020-12-16 16:46:01 -08:00
parent adc81a0783
commit 127bb8b9f6
15 changed files with 344 additions and 200 deletions

View File

@ -90,6 +90,7 @@ type MakeVarsContext interface {
ModuleDir(module blueprint.Module) string ModuleDir(module blueprint.Module) string
ModuleSubDir(module blueprint.Module) string ModuleSubDir(module blueprint.Module) string
ModuleType(module blueprint.Module) string ModuleType(module blueprint.Module) string
ModuleProvider(module blueprint.Module, key blueprint.ProviderKey) interface{}
BlueprintFile(module blueprint.Module) string BlueprintFile(module blueprint.Module) string
ModuleErrorf(module blueprint.Module, format string, args ...interface{}) ModuleErrorf(module blueprint.Module, format string, args ...interface{})

View File

@ -1355,9 +1355,9 @@ func TestApexDependsOnLLNDKTransitively(t *testing.T) {
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so") ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"] mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"]
ensureContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so") ensureContains(t, mylibLdFlags, "libbar/android_vendor.VER_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
for _, ver := range tc.shouldNotLink { for _, ver := range tc.shouldNotLink {
ensureNotContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+ver+"/libbar.so") ensureNotContains(t, mylibLdFlags, "libbar/android_vendor.VER_arm64_armv8-a_shared_"+ver+"/libbar.so")
} }
mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"] mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]

View File

@ -269,7 +269,7 @@ func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries
if library.shared() && !library.buildStubs() { if library.shared() && !library.buildStubs() {
ctx.subAndroidMk(entries, library.baseInstaller) ctx.subAndroidMk(entries, library.baseInstaller)
} else { } else {
if library.buildStubs() { if library.buildStubs() && library.stubsVersion() != "" {
entries.SubName = "." + library.stubsVersion() entries.SubName = "." + library.stubsVersion()
} }
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) { entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
@ -471,18 +471,9 @@ func (c *stubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.
} }
func (c *llndkStubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { func (c *llndkStubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
entries.Class = "SHARED_LIBRARIES" // Don't write anything for an llndk_library module, the vendor variant of the cc_library
entries.OverrideName = c.implementationModuleName(ctx.BaseModuleName()) // module will write the Android.mk entries.
entries.Disabled = true
entries.ExtraEntries = append(entries.ExtraEntries, func(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)
entries.SetString("LOCAL_SOONG_TOC", c.toc().String())
})
} }
func (c *vndkPrebuiltLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { func (c *vndkPrebuiltLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {

View File

@ -390,6 +390,13 @@ type VendorProperties struct {
// explicitly marked as `double_loadable: true` by the owner, or the dependency // explicitly marked as `double_loadable: true` by the owner, or the dependency
// from the LLNDK lib should be cut if the lib is not designed to be double loaded. // from the LLNDK lib should be cut if the lib is not designed to be double loaded.
Double_loadable *bool Double_loadable *bool
// IsLLNDK is set to true for the vendor variant of a cc_library module that has LLNDK stubs.
IsLLNDK bool `blueprint:"mutated"`
// IsLLNDKPrivate is set to true for the vendor variant of a cc_library module that has LLNDK
// stubs and also sets llndk.vendor_available: false.
IsLLNDKPrivate bool `blueprint:"mutated"`
} }
// ModuleContextIntf is an interface (on a module context helper) consisting of functions related // ModuleContextIntf is an interface (on a module context helper) consisting of functions related
@ -408,9 +415,10 @@ type ModuleContextIntf interface {
sdkVersion() string sdkVersion() string
useVndk() bool useVndk() bool
isNdk(config android.Config) bool isNdk(config android.Config) bool
isLlndk(config android.Config) bool IsLlndk() bool
isLlndkPublic(config android.Config) bool IsLlndkPublic() bool
isVndkPrivate(config android.Config) bool isImplementationForLLNDKPublic() bool
IsVndkPrivate() bool
isVndk() bool isVndk() bool
isVndkSp() bool isVndkSp() bool
IsVndkExt() bool IsVndkExt() bool
@ -645,6 +653,7 @@ var (
runtimeDepTag = installDependencyTag{name: "runtime lib"} runtimeDepTag = installDependencyTag{name: "runtime lib"}
testPerSrcDepTag = dependencyTag{name: "test_per_src"} testPerSrcDepTag = dependencyTag{name: "test_per_src"}
stubImplDepTag = dependencyTag{name: "stub_impl"} stubImplDepTag = dependencyTag{name: "stub_impl"}
llndkStubDepTag = dependencyTag{name: "llndk stub"}
) )
type copyDirectlyInAnyApexDependencyTag dependencyTag type copyDirectlyInAnyApexDependencyTag dependencyTag
@ -1028,20 +1037,34 @@ func (c *Module) IsNdk(config android.Config) bool {
return inList(c.BaseModuleName(), *getNDKKnownLibs(config)) return inList(c.BaseModuleName(), *getNDKKnownLibs(config))
} }
func (c *Module) isLlndk(config android.Config) bool { // isLLndk returns true for both LLNDK (public) and LLNDK-private libs.
// Returns true for both LLNDK (public) and LLNDK-private libs. func (c *Module) IsLlndk() bool {
return isLlndkLibrary(c.BaseModuleName(), config) return c.VendorProperties.IsLLNDK
} }
func (c *Module) isLlndkPublic(config android.Config) bool { // IsLlndkPublic returns true only for LLNDK (public) libs.
// Returns true only for LLNDK (public) libs. func (c *Module) IsLlndkPublic() bool {
name := c.BaseModuleName() return c.VendorProperties.IsLLNDK && !c.VendorProperties.IsLLNDKPrivate
return isLlndkLibrary(name, config) && !isVndkPrivateLibrary(name, config)
} }
func (c *Module) IsVndkPrivate(config android.Config) bool { // 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 {
library, _ := c.library.(*libraryDecorator)
return library != nil && library.hasLLNDKStubs() &&
(Bool(library.Properties.Llndk.Vendor_available) ||
// TODO(b/170784825): until the LLNDK properties are moved into the cc_library,
// the non-Vendor variants of the cc_library don't know if the corresponding
// llndk_library set vendor_available: false. Since libft2 is the only
// private LLNDK library, hardcode it during the transition.
c.BaseModuleName() != "libft2")
}
func (c *Module) IsVndkPrivate() bool {
// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private. // Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
return isVndkPrivateLibrary(c.BaseModuleName(), config) library, _ := c.library.(*libraryDecorator)
return library != nil && !Bool(library.Properties.Llndk.Vendor_available) &&
!Bool(c.VendorProperties.Vendor_available) && !c.IsVndkExt()
} }
func (c *Module) IsVndk() bool { func (c *Module) IsVndk() bool {
@ -1247,16 +1270,20 @@ func (ctx *moduleContextImpl) isNdk(config android.Config) bool {
return ctx.mod.IsNdk(config) return ctx.mod.IsNdk(config)
} }
func (ctx *moduleContextImpl) isLlndk(config android.Config) bool { func (ctx *moduleContextImpl) IsLlndk() bool {
return ctx.mod.isLlndk(config) return ctx.mod.IsLlndk()
} }
func (ctx *moduleContextImpl) isLlndkPublic(config android.Config) bool { func (ctx *moduleContextImpl) IsLlndkPublic() bool {
return ctx.mod.isLlndkPublic(config) return ctx.mod.IsLlndkPublic()
} }
func (ctx *moduleContextImpl) isVndkPrivate(config android.Config) bool { func (ctx *moduleContextImpl) isImplementationForLLNDKPublic() bool {
return ctx.mod.IsVndkPrivate(config) return ctx.mod.isImplementationForLLNDKPublic()
}
func (ctx *moduleContextImpl) IsVndkPrivate() bool {
return ctx.mod.IsVndkPrivate()
} }
func (ctx *moduleContextImpl) isVndk() bool { func (ctx *moduleContextImpl) isVndk() bool {
@ -1407,7 +1434,7 @@ func (c *Module) getNameSuffixWithVndkVersion(ctx android.ModuleContext) string
if vndkVersion == "current" { if vndkVersion == "current" {
vndkVersion = ctx.DeviceConfig().PlatformVndkVersion() vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
} }
if c.Properties.VndkVersion != vndkVersion { if c.Properties.VndkVersion != vndkVersion && c.Properties.VndkVersion != "" {
// add version suffix only if the module is using different vndk version than the // add version suffix only if the module is using different vndk version than the
// version in product or vendor partition. // version in product or vendor partition.
nameSuffix += "." + c.Properties.VndkVersion nameSuffix += "." + c.Properties.VndkVersion
@ -1439,7 +1466,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
c.Properties.SubName += nativeBridgeSuffix c.Properties.SubName += nativeBridgeSuffix
} }
_, llndk := c.linker.(*llndkStubDecorator) llndk := c.IsLlndk()
_, llndkHeader := c.linker.(*llndkHeadersDecorator) _, llndkHeader := c.linker.(*llndkHeadersDecorator)
if llndk || llndkHeader || (c.UseVndk() && c.HasNonSystemVariants()) { if llndk || llndkHeader || (c.UseVndk() && c.HasNonSystemVariants()) {
// .vendor.{version} suffix is added for vendor variant or .product.{version} suffix is // .vendor.{version} suffix is added for vendor variant or .product.{version} suffix is
@ -1817,10 +1844,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
vendorSnapshotSharedLibs := vendorSnapshotSharedLibs(actx.Config()) vendorSnapshotSharedLibs := vendorSnapshotSharedLibs(actx.Config())
rewriteVendorLibs := func(lib string) string { rewriteVendorLibs := func(lib string) string {
if isLlndkLibrary(lib, ctx.Config()) {
return lib + llndkLibrarySuffix
}
// only modules with BOARD_VNDK_VERSION uses snapshot. // only modules with BOARD_VNDK_VERSION uses snapshot.
if c.VndkVersion() != actx.DeviceConfig().VndkVersion() { if c.VndkVersion() != actx.DeviceConfig().VndkVersion() {
return lib return lib
@ -2237,7 +2260,7 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
return true return true
} }
if to.isVndkSp() || to.isLlndk(ctx.Config()) || Bool(to.VendorProperties.Double_loadable) { if to.isVndkSp() || to.IsLlndk() || Bool(to.VendorProperties.Double_loadable) {
return false return false
} }
@ -2252,7 +2275,7 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
} }
if module, ok := ctx.Module().(*Module); ok { if module, ok := ctx.Module().(*Module); ok {
if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() { if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() {
if module.isLlndk(ctx.Config()) || Bool(module.VendorProperties.Double_loadable) { if lib.hasLLNDKStubs() || Bool(module.VendorProperties.Double_loadable) {
ctx.WalkDeps(check) ctx.WalkDeps(check)
} }
} }
@ -2372,9 +2395,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if depTag == android.ProtoPluginDepTag { if depTag == android.ProtoPluginDepTag {
return return
} }
if depTag == llndkImplDep {
return
}
if dep.Target().Os != ctx.Os() { if dep.Target().Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
@ -2744,7 +2764,8 @@ func (c *Module) makeLibName(ctx android.ModuleContext, ccDep LinkableInterface,
vendorPublicLibraries := vendorPublicLibraries(ctx.Config()) vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
libName := baseLibName(depName) libName := baseLibName(depName)
isLLndk := isLlndkLibrary(libName, ctx.Config()) ccDepModule, _ := ccDep.(*Module)
isLLndk := ccDepModule != nil && ccDepModule.IsLlndk()
isVendorPublicLib := inList(libName, *vendorPublicLibraries) isVendorPublicLib := inList(libName, *vendorPublicLibraries)
bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk
@ -2896,17 +2917,14 @@ func (c *Module) object() bool {
func GetMakeLinkType(actx android.ModuleContext, c LinkableInterface) string { func GetMakeLinkType(actx android.ModuleContext, c LinkableInterface) string {
if c.UseVndk() { if c.UseVndk() {
if ccModule, ok := c.Module().(*Module); ok { if c.IsLlndk() {
// Only CC modules provide stubs at the moment. if !c.IsLlndkPublic() {
if lib, ok := ccModule.linker.(*llndkStubDecorator); ok {
if Bool(lib.Properties.Vendor_available) {
return "native:vndk"
}
return "native:vndk_private" return "native:vndk_private"
} }
return "native:vndk"
} }
if c.IsVndk() && !c.IsVndkExt() { if c.IsVndk() && !c.IsVndkExt() {
if c.IsVndkPrivate(actx.Config()) { if c.IsVndkPrivate() {
return "native:vndk_private" return "native:vndk_private"
} }
return "native:vndk" return "native:vndk"
@ -3039,7 +3057,7 @@ func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return false return false
} }
} }
if depTag == stubImplDepTag || depTag == llndkImplDep { if depTag == stubImplDepTag || depTag == llndkStubDepTag {
// We don't track beyond LLNDK or from an implementation library to its stubs. // We don't track beyond LLNDK or from an implementation library to its stubs.
return false return false
} }

View File

@ -1049,6 +1049,16 @@ func TestVendorSnapshotCapture(t *testing.T) {
name: "obj", name: "obj",
vendor_available: true, vendor_available: true,
} }
cc_library {
name: "libllndk",
llndk_stubs: "libllndk.llndk",
}
llndk_library {
name: "libllndk.llndk",
symbol_file: "",
}
` `
config := TestConfig(buildDir, android.Android, nil, bp, nil) config := TestConfig(buildDir, android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current") config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
@ -1080,6 +1090,9 @@ func TestVendorSnapshotCapture(t *testing.T) {
filepath.Join(sharedDir, "libvendor.so.json"), filepath.Join(sharedDir, "libvendor.so.json"),
filepath.Join(sharedDir, "libvendor_available.so.json")) filepath.Join(sharedDir, "libvendor_available.so.json"))
// LLNDK modules are not captured
checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant)
// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured. // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
// Also cfi variants are captured, except for prebuilts like toolchain_library // Also cfi variants are captured, except for prebuilts like toolchain_library
staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant) staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
@ -2899,7 +2912,7 @@ func TestMakeLinkType(t *testing.T) {
{vendorVariant, "libvndkprivate", "native:vndk_private"}, {vendorVariant, "libvndkprivate", "native:vndk_private"},
{vendorVariant, "libvendor", "native:vendor"}, {vendorVariant, "libvendor", "native:vendor"},
{vendorVariant, "libvndkext", "native:vendor"}, {vendorVariant, "libvndkext", "native:vendor"},
{vendorVariant, "libllndk.llndk", "native:vndk"}, {vendorVariant, "libllndk", "native:vndk"},
{vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"}, {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
{coreVariant, "libvndk", "native:platform"}, {coreVariant, "libvndk", "native:platform"},
{coreVariant, "libvndkprivate", "native:platform"}, {coreVariant, "libvndkprivate", "native:platform"},
@ -3178,8 +3191,39 @@ func TestLlndkLibrary(t *testing.T) {
llndk_library { llndk_library {
name: "libllndk.llndk", name: "libllndk.llndk",
} }
cc_prebuilt_library_shared {
name: "libllndkprebuilt",
stubs: { versions: ["1", "2"] },
llndk_stubs: "libllndkprebuilt.llndk",
}
llndk_library {
name: "libllndkprebuilt.llndk",
}
cc_library {
name: "libllndk_with_external_headers",
stubs: { versions: ["1", "2"] },
llndk_stubs: "libllndk_with_external_headers.llndk",
header_libs: ["libexternal_headers"],
export_header_lib_headers: ["libexternal_headers"],
}
llndk_library {
name: "libllndk_with_external_headers.llndk",
}
cc_library_headers {
name: "libexternal_headers",
export_include_dirs: ["include"],
vendor_available: true,
}
`) `)
actual := ctx.ModuleVariantsForTests("libllndk.llndk") actual := ctx.ModuleVariantsForTests("libllndk")
for i := 0; i < len(actual); i++ {
if !strings.HasPrefix(actual[i], "android_vendor.VER_") {
actual = append(actual[:i], actual[i+1:]...)
i--
}
}
expected := []string{ expected := []string{
"android_vendor.VER_arm64_armv8-a_shared_1", "android_vendor.VER_arm64_armv8-a_shared_1",
"android_vendor.VER_arm64_armv8-a_shared_2", "android_vendor.VER_arm64_armv8-a_shared_2",
@ -3190,10 +3234,10 @@ func TestLlndkLibrary(t *testing.T) {
} }
checkEquals(t, "variants for llndk stubs", expected, actual) checkEquals(t, "variants for llndk stubs", expected, actual)
params := ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared").Description("generate stub") params := ctx.ModuleForTests("libllndk", "android_vendor.VER_arm_armv7-a-neon_shared").Description("generate stub")
checkEquals(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"]) checkEquals(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
params = ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared_1").Description("generate stub") params = ctx.ModuleForTests("libllndk", "android_vendor.VER_arm_armv7-a-neon_shared_1").Description("generate stub")
checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"]) checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
} }

View File

@ -308,6 +308,18 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
} else { } else {
vendorVariants = append(vendorVariants, platformVndkVersion) vendorVariants = append(vendorVariants, platformVndkVersion)
} }
} else if lib := moduleLibraryInterface(m); lib != nil && lib.hasLLNDKStubs() {
// This is an LLNDK library. The implementation of the library will be on /system,
// and vendor and product variants will be created with LLNDK stubs.
coreVariantNeeded = true
vendorVariants = append(vendorVariants,
platformVndkVersion,
boardVndkVersion,
)
productVariants = append(productVariants,
platformVndkVersion,
productVndkVersion,
)
} else { } else {
// This is either in /system (or similar: /data), or is a // This is either in /system (or similar: /data), or is a
// modules built with the NDK. Modules built with the NDK // modules built with the NDK. Modules built with the NDK

View File

@ -22,6 +22,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools" "github.com/google/blueprint/pathtools"
"android/soong/android" "android/soong/android"
@ -114,6 +115,10 @@ type LibraryProperties struct {
// If this is an LLNDK library, the name of the equivalent llndk_library module. // If this is an LLNDK library, the name of the equivalent llndk_library module.
Llndk_stubs *string Llndk_stubs *string
// 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
} }
// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a // StaticProperties is a properties stanza to affect only attributes of the "static" variants of a
@ -570,6 +575,12 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, d
} }
flags = library.baseCompiler.compilerFlags(ctx, flags, deps) flags = library.baseCompiler.compilerFlags(ctx, flags, deps)
if ctx.IsLlndk() {
// LLNDK libraries ignore most of the properties on the cc_library and use the
// LLNDK-specific properties instead.
// Wipe all the module-local properties, leaving only the global properties.
flags.Local = LocalOrGlobalFlags{}
}
if library.buildStubs() { if library.buildStubs() {
// Remove -include <file> when compiling stubs. Otherwise, the force included // Remove -include <file> when compiling stubs. Otherwise, the force included
// headers might cause conflicting types error with the symbols in the // headers might cause conflicting types error with the symbols in the
@ -603,6 +614,22 @@ func (library *libraryDecorator) headerAbiCheckerExplicitlyDisabled() bool {
} }
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
if ctx.IsLlndk() {
// This is the vendor variant of an LLNDK library, build the LLNDK stubs.
vndkVer := ctx.Module().(*Module).VndkVersion()
if !inList(vndkVer, ctx.Config().PlatformVersionActiveCodenames()) || vndkVer == "" {
// For non-enforcing devices, vndkVer is empty. Use "current" in that case, too.
vndkVer = "current"
}
if library.stubsVersion() != "" {
vndkVer = library.stubsVersion()
}
objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Llndk.Symbol_file), vndkVer, "--llndk")
if !Bool(library.Properties.Llndk.Unversioned) {
library.versionScriptPath = android.OptionalPathForPath(versionScript)
}
return objs
}
if library.buildStubs() { if library.buildStubs() {
objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "--apex") objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "--apex")
library.versionScriptPath = android.OptionalPathForPath(versionScript) library.versionScriptPath = android.OptionalPathForPath(versionScript)
@ -693,6 +720,7 @@ type versionedInterface interface {
allStubsVersions() []string allStubsVersions() []string
implementationModuleName(name string) string implementationModuleName(name string) string
hasLLNDKStubs() bool
} }
var _ libraryInterface = (*libraryDecorator)(nil) var _ libraryInterface = (*libraryDecorator)(nil)
@ -768,12 +796,27 @@ func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
} }
func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
if ctx.IsLlndk() {
// LLNDK libraries ignore most of the properties on the cc_library and use the
// LLNDK-specific properties instead.
return deps
}
deps = library.baseCompiler.compilerDeps(ctx, deps) deps = library.baseCompiler.compilerDeps(ctx, deps)
return deps return deps
} }
func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
if ctx.IsLlndk() {
// LLNDK libraries ignore most of the properties on the cc_library and use the
// LLNDK-specific properties instead.
deps.HeaderLibs = append(deps.HeaderLibs, library.Properties.Llndk.Export_llndk_headers...)
deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders,
library.Properties.Llndk.Export_llndk_headers...)
return deps
}
if library.static() { if library.static() {
// Compare with nil because an empty list needs to be propagated. // Compare with nil because an empty list needs to be propagated.
if library.StaticProperties.Static.System_shared_libs != nil { if library.StaticProperties.Static.System_shared_libs != nil {
@ -1022,7 +1065,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...) linkerDeps = append(linkerDeps, objs.tidyFiles...)
if Bool(library.Properties.Sort_bss_symbols_by_size) { if Bool(library.Properties.Sort_bss_symbols_by_size) && !library.buildStubs() {
unsortedOutputFile := android.PathForModuleOut(ctx, "unsorted", fileName) unsortedOutputFile := android.PathForModuleOut(ctx, "unsorted", fileName)
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
@ -1076,7 +1119,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{ ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{
SharedStubLibraries: stubsInfo, SharedStubLibraries: stubsInfo,
IsLLNDK: ctx.isLlndk(ctx.Config()), IsLLNDK: ctx.IsLlndk(),
}) })
} }
@ -1105,7 +1148,7 @@ func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath {
func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path { func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
// The logic must be consistent with classifySourceAbiDump. // The logic must be consistent with classifySourceAbiDump.
isNdk := ctx.isNdk(ctx.Config()) isNdk := ctx.isNdk(ctx.Config())
isLlndkOrVndk := ctx.isLlndkPublic(ctx.Config()) || (ctx.useVndk() && ctx.isVndk()) isLlndkOrVndk := ctx.IsLlndkPublic() || (ctx.useVndk() && ctx.isVndk())
refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false) refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false)
refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true) refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true)
@ -1158,17 +1201,64 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(), library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
refAbiDumpFile, fileName, exportedHeaderFlags, refAbiDumpFile, fileName, exportedHeaderFlags,
Bool(library.Properties.Header_abi_checker.Check_all_apis), Bool(library.Properties.Header_abi_checker.Check_all_apis),
ctx.isLlndk(ctx.Config()), ctx.isNdk(ctx.Config()), ctx.IsVndkExt()) ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt())
} }
} }
} }
func processLLNDKHeaders(ctx ModuleContext, srcHeaderDir string, outDir android.ModuleGenPath) android.Path {
srcDir := android.PathForModuleSrc(ctx, srcHeaderDir)
srcFiles := ctx.GlobFiles(filepath.Join(srcDir.String(), "**/*.h"), nil)
var installPaths []android.WritablePath
for _, header := range srcFiles {
headerDir := filepath.Dir(header.String())
relHeaderDir, err := filepath.Rel(srcDir.String(), headerDir)
if err != nil {
ctx.ModuleErrorf("filepath.Rel(%q, %q) failed: %s",
srcDir.String(), headerDir, err)
continue
}
installPaths = append(installPaths, outDir.Join(ctx, relHeaderDir, header.Base()))
}
return processHeadersWithVersioner(ctx, srcDir, outDir, srcFiles, installPaths)
}
// link registers actions to link this library, and sets various fields // link registers actions to link this library, and sets various fields
// on this library to reflect information that should be exported up the build // on this library to reflect information that should be exported up the build
// tree (for example, exported flags and include paths). // tree (for example, exported flags and include paths).
func (library *libraryDecorator) link(ctx ModuleContext, func (library *libraryDecorator) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path { flags Flags, deps PathDeps, objs Objects) android.Path {
if ctx.IsLlndk() {
if len(library.Properties.Llndk.Export_preprocessed_headers) > 0 {
// This is the vendor variant of an LLNDK library with preprocessed headers.
genHeaderOutDir := android.PathForModuleGen(ctx, "include")
var timestampFiles android.Paths
for _, dir := range library.Properties.Llndk.Export_preprocessed_headers {
timestampFiles = append(timestampFiles, processLLNDKHeaders(ctx, dir, genHeaderOutDir))
}
if Bool(library.Properties.Llndk.Export_headers_as_system) {
library.reexportSystemDirs(genHeaderOutDir)
} else {
library.reexportDirs(genHeaderOutDir)
}
library.reexportDeps(timestampFiles...)
}
if Bool(library.Properties.Llndk.Export_headers_as_system) {
library.flagExporter.Properties.Export_system_include_dirs = append(
library.flagExporter.Properties.Export_system_include_dirs,
library.flagExporter.Properties.Export_include_dirs...)
library.flagExporter.Properties.Export_include_dirs = nil
}
}
// Linking this library consists of linking `deps.Objs` (.o files in dependencies // Linking this library consists of linking `deps.Objs` (.o files in dependencies
// of this library), together with `objs` (.o files created by compiling this // of this library), together with `objs` (.o files created by compiling this
// library). // library).
@ -1251,7 +1341,7 @@ func (library *libraryDecorator) link(ctx ModuleContext,
} }
func (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) { func (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) {
if library.buildStubs() && !library.skipAPIDefine { if library.buildStubs() && library.stubsVersion() != "" && !library.skipAPIDefine {
name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx)) name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx))
ver := library.stubsVersion() ver := library.stubsVersion()
library.reexportFlags("-D" + name + "=" + ver) library.reexportFlags("-D" + name + "=" + ver)
@ -1339,7 +1429,7 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
} }
library.baseInstaller.subDir = "bootstrap" library.baseInstaller.subDir = "bootstrap"
} }
} else if ctx.directlyInAnyApex() && ctx.isLlndk(ctx.Config()) && !isBionic(ctx.baseModuleName()) { } else if ctx.directlyInAnyApex() && ctx.IsLlndk() && !isBionic(ctx.baseModuleName()) {
// Skip installing LLNDK (non-bionic) libraries moved to APEX. // Skip installing LLNDK (non-bionic) libraries moved to APEX.
ctx.Module().HideFromMake() ctx.Module().HideFromMake()
} }
@ -1416,6 +1506,11 @@ func (library *libraryDecorator) HeaderOnly() {
library.MutatedProperties.BuildStatic = false library.MutatedProperties.BuildStatic = false
} }
// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
func (library *libraryDecorator) hasLLNDKStubs() bool {
return String(library.Properties.Llndk_stubs) != ""
}
func (library *libraryDecorator) implementationModuleName(name string) string { func (library *libraryDecorator) implementationModuleName(name string) string {
return name return name
} }
@ -1428,6 +1523,9 @@ func (library *libraryDecorator) symbolFileForAbiCheck(ctx ModuleContext) *strin
if library.Properties.Header_abi_checker.Symbol_file != nil { if library.Properties.Header_abi_checker.Symbol_file != nil {
return library.Properties.Header_abi_checker.Symbol_file return library.Properties.Header_abi_checker.Symbol_file
} }
if ctx.Module().(*Module).IsLlndk() {
return library.Properties.Llndk.Symbol_file
}
if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil { if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
return library.Properties.Stubs.Symbol_file return library.Properties.Stubs.Symbol_file
} }
@ -1592,7 +1690,9 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface) library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface)
// Differentiate between header only and building an actual static/shared library // Differentiate between header only and building an actual static/shared library
if library.buildStatic() || library.buildShared() { buildStatic := library.buildStatic()
buildShared := library.buildShared()
if buildStatic || buildShared {
// Always create both the static and shared variants for prebuilt libraries, and then disable the one // Always create both the static and shared variants for prebuilt libraries, and then disable the one
// that is not being used. This allows them to share the name of a cc_library module, which requires that // that is not being used. This allows them to share the name of a cc_library module, which requires that
// all the variants of the cc_library also exist on the prebuilt. // all the variants of the cc_library also exist on the prebuilt.
@ -1603,16 +1703,16 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
static.linker.(prebuiltLibraryInterface).setStatic() static.linker.(prebuiltLibraryInterface).setStatic()
shared.linker.(prebuiltLibraryInterface).setShared() shared.linker.(prebuiltLibraryInterface).setShared()
if library.buildShared() { if buildShared {
mctx.AliasVariation("shared") mctx.AliasVariation("shared")
} else if library.buildStatic() { } else if buildStatic {
mctx.AliasVariation("static") mctx.AliasVariation("static")
} }
if !library.buildStatic() { if !buildStatic {
static.linker.(prebuiltLibraryInterface).disablePrebuilt() static.linker.(prebuiltLibraryInterface).disablePrebuilt()
} }
if !library.buildShared() { if !buildShared {
shared.linker.(prebuiltLibraryInterface).disablePrebuilt() shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
} }
} else { } else {
@ -1627,7 +1727,18 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
variations = append(variations, "") variations = append(variations, "")
} }
if library.BuildStaticVariant() && library.BuildSharedVariant() { isLLNDK := false
if m, ok := mctx.Module().(*Module); ok {
isLLNDK = m.IsLlndk()
// Don't count the vestigial llndk_library module as isLLNDK, it needs a static
// variant so that a cc_library_prebuilt can depend on it.
if _, ok := m.linker.(*llndkStubDecorator); ok {
isLLNDK = false
}
}
buildStatic := library.BuildStaticVariant() && !isLLNDK
buildShared := library.BuildSharedVariant()
if buildStatic && buildShared {
variations := append([]string{"static", "shared"}, variations...) variations := append([]string{"static", "shared"}, variations...)
modules := mctx.CreateLocalVariations(variations...) modules := mctx.CreateLocalVariations(variations...)
@ -1641,13 +1752,13 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
reuseStaticLibrary(mctx, static.(*Module), shared.(*Module)) reuseStaticLibrary(mctx, static.(*Module), shared.(*Module))
} }
mctx.AliasVariation("shared") mctx.AliasVariation("shared")
} else if library.BuildStaticVariant() { } else if buildStatic {
variations := append([]string{"static"}, variations...) variations := append([]string{"static"}, variations...)
modules := mctx.CreateLocalVariations(variations...) modules := mctx.CreateLocalVariations(variations...)
modules[0].(LinkableInterface).SetStatic() modules[0].(LinkableInterface).SetStatic()
mctx.AliasVariation("static") mctx.AliasVariation("static")
} else if library.BuildSharedVariant() { } else if buildShared {
variations := append([]string{"shared"}, variations...) variations := append([]string{"shared"}, variations...)
modules := mctx.CreateLocalVariations(variations...) modules := mctx.CreateLocalVariations(variations...)
@ -1680,24 +1791,34 @@ func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
} }
func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) { func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
// "" is for the non-stubs (implementation) variant. // "" is for the non-stubs (implementation) variant for system modules, or the LLNDK variant
// for LLNDK modules.
variants := append(android.CopyOf(versions), "") variants := append(android.CopyOf(versions), "")
m := mctx.Module().(*Module)
isLLNDK := m.IsLlndk()
modules := mctx.CreateLocalVariations(variants...) modules := mctx.CreateLocalVariations(variants...)
for i, m := range modules { for i, m := range modules {
if variants[i] != "" {
if variants[i] != "" || isLLNDK {
// A stubs or LLNDK stubs variant.
c := m.(*Module) c := m.(*Module)
c.Properties.HideFromMake = true
c.sanitize = nil c.sanitize = nil
c.stl = nil c.stl = nil
c.Properties.PreventInstall = true c.Properties.PreventInstall = true
lib := moduleLibraryInterface(m) lib := moduleLibraryInterface(m)
lib.setBuildStubs() lib.setBuildStubs()
if variants[i] != "" {
// A non-LLNDK stubs module is hidden from make and has a dependency from the
// implementation module to the stubs module.
c.Properties.HideFromMake = true
lib.setStubsVersion(variants[i]) lib.setStubsVersion(variants[i])
// The implementation depends on the stubs
mctx.AddInterVariantDependency(stubImplDepTag, modules[len(modules)-1], modules[i]) mctx.AddInterVariantDependency(stubImplDepTag, modules[len(modules)-1], modules[i])
} }
} }
}
mctx.AliasVariation("") mctx.AliasVariation("")
latestVersion := "" latestVersion := ""
if len(versions) > 0 { if len(versions) > 0 {
@ -1742,7 +1863,7 @@ func CanBeVersionVariant(module interface {
module.CcLibraryInterface() && module.Shared() module.CcLibraryInterface() && module.Shared()
} }
func moduleLibraryInterface(module android.Module) libraryInterface { func moduleLibraryInterface(module blueprint.Module) libraryInterface {
if m, ok := module.(*Module); ok { if m, ok := module.(*Module); ok {
return m.library return m.library
} }
@ -1763,7 +1884,15 @@ func versionSelectorMutator(mctx android.BottomUpMutatorContext) {
// Set the versions on the pre-mutated module so they can be read by any llndk modules that // Set the versions on the pre-mutated module so they can be read by any llndk modules that
// depend on the implementation library and haven't been mutated yet. // depend on the implementation library and haven't been mutated yet.
library.setAllStubsVersions(versions) library.setAllStubsVersions(versions)
return }
if mctx.Module().(*Module).UseVndk() && library.hasLLNDKStubs() {
// Propagate the version to the llndk stubs module.
mctx.VisitDirectDepsWithTag(llndkStubDepTag, func(stubs android.Module) {
if stubsLib := moduleLibraryInterface(stubs); stubsLib != nil {
stubsLib.setAllStubsVersions(library.allStubsVersions())
}
})
} }
} }
} }

View File

@ -43,9 +43,11 @@ type LinkableInterface interface {
UseSdk() bool UseSdk() bool
UseVndk() bool UseVndk() bool
MustUseVendorVariant() bool MustUseVendorVariant() bool
IsLlndk() bool
IsLlndkPublic() bool
IsVndk() bool IsVndk() bool
IsVndkExt() bool IsVndkExt() bool
IsVndkPrivate(config android.Config) bool IsVndkPrivate() bool
HasVendorVariant() bool HasVendorVariant() bool
InProduct() bool InProduct() bool

View File

@ -15,21 +15,21 @@
package cc package cc
import ( import (
"fmt"
"path/filepath"
"strings" "strings"
"android/soong/android" "android/soong/android"
) )
var llndkImplDep = dependencyTag{name: "llndk impl"}
var ( var (
llndkLibrarySuffix = ".llndk" llndkLibrarySuffix = ".llndk"
llndkHeadersSuffix = ".llndk" llndkHeadersSuffix = ".llndk"
) )
// Creates a stub shared library based on the provided version file. // Holds properties to describe a stub shared library based on the provided version file.
// The stub library will actually be built by the cc_library module that points to this
// module with the llndk_stubs property.
// TODO(ccross): move the properties from llndk_library modules directly into the cc_library
// modules and remove the llndk_library modules.
// //
// Example: // Example:
// //
@ -64,43 +64,32 @@ type llndkLibraryProperties struct {
// list of llndk headers to re-export include directories from. // list of llndk headers to re-export include directories from.
Export_llndk_headers []string `android:"arch_variant"` Export_llndk_headers []string `android:"arch_variant"`
// whether this module can be directly depended upon by libs that are installed
// to /vendor and /product.
// When set to true, this module can only be depended on by VNDK libraries, not
// vendor nor product libraries. This effectively hides this module from
// non-system modules. Default value is false.
Private *bool
} }
type llndkStubDecorator struct { type llndkStubDecorator struct {
*libraryDecorator *libraryDecorator
Properties llndkLibraryProperties Properties llndkLibraryProperties
movedToApex bool
} }
var _ versionedInterface = (*llndkStubDecorator)(nil) var _ versionedInterface = (*llndkStubDecorator)(nil)
func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags { func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
flags = stub.baseCompiler.compilerFlags(ctx, flags, deps) return flags
return addStubLibraryCompilerFlags(flags)
} }
func (stub *llndkStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { func (stub *llndkStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
vndkVer := ctx.Module().(*Module).VndkVersion() return Objects{}
if !inList(vndkVer, ctx.Config().PlatformVersionActiveCodenames()) || vndkVer == "" {
// For non-enforcing devices, vndkVer is empty. Use "current" in that case, too.
vndkVer = "current"
}
if stub.stubsVersion() != "" {
vndkVer = stub.stubsVersion()
}
objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), vndkVer, "--llndk")
if !Bool(stub.Properties.Unversioned) {
stub.versionScriptPath = android.OptionalPathForPath(versionScript)
}
return objs
} }
func (stub *llndkStubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { func (stub *llndkStubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
headers := addSuffix(stub.Properties.Export_llndk_headers, llndkHeadersSuffix)
deps.HeaderLibs = append(deps.HeaderLibs, headers...)
deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, headers...)
return deps return deps
} }
@ -116,57 +105,9 @@ func (stub *llndkStubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flag
return stub.libraryDecorator.linkerFlags(ctx, flags) return stub.libraryDecorator.linkerFlags(ctx, flags)
} }
func (stub *llndkStubDecorator) processHeaders(ctx ModuleContext, srcHeaderDir string, outDir android.ModuleGenPath) android.Path {
srcDir := android.PathForModuleSrc(ctx, srcHeaderDir)
srcFiles := ctx.GlobFiles(filepath.Join(srcDir.String(), "**/*.h"), nil)
var installPaths []android.WritablePath
for _, header := range srcFiles {
headerDir := filepath.Dir(header.String())
relHeaderDir, err := filepath.Rel(srcDir.String(), headerDir)
if err != nil {
ctx.ModuleErrorf("filepath.Rel(%q, %q) failed: %s",
srcDir.String(), headerDir, err)
continue
}
installPaths = append(installPaths, outDir.Join(ctx, relHeaderDir, header.Base()))
}
return processHeadersWithVersioner(ctx, srcDir, outDir, srcFiles, installPaths)
}
func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
objs Objects) android.Path { objs Objects) android.Path {
return nil
impl := ctx.GetDirectDepWithTag(stub.implementationModuleName(ctx.ModuleName()), llndkImplDep)
if implApexModule, ok := impl.(android.ApexModule); ok {
stub.movedToApex = implApexModule.DirectlyInAnyApex()
}
if len(stub.Properties.Export_preprocessed_headers) > 0 {
genHeaderOutDir := android.PathForModuleGen(ctx, "include")
var timestampFiles android.Paths
for _, dir := range stub.Properties.Export_preprocessed_headers {
timestampFiles = append(timestampFiles, stub.processHeaders(ctx, dir, genHeaderOutDir))
}
if Bool(stub.Properties.Export_headers_as_system) {
stub.reexportSystemDirs(genHeaderOutDir)
} else {
stub.reexportDirs(genHeaderOutDir)
}
stub.reexportDeps(timestampFiles...)
}
if Bool(stub.Properties.Export_headers_as_system) {
stub.exportIncludesAsSystem(ctx)
stub.libraryDecorator.flagExporter.Properties.Export_include_dirs = []string{}
}
return stub.libraryDecorator.link(ctx, flags, deps, objs)
} }
func (stub *llndkStubDecorator) nativeCoverage() bool { func (stub *llndkStubDecorator) nativeCoverage() bool {
@ -181,20 +122,8 @@ func (stub *llndkStubDecorator) buildStubs() bool {
return true return true
} }
func (stub *llndkStubDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
// Get the versions from the implementation module.
impls := ctx.GetDirectDepsWithTag(llndkImplDep)
if len(impls) > 1 {
panic(fmt.Errorf("Expected single implmenetation library, got %d", len(impls)))
} else if len(impls) == 1 {
return moduleLibraryInterface(impls[0]).allStubsVersions()
}
return nil
}
func NewLLndkStubLibrary() *Module { func NewLLndkStubLibrary() *Module {
module, library := NewLibrary(android.DeviceSupported) module, library := NewLibrary(android.DeviceSupported)
library.BuildOnlyShared()
module.stl = nil module.stl = nil
module.sanitize = nil module.sanitize = nil
library.disableStripping() library.disableStripping()
@ -235,10 +164,6 @@ type llndkHeadersDecorator struct {
*libraryDecorator *libraryDecorator
} }
func (headers *llndkHeadersDecorator) Name(name string) string {
return name + llndkHeadersSuffix
}
// llndk_headers contains a set of c/c++ llndk headers files which are imported // llndk_headers contains a set of c/c++ llndk headers files which are imported
// by other soongs cc modules. // by other soongs cc modules.
func llndkHeadersFactory() android.Module { func llndkHeadersFactory() android.Module {

View File

@ -80,10 +80,10 @@ func classifySourceAbiDump(ctx android.BaseModuleContext) string {
if m.IsNdk(ctx.Config()) { if m.IsNdk(ctx.Config()) {
return "NDK" return "NDK"
} }
if m.isLlndkPublic(ctx.Config()) { if m.isImplementationForLLNDKPublic() {
return "LLNDK" return "LLNDK"
} }
if m.UseVndk() && m.IsVndk() && !m.IsVndkPrivate(ctx.Config()) { if m.UseVndk() && m.IsVndk() && !m.IsVndkPrivate() {
if m.isVndkSp() { if m.isVndkSp() {
if m.IsVndkExt() { if m.IsVndkExt() {
return "VNDK-SP-ext" return "VNDK-SP-ext"
@ -156,7 +156,7 @@ func shouldCreateSourceAbiDumpForLibrary(ctx android.BaseModuleContext) bool {
} }
// Don't create ABI dump for stubs. // Don't create ABI dump for stubs.
if m.isNDKStubLibrary() || m.IsStubs() { if m.isNDKStubLibrary() || m.IsLlndk() || m.IsStubs() {
return false return false
} }

View File

@ -1002,9 +1002,6 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
if runtimeLibrary != "" && (toolchain.Bionic() || c.sanitize.Properties.UbsanRuntimeDep) { if runtimeLibrary != "" && (toolchain.Bionic() || c.sanitize.Properties.UbsanRuntimeDep) {
// UBSan is supported on non-bionic linux host builds as well // UBSan is supported on non-bionic linux host builds as well
if isLlndkLibrary(runtimeLibrary, mctx.Config()) && !c.static() && c.UseVndk() {
runtimeLibrary = runtimeLibrary + llndkLibrarySuffix
}
// Adding dependency to the runtime library. We are using *FarVariation* // Adding dependency to the runtime library. We are using *FarVariation*
// because the runtime libraries themselves are not mutated by sanitizer // because the runtime libraries themselves are not mutated by sanitizer

View File

@ -805,7 +805,7 @@ func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
} }
// .. and also filter out llndk library // .. and also filter out llndk library
if module.isLlndk(ctx.Config()) { if module.IsLlndk() {
return return
} }

View File

@ -210,6 +210,9 @@ func isSnapshotAware(m *Module, inProprietaryPath bool, apexInfo android.ApexInf
return false return false
} }
// skip llndk_library and llndk_headers which are backward compatible // skip llndk_library and llndk_headers which are backward compatible
if m.IsLlndk() {
return false
}
if _, ok := m.linker.(*llndkStubDecorator); ok { if _, ok := m.linker.(*llndkStubDecorator); ok {
return false return false
} }

View File

@ -156,9 +156,15 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.BaseModuleContext, to *Module
} }
if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() { if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
// Check only shared libraries. // Check only shared libraries.
// Other (static and LL-NDK) libraries are allowed to link. // Other (static) libraries are allowed to link.
return return
} }
if to.IsLlndk() {
// LL-NDK libraries are allowed to link
return
}
if !to.UseVndk() { if !to.UseVndk() {
ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library", ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
vndk.typeName(), to.Name()) vndk.typeName(), to.Name())
@ -250,22 +256,12 @@ func vndkSpLibraries(config android.Config) map[string]string {
}).(map[string]string) }).(map[string]string)
} }
func isLlndkLibrary(baseModuleName string, config android.Config) bool {
_, ok := llndkLibraries(config)[strings.TrimSuffix(baseModuleName, llndkLibrarySuffix)]
return ok
}
func llndkLibraries(config android.Config) map[string]string { func llndkLibraries(config android.Config) map[string]string {
return config.Once(llndkLibrariesKey, func() interface{} { return config.Once(llndkLibrariesKey, func() interface{} {
return make(map[string]string) return make(map[string]string)
}).(map[string]string) }).(map[string]string)
} }
func isVndkPrivateLibrary(baseModuleName string, config android.Config) bool {
_, ok := vndkPrivateLibraries(config)[baseModuleName]
return ok
}
func vndkPrivateLibraries(config android.Config) map[string]string { func vndkPrivateLibraries(config android.Config) map[string]string {
return config.Once(vndkPrivateLibrariesKey, func() interface{} { return config.Once(vndkPrivateLibrariesKey, func() interface{} {
return make(map[string]string) return make(map[string]string)
@ -301,12 +297,10 @@ func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
defer vndkLibrariesLock.Unlock() defer vndkLibrariesLock.Unlock()
llndkLibraries(mctx.Config())[name] = filename llndkLibraries(mctx.Config())[name] = filename
m.VendorProperties.IsLLNDK = true
if !Bool(lib.Properties.Vendor_available) { if !Bool(lib.Properties.Vendor_available) {
vndkPrivateLibraries(mctx.Config())[name] = filename vndkPrivateLibraries(mctx.Config())[name] = filename
} m.VendorProperties.IsLLNDKPrivate = true
if mctx.OtherModuleExists(name) {
mctx.AddFarVariationDependencies(m.Target().Variations(), llndkImplDep, name)
} }
} }
@ -410,9 +404,31 @@ func VndkMutator(mctx android.BottomUpMutatorContext) {
return return
} }
// This is a temporary measure to copy the properties from an llndk_library into the cc_library
// that will actually build the stubs. It will be removed once the properties are moved into
// the cc_library in the Android.bp files.
mergeLLNDKToLib := func(llndk *Module, llndkProperties *llndkLibraryProperties, flagExporter *flagExporter) {
if llndkLib := moduleLibraryInterface(llndk); llndkLib != nil {
*llndkProperties = llndkLib.(*llndkStubDecorator).Properties
flagExporter.Properties = llndkLib.(*llndkStubDecorator).flagExporter.Properties
m.VendorProperties.IsLLNDK = llndk.VendorProperties.IsLLNDK
m.VendorProperties.IsLLNDKPrivate = llndk.VendorProperties.IsLLNDKPrivate
}
}
lib, is_lib := m.linker.(*libraryDecorator) lib, is_lib := m.linker.(*libraryDecorator)
prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker) prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
if m.UseVndk() && is_lib && lib.hasLLNDKStubs() {
llndk := mctx.AddVariationDependencies(nil, llndkStubDepTag, String(lib.Properties.Llndk_stubs))
mergeLLNDKToLib(llndk[0].(*Module), &lib.Properties.Llndk, &lib.flagExporter)
}
if m.UseVndk() && is_prebuilt_lib && prebuilt_lib.hasLLNDKStubs() {
llndk := mctx.AddVariationDependencies(nil, llndkStubDepTag, String(prebuilt_lib.Properties.Llndk_stubs))
mergeLLNDKToLib(llndk[0].(*Module), &prebuilt_lib.Properties.Llndk, &prebuilt_lib.flagExporter)
}
if (is_lib && lib.buildShared()) || (is_prebuilt_lib && prebuilt_lib.buildShared()) { if (is_lib && lib.buildShared()) || (is_prebuilt_lib && prebuilt_lib.buildShared()) {
if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() { if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
processVndkLibrary(mctx, m) processVndkLibrary(mctx, m)
@ -819,15 +835,13 @@ func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
// they been moved to an apex. // they been moved to an apex.
movedToApexLlndkLibraries := make(map[string]bool) movedToApexLlndkLibraries := make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) { ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(*Module); ok { if library := moduleLibraryInterface(module); library != nil && library.hasLLNDKStubs() {
if llndk, ok := m.linker.(*llndkStubDecorator); ok {
// Skip bionic libs, they are handled in different manner // Skip bionic libs, they are handled in different manner
name := llndk.implementationModuleName(m.BaseModuleName()) name := library.implementationModuleName(module.(*Module).BaseModuleName())
if llndk.movedToApex && !isBionic(name) { if module.(android.ApexModule).DirectlyInAnyApex() && !isBionic(name) {
movedToApexLlndkLibraries[name] = true movedToApexLlndkLibraries[name] = true
} }
} }
}
}) })
ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",

View File

@ -189,7 +189,15 @@ func (mod *Module) IsVndkExt() bool {
return false return false
} }
func (c *Module) IsVndkPrivate(config android.Config) bool { func (c *Module) IsVndkPrivate() bool {
return false
}
func (c *Module) IsLlndk() bool {
return false
}
func (c *Module) IsLlndkPublic() bool {
return false return false
} }