Merge "CcApiLibrary Variants for LLNDK"
This commit is contained in:
2
cc/cc.go
2
cc/cc.go
@@ -2540,6 +2540,8 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||
}, vndkExtDepTag, GetReplaceModuleName(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs))
|
||||
}
|
||||
}
|
||||
|
||||
updateImportedLibraryDependency(ctx)
|
||||
}
|
||||
|
||||
func BeginMutator(ctx android.BottomUpMutatorContext) {
|
||||
|
@@ -2597,11 +2597,12 @@ func createVersionVariations(mctx android.BottomUpMutatorContext, versions []str
|
||||
m := mctx.Module().(*Module)
|
||||
isLLNDK := m.IsLlndk()
|
||||
isVendorPublicLibrary := m.IsVendorPublicLibrary()
|
||||
isImportedApiLibrary := m.isImportedApiLibrary()
|
||||
|
||||
modules := mctx.CreateLocalVariations(variants...)
|
||||
for i, m := range modules {
|
||||
|
||||
if variants[i] != "" || isLLNDK || isVendorPublicLibrary {
|
||||
if variants[i] != "" || isLLNDK || isVendorPublicLibrary || isImportedApiLibrary {
|
||||
// A stubs or LLNDK stubs variant.
|
||||
c := m.(*Module)
|
||||
c.sanitize = nil
|
||||
|
@@ -15,6 +15,10 @@
|
||||
package cc
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint/proptools"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/multitree"
|
||||
)
|
||||
@@ -26,6 +30,30 @@ func init() {
|
||||
func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) {
|
||||
ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory)
|
||||
ctx.RegisterModuleType("cc_api_headers", CcApiHeadersFactory)
|
||||
ctx.RegisterModuleType("cc_api_variant", CcApiVariantFactory)
|
||||
}
|
||||
|
||||
func updateImportedLibraryDependency(ctx android.BottomUpMutatorContext) {
|
||||
m, ok := ctx.Module().(*Module)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
apiLibrary, ok := m.linker.(*apiLibraryDecorator)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if m.UseVndk() && apiLibrary.hasLLNDKStubs() {
|
||||
// Add LLNDK dependencies
|
||||
for _, variant := range apiLibrary.properties.Variants {
|
||||
if variant == "llndk" {
|
||||
variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
|
||||
ctx.AddDependency(m, nil, variantName)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 'cc_api_library' is a module type which is from the exported API surface
|
||||
@@ -33,7 +61,8 @@ func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) {
|
||||
// offer a link to the module that generates shared library object from the
|
||||
// map file.
|
||||
type apiLibraryProperties struct {
|
||||
Src *string `android:"arch_variant"`
|
||||
Src *string `android:"arch_variant"`
|
||||
Variants []string
|
||||
}
|
||||
|
||||
type apiLibraryDecorator struct {
|
||||
@@ -55,11 +84,9 @@ func CcApiLibraryFactory() android.Module {
|
||||
module.compiler = nil
|
||||
module.linker = apiLibraryDecorator
|
||||
module.installer = nil
|
||||
module.library = apiLibraryDecorator
|
||||
module.AddProperties(&module.Properties, &apiLibraryDecorator.properties)
|
||||
|
||||
// Mark module as stub, so APEX would not include this stub in the package.
|
||||
module.library.setBuildStubs(true)
|
||||
|
||||
// Prevent default system libs (libc, libm, and libdl) from being linked
|
||||
if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil {
|
||||
apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{}
|
||||
@@ -91,12 +118,45 @@ func (d *apiLibraryDecorator) exportIncludes(ctx ModuleContext) {
|
||||
}
|
||||
|
||||
func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
|
||||
// Export headers as system include dirs if specified. Mostly for libc
|
||||
if Bool(d.libraryDecorator.Properties.Llndk.Export_headers_as_system) {
|
||||
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append(
|
||||
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs,
|
||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs...)
|
||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = nil
|
||||
m, _ := ctx.Module().(*Module)
|
||||
|
||||
var in android.Path
|
||||
|
||||
if src := proptools.String(d.properties.Src); src != "" {
|
||||
in = android.PathForModuleSrc(ctx, src)
|
||||
}
|
||||
|
||||
// LLNDK variant
|
||||
if m.UseVndk() && d.hasLLNDKStubs() {
|
||||
apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
|
||||
|
||||
var mod android.Module
|
||||
|
||||
ctx.VisitDirectDeps(func(depMod android.Module) {
|
||||
if depMod.Name() == apiVariantModule {
|
||||
mod = depMod
|
||||
}
|
||||
})
|
||||
|
||||
if mod != nil {
|
||||
variantMod, ok := mod.(*CcApiVariant)
|
||||
if ok {
|
||||
in = variantMod.Src()
|
||||
|
||||
// Copy LLDNK properties to cc_api_library module
|
||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append(
|
||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs,
|
||||
variantMod.exportProperties.Export_headers...)
|
||||
|
||||
// Export headers as system include dirs if specified. Mostly for libc
|
||||
if proptools.Bool(variantMod.exportProperties.Export_headers_as_system) {
|
||||
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append(
|
||||
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs,
|
||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs...)
|
||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
|
||||
@@ -107,13 +167,10 @@ func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps
|
||||
d.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
|
||||
d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
|
||||
|
||||
if d.properties.Src == nil {
|
||||
ctx.PropertyErrorf("src", "src is a required property")
|
||||
if in == nil {
|
||||
ctx.PropertyErrorf("src", "Unable to locate source property")
|
||||
return nil
|
||||
}
|
||||
// Skip the existence check of the stub prebuilt file.
|
||||
// The file is not guaranteed to exist during Soong analysis.
|
||||
// Build orchestrator will be responsible for creating a connected ninja graph.
|
||||
in := android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), *d.properties.Src)
|
||||
|
||||
// Make the _compilation_ of rdeps have an order-only dep on cc_api_library.src (an .so file)
|
||||
// The .so file itself has an order-only dependency on the headers contributed by this library.
|
||||
@@ -143,6 +200,43 @@ func (d *apiLibraryDecorator) availableFor(what string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
|
||||
m, ok := ctx.Module().(*Module)
|
||||
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
if d.hasLLNDKStubs() && m.UseVndk() {
|
||||
// LLNDK libraries only need a single stubs variant.
|
||||
return []string{android.FutureApiLevel.String()}
|
||||
}
|
||||
|
||||
// TODO(b/244244438) Create more version information for NDK and APEX variations
|
||||
// NDK variants
|
||||
if m.MinSdkVersion() == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
firstVersion, err := nativeApiLevelFromUser(ctx,
|
||||
m.MinSdkVersion())
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ndkLibraryVersions(ctx, firstVersion)
|
||||
}
|
||||
|
||||
func (d *apiLibraryDecorator) hasLLNDKStubs() bool {
|
||||
for _, variant := range d.properties.Variants {
|
||||
if strings.Contains(variant, "llndk") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 'cc_api_headers' is similar with 'cc_api_library', but which replaces
|
||||
// header libraries. The module will replace any dependencies to existing
|
||||
// original header libraries.
|
||||
@@ -165,9 +259,6 @@ func CcApiHeadersFactory() android.Module {
|
||||
module.linker = apiHeadersDecorator
|
||||
module.installer = nil
|
||||
|
||||
// Mark module as stub, so APEX would not include this stub in the package.
|
||||
module.library.setBuildStubs(true)
|
||||
|
||||
// Prevent default system libs (libc, libm, and libdl) from being linked
|
||||
if apiHeadersDecorator.baseLinker.Properties.System_shared_libs == nil {
|
||||
apiHeadersDecorator.baseLinker.Properties.System_shared_libs = []string{}
|
||||
@@ -189,3 +280,91 @@ func (d *apiHeadersDecorator) availableFor(what string) bool {
|
||||
// Stub from API surface should be available for any APEX.
|
||||
return true
|
||||
}
|
||||
|
||||
type ccApiexportProperties struct {
|
||||
Src *string `android:"arch_variant"`
|
||||
Variant *string
|
||||
Version *string
|
||||
}
|
||||
|
||||
type variantExporterProperties struct {
|
||||
// Header directory or library to export
|
||||
Export_headers []string
|
||||
|
||||
// Export all headers as system include
|
||||
Export_headers_as_system *bool
|
||||
}
|
||||
|
||||
type CcApiVariant struct {
|
||||
android.ModuleBase
|
||||
|
||||
properties ccApiexportProperties
|
||||
exportProperties variantExporterProperties
|
||||
|
||||
src android.Path
|
||||
}
|
||||
|
||||
var _ android.Module = (*CcApiVariant)(nil)
|
||||
var _ android.ImageInterface = (*CcApiVariant)(nil)
|
||||
|
||||
func CcApiVariantFactory() android.Module {
|
||||
module := &CcApiVariant{}
|
||||
|
||||
module.AddProperties(&module.properties)
|
||||
module.AddProperties(&module.exportProperties)
|
||||
|
||||
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
|
||||
return module
|
||||
}
|
||||
|
||||
func (v *CcApiVariant) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
// No need to build
|
||||
|
||||
if proptools.String(v.properties.Src) == "" {
|
||||
ctx.PropertyErrorf("src", "src is a required property")
|
||||
}
|
||||
|
||||
// Skip the existence check of the stub prebuilt file.
|
||||
// The file is not guaranteed to exist during Soong analysis.
|
||||
// Build orchestrator will be responsible for creating a connected ninja graph.
|
||||
v.src = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), proptools.String(v.properties.Src))
|
||||
}
|
||||
|
||||
func (v *CcApiVariant) Name() string {
|
||||
version := proptools.String(v.properties.Version)
|
||||
return BuildApiVariantName(v.BaseModuleName(), *v.properties.Variant, version)
|
||||
}
|
||||
|
||||
func (v *CcApiVariant) Src() android.Path {
|
||||
return v.src
|
||||
}
|
||||
|
||||
func BuildApiVariantName(baseName string, variant string, version string) string {
|
||||
names := []string{baseName, variant}
|
||||
if version != "" {
|
||||
names = append(names, version)
|
||||
}
|
||||
|
||||
return strings.Join(names[:], ".") + multitree.GetApiImportSuffix()
|
||||
}
|
||||
|
||||
// Implement ImageInterface to generate image variants
|
||||
func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
|
||||
func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool { return false }
|
||||
func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
|
||||
func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
|
||||
func (v *CcApiVariant) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
|
||||
func (v *CcApiVariant) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { return false }
|
||||
func (v *CcApiVariant) ExtraImageVariations(ctx android.BaseModuleContext) []string {
|
||||
var variations []string
|
||||
platformVndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
|
||||
|
||||
if proptools.String(v.properties.Variant) == "llndk" {
|
||||
variations = append(variations, VendorVariationPrefix+platformVndkVersion)
|
||||
variations = append(variations, ProductVariationPrefix+platformVndkVersion)
|
||||
}
|
||||
|
||||
return variations
|
||||
}
|
||||
func (v *CcApiVariant) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
|
||||
}
|
||||
|
@@ -284,3 +284,54 @@ func TestExportDirFromStubLibrary(t *testing.T) {
|
||||
// These header files are required for compiling the other API domain (vendor in this case)
|
||||
android.AssertStringListContains(t, "Vendor binary compilation should have an implicit dep on the stub .so file", vendorImplicits, "libfoo.so")
|
||||
}
|
||||
|
||||
func TestApiLibraryWithLlndkVariant(t *testing.T) {
|
||||
bp := `
|
||||
cc_binary {
|
||||
name: "binfoo",
|
||||
vendor: true,
|
||||
srcs: ["binfoo.cc"],
|
||||
shared_libs: ["libbar"],
|
||||
}
|
||||
|
||||
cc_api_library {
|
||||
name: "libbar",
|
||||
// TODO(b/244244438) Remove src property once all variants are implemented.
|
||||
src: "libbar.so",
|
||||
vendor_available: true,
|
||||
variants: [
|
||||
"llndk",
|
||||
],
|
||||
}
|
||||
|
||||
cc_api_variant {
|
||||
name: "libbar",
|
||||
variant: "llndk",
|
||||
src: "libbar_llndk.so",
|
||||
export_headers: ["libbar_llndk_include"]
|
||||
}
|
||||
|
||||
api_imports {
|
||||
name: "api_imports",
|
||||
shared_libs: [
|
||||
"libbar",
|
||||
],
|
||||
header_libs: [],
|
||||
}
|
||||
`
|
||||
|
||||
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
||||
|
||||
libfoo := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Module()
|
||||
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||
libbarApiVariant := ctx.ModuleForTests("libbar.llndk.apiimport", "android_vendor.29_arm64_armv8-a").Module()
|
||||
|
||||
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
|
||||
android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
|
||||
|
||||
libFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
|
||||
android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", libFooLibFlags, "libbar_llndk.so")
|
||||
|
||||
libFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
|
||||
android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", libFooCFlags, "-Ilibbar_llndk_include")
|
||||
}
|
||||
|
Reference in New Issue
Block a user