Merge "Implement API surface import with APEX stub"
This commit is contained in:
@@ -9788,30 +9788,85 @@ func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
|
|||||||
apex {
|
apex {
|
||||||
name: "myapex",
|
name: "myapex",
|
||||||
key: "myapex.key",
|
key: "myapex.key",
|
||||||
native_shared_libs: ["libfoo"],
|
native_shared_libs: ["libbaz"],
|
||||||
|
binaries: ["binfoo"],
|
||||||
min_sdk_version: "29",
|
min_sdk_version: "29",
|
||||||
}
|
}
|
||||||
apex_key {
|
apex_key {
|
||||||
name: "myapex.key",
|
name: "myapex.key",
|
||||||
}
|
}
|
||||||
cc_library {
|
cc_binary {
|
||||||
name: "libfoo",
|
name: "binfoo",
|
||||||
shared_libs: ["libc"],
|
shared_libs: ["libbar", "libbaz", "libqux",],
|
||||||
apex_available: ["myapex"],
|
apex_available: ["myapex"],
|
||||||
min_sdk_version: "29",
|
min_sdk_version: "29",
|
||||||
|
recovery_available: false,
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libbar",
|
||||||
|
srcs: ["libbar.cc"],
|
||||||
|
stubs: {
|
||||||
|
symbol_file: "libbar.map.txt",
|
||||||
|
versions: [
|
||||||
|
"29",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libbaz",
|
||||||
|
srcs: ["libbaz.cc"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
stubs: {
|
||||||
|
symbol_file: "libbaz.map.txt",
|
||||||
|
versions: [
|
||||||
|
"29",
|
||||||
|
],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
cc_api_library {
|
cc_api_library {
|
||||||
name: "libc",
|
name: "libbar",
|
||||||
src: "libc.so",
|
src: "libbar_stub.so",
|
||||||
min_sdk_version: "29",
|
min_sdk_version: "29",
|
||||||
recovery_available: true,
|
variants: ["apex.29"],
|
||||||
|
}
|
||||||
|
cc_api_variant {
|
||||||
|
name: "libbar",
|
||||||
|
variant: "apex",
|
||||||
|
version: "29",
|
||||||
|
src: "libbar_apex_29.so",
|
||||||
|
}
|
||||||
|
cc_api_library {
|
||||||
|
name: "libbaz",
|
||||||
|
src: "libbaz_stub.so",
|
||||||
|
min_sdk_version: "29",
|
||||||
|
variants: ["apex.29"],
|
||||||
|
}
|
||||||
|
cc_api_variant {
|
||||||
|
name: "libbaz",
|
||||||
|
variant: "apex",
|
||||||
|
version: "29",
|
||||||
|
src: "libbaz_apex_29.so",
|
||||||
|
}
|
||||||
|
cc_api_library {
|
||||||
|
name: "libqux",
|
||||||
|
src: "libqux_stub.so",
|
||||||
|
min_sdk_version: "29",
|
||||||
|
variants: ["apex.29"],
|
||||||
|
}
|
||||||
|
cc_api_variant {
|
||||||
|
name: "libqux",
|
||||||
|
variant: "apex",
|
||||||
|
version: "29",
|
||||||
|
src: "libqux_apex_29.so",
|
||||||
}
|
}
|
||||||
api_imports {
|
api_imports {
|
||||||
name: "api_imports",
|
name: "api_imports",
|
||||||
shared_libs: [
|
apex_shared_libs: [
|
||||||
"libc",
|
"libbar",
|
||||||
|
"libbaz",
|
||||||
|
"libqux",
|
||||||
],
|
],
|
||||||
header_libs: [],
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
result := testApex(t, bp)
|
result := testApex(t, bp)
|
||||||
@@ -9827,17 +9882,107 @@ func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
|
|||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
libfooApexVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex29").Module()
|
// Library defines stubs and cc_api_library should be used with cc_api_library
|
||||||
libcApexVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared_apex29").Module()
|
binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Module()
|
||||||
|
libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
|
||||||
|
libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
|
||||||
|
|
||||||
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(libfooApexVariant, libcApexVariant))
|
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
|
||||||
|
android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
|
||||||
|
|
||||||
// libfoo core variant should be buildable in the same inner tree since
|
binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Rule("ld").Args["libFlags"]
|
||||||
// certain mcombo files might build system and apexes in the same inner tree
|
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
|
||||||
// libfoo core variant should link against source libc
|
android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
|
||||||
libfooCoreVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
|
android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
|
||||||
libcCoreVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared").Module()
|
|
||||||
android.AssertBoolEquals(t, "core variant should link against source libc", true, hasDep(libfooCoreVariant, libcCoreVariant))
|
// Library defined in the same APEX should be linked with original definition instead of cc_api_library
|
||||||
|
libbazApexVariant := result.ModuleForTests("libbaz", "android_arm64_armv8-a_shared_apex29").Module()
|
||||||
|
libbazApiImportCoreVariant := result.ModuleForTests("libbaz.apiimport", "android_arm64_armv8-a_shared").Module()
|
||||||
|
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even from same APEX", true, hasDep(binfooApexVariant, libbazApiImportCoreVariant))
|
||||||
|
android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbazApexVariant))
|
||||||
|
|
||||||
|
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbaz.so")
|
||||||
|
android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbaz.apiimport.so")
|
||||||
|
android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbaz.apex.29.apiimport.so")
|
||||||
|
|
||||||
|
// cc_api_library defined without original library should be linked with cc_api_library
|
||||||
|
libquxApiImportApexVariant := result.ModuleForTests("libqux.apiimport", "android_arm64_armv8-a_shared").Module()
|
||||||
|
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even original library definition does not exist", true, hasDep(binfooApexVariant, libquxApiImportApexVariant))
|
||||||
|
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libqux.apex.29.apiimport.so")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPlatformBinaryBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
|
||||||
|
bp := `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libbar"],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
}
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
}
|
||||||
|
cc_binary {
|
||||||
|
name: "binfoo",
|
||||||
|
shared_libs: ["libbar"],
|
||||||
|
recovery_available: false,
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libbar",
|
||||||
|
srcs: ["libbar.cc"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
min_sdk_version: "29",
|
||||||
|
stubs: {
|
||||||
|
symbol_file: "libbar.map.txt",
|
||||||
|
versions: [
|
||||||
|
"29",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cc_api_library {
|
||||||
|
name: "libbar",
|
||||||
|
src: "libbar_stub.so",
|
||||||
|
variants: ["apex.29"],
|
||||||
|
}
|
||||||
|
cc_api_variant {
|
||||||
|
name: "libbar",
|
||||||
|
variant: "apex",
|
||||||
|
version: "29",
|
||||||
|
src: "libbar_apex_29.so",
|
||||||
|
}
|
||||||
|
api_imports {
|
||||||
|
name: "api_imports",
|
||||||
|
apex_shared_libs: [
|
||||||
|
"libbar",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
result := testApex(t, bp)
|
||||||
|
|
||||||
|
hasDep := func(m android.Module, wantDep android.Module) bool {
|
||||||
|
t.Helper()
|
||||||
|
var found bool
|
||||||
|
result.VisitDirectDeps(m, func(dep blueprint.Module) {
|
||||||
|
if dep == wantDep {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Library defines stubs and cc_api_library should be used with cc_api_library
|
||||||
|
binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Module()
|
||||||
|
libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
|
||||||
|
libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
|
||||||
|
|
||||||
|
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
|
||||||
|
android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
|
||||||
|
|
||||||
|
binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
|
||||||
|
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
|
||||||
|
android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
|
||||||
|
android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrimmedApex(t *testing.T) {
|
func TestTrimmedApex(t *testing.T) {
|
||||||
|
231
cc/cc.go
231
cc/cc.go
@@ -2416,6 +2416,27 @@ func rewriteLibsForApiImports(c LinkableInterface, libs []string, replaceList ma
|
|||||||
return nonVariantLibs, variantLibs
|
return nonVariantLibs, variantLibs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Module) shouldUseApiSurface() bool {
|
||||||
|
if c.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
|
||||||
|
if GetImageVariantType(c) == vendorImageVariant || GetImageVariantType(c) == productImageVariant {
|
||||||
|
// LLNDK Variant
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Properties.IsSdkVariant {
|
||||||
|
// NDK Variant
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.isImportedApiLibrary() {
|
||||||
|
// API Library should depend on API headers
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||||
if !c.Enabled() {
|
if !c.Enabled() {
|
||||||
return
|
return
|
||||||
@@ -2435,7 +2456,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
apiNdkLibs := []string{}
|
apiNdkLibs := []string{}
|
||||||
apiLateNdkLibs := []string{}
|
apiLateNdkLibs := []string{}
|
||||||
|
|
||||||
if ctx.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
|
if c.shouldUseApiSurface() {
|
||||||
deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config())
|
deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config())
|
||||||
deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
|
deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
|
||||||
deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
|
deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
|
||||||
@@ -2466,7 +2487,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check header lib replacement from API surface first, and then check again with VSDK
|
// Check header lib replacement from API surface first, and then check again with VSDK
|
||||||
if ctx.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
|
if c.shouldUseApiSurface() {
|
||||||
lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs)
|
lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs)
|
||||||
}
|
}
|
||||||
lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
|
lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
|
||||||
@@ -2550,12 +2571,22 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
name, version := StubsLibNameAndVersion(lib)
|
name, version := StubsLibNameAndVersion(lib)
|
||||||
|
if apiLibraryName, ok := apiImportInfo.SharedLibs[name]; ok && !ctx.OtherModuleExists(name) {
|
||||||
|
name = apiLibraryName
|
||||||
|
}
|
||||||
sharedLibNames = append(sharedLibNames, name)
|
sharedLibNames = append(sharedLibNames, name)
|
||||||
|
|
||||||
variations := []blueprint.Variation{
|
variations := []blueprint.Variation{
|
||||||
{Mutator: "link", Variation: "shared"},
|
{Mutator: "link", Variation: "shared"},
|
||||||
}
|
}
|
||||||
AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
|
|
||||||
|
if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
|
||||||
|
AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok {
|
||||||
|
AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, apiLibraryName, version, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, lib := range deps.LateStaticLibs {
|
for _, lib := range deps.LateStaticLibs {
|
||||||
@@ -2898,10 +2929,58 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
||||||
c.apexSdkVersion = findApexSdkVersion(ctx, apexInfo)
|
c.apexSdkVersion = findApexSdkVersion(ctx, apexInfo)
|
||||||
|
|
||||||
|
skipModuleList := map[string]bool{}
|
||||||
|
|
||||||
|
var apiImportInfo multitree.ApiImportInfo
|
||||||
|
hasApiImportInfo := false
|
||||||
|
|
||||||
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
|
if dep.Name() == "api_imports" {
|
||||||
|
apiImportInfo = ctx.OtherModuleProvider(dep, multitree.ApiImportsProvider).(multitree.ApiImportInfo)
|
||||||
|
hasApiImportInfo = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if hasApiImportInfo {
|
||||||
|
targetStubModuleList := map[string]string{}
|
||||||
|
targetOrigModuleList := map[string]string{}
|
||||||
|
|
||||||
|
// Search for dependency which both original module and API imported library with APEX stub exists
|
||||||
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
|
depName := ctx.OtherModuleName(dep)
|
||||||
|
if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok {
|
||||||
|
targetStubModuleList[apiLibrary] = depName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
|
depName := ctx.OtherModuleName(dep)
|
||||||
|
if origLibrary, ok := targetStubModuleList[depName]; ok {
|
||||||
|
targetOrigModuleList[origLibrary] = depName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Decide which library should be used between original and API imported library
|
||||||
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
|
depName := ctx.OtherModuleName(dep)
|
||||||
|
if apiLibrary, ok := targetOrigModuleList[depName]; ok {
|
||||||
|
if shouldUseStubForApex(ctx, dep) {
|
||||||
|
skipModuleList[depName] = true
|
||||||
|
} else {
|
||||||
|
skipModuleList[apiLibrary] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
ctx.VisitDirectDeps(func(dep android.Module) {
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
depName := ctx.OtherModuleName(dep)
|
depName := ctx.OtherModuleName(dep)
|
||||||
depTag := ctx.OtherModuleDependencyTag(dep)
|
depTag := ctx.OtherModuleDependencyTag(dep)
|
||||||
|
|
||||||
|
if _, ok := skipModuleList[depName]; ok {
|
||||||
|
// skip this module because original module or API imported module matching with this should be used instead.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if depTag == android.DarwinUniversalVariantTag {
|
if depTag == android.DarwinUniversalVariantTag {
|
||||||
depPaths.DarwinSecondArchOutput = dep.(*Module).OutputFile()
|
depPaths.DarwinSecondArchOutput = dep.(*Module).OutputFile()
|
||||||
return
|
return
|
||||||
@@ -3237,21 +3316,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
return depPaths
|
return depPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant
|
func shouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool {
|
||||||
// of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right
|
|
||||||
// dependency. The stub variant is selected when the dependency crosses a boundary where each side
|
|
||||||
// has different level of updatability. For example, if a library foo in an APEX depends on a
|
|
||||||
// library bar which provides stable interface and exists in the platform, foo uses the stub variant
|
|
||||||
// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
|
|
||||||
// same APEX as foo, the non-stub variant of bar is used.
|
|
||||||
func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
|
|
||||||
depName := ctx.OtherModuleName(dep)
|
depName := ctx.OtherModuleName(dep)
|
||||||
depTag := ctx.OtherModuleDependencyTag(dep)
|
|
||||||
libDepTag, ok := depTag.(libraryDependencyTag)
|
|
||||||
if !ok || !libDepTag.shared() {
|
|
||||||
panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
|
|
||||||
}
|
|
||||||
|
|
||||||
thisModule, ok := ctx.Module().(android.ApexModule)
|
thisModule, ok := ctx.Module().(android.ApexModule)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Errorf("Not an APEX module: %q", ctx.ModuleName()))
|
panic(fmt.Errorf("Not an APEX module: %q", ctx.ModuleName()))
|
||||||
@@ -3266,62 +3332,93 @@ func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibr
|
|||||||
bootstrap = linkable.Bootstrap()
|
bootstrap = linkable.Bootstrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
||||||
|
|
||||||
|
useStubs := false
|
||||||
|
|
||||||
|
if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK
|
||||||
|
if !apexInfo.IsForPlatform() {
|
||||||
|
// For platform libraries, use current version of LLNDK
|
||||||
|
// If this is for use_vendor apex we will apply the same rules
|
||||||
|
// of apex sdk enforcement below to choose right version.
|
||||||
|
useStubs = true
|
||||||
|
}
|
||||||
|
} else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis {
|
||||||
|
// If not building for APEX or the containing APEX allows the use of
|
||||||
|
// platform APIs, use stubs only when it is from an APEX (and not from
|
||||||
|
// platform) However, for host, ramdisk, vendor_ramdisk, recovery or
|
||||||
|
// bootstrap modules, always link to non-stub variant
|
||||||
|
isNotInPlatform := dep.(android.ApexModule).NotInPlatform()
|
||||||
|
|
||||||
|
isApexImportedApiLibrary := false
|
||||||
|
|
||||||
|
if cc, ok := dep.(*Module); ok {
|
||||||
|
if apiLibrary, ok := cc.linker.(*apiLibraryDecorator); ok {
|
||||||
|
if apiLibrary.hasApexStubs() {
|
||||||
|
isApexImportedApiLibrary = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useStubs = (isNotInPlatform || isApexImportedApiLibrary) && !bootstrap
|
||||||
|
|
||||||
|
if useStubs {
|
||||||
|
// Another exception: if this module is a test for an APEX, then
|
||||||
|
// it is linked with the non-stub variant of a module in the APEX
|
||||||
|
// as if this is part of the APEX.
|
||||||
|
testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
|
||||||
|
for _, apexContents := range testFor.ApexContents {
|
||||||
|
if apexContents.DirectlyInApex(depName) {
|
||||||
|
useStubs = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if useStubs {
|
||||||
|
// Yet another exception: If this module and the dependency are
|
||||||
|
// available to the same APEXes then skip stubs between their
|
||||||
|
// platform variants. This complements the test_for case above,
|
||||||
|
// which avoids the stubs on a direct APEX library dependency, by
|
||||||
|
// avoiding stubs for indirect test dependencies as well.
|
||||||
|
//
|
||||||
|
// TODO(b/183882457): This doesn't work if the two libraries have
|
||||||
|
// only partially overlapping apex_available. For that test_for
|
||||||
|
// modules would need to be split into APEX variants and resolved
|
||||||
|
// separately for each APEX they have access to.
|
||||||
|
if !isApexImportedApiLibrary && android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
|
||||||
|
useStubs = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If building for APEX, use stubs when the parent is in any APEX that
|
||||||
|
// the child is not in.
|
||||||
|
useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return useStubs
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant
|
||||||
|
// of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right
|
||||||
|
// dependency. The stub variant is selected when the dependency crosses a boundary where each side
|
||||||
|
// has different level of updatability. For example, if a library foo in an APEX depends on a
|
||||||
|
// library bar which provides stable interface and exists in the platform, foo uses the stub variant
|
||||||
|
// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
|
||||||
|
// same APEX as foo, the non-stub variant of bar is used.
|
||||||
|
func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
|
||||||
|
depTag := ctx.OtherModuleDependencyTag(dep)
|
||||||
|
libDepTag, ok := depTag.(libraryDependencyTag)
|
||||||
|
if !ok || !libDepTag.shared() {
|
||||||
|
panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
|
||||||
|
}
|
||||||
|
|
||||||
sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo)
|
sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo)
|
||||||
depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
|
depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
|
||||||
sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryStubsProvider).(SharedLibraryStubsInfo)
|
sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryStubsProvider).(SharedLibraryStubsInfo)
|
||||||
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
|
||||||
|
|
||||||
if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 {
|
if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 {
|
||||||
useStubs := false
|
|
||||||
|
|
||||||
if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK
|
|
||||||
if !apexInfo.IsForPlatform() {
|
|
||||||
// For platform libraries, use current version of LLNDK
|
|
||||||
// If this is for use_vendor apex we will apply the same rules
|
|
||||||
// of apex sdk enforcement below to choose right version.
|
|
||||||
useStubs = true
|
|
||||||
}
|
|
||||||
} else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis {
|
|
||||||
// If not building for APEX or the containing APEX allows the use of
|
|
||||||
// platform APIs, use stubs only when it is from an APEX (and not from
|
|
||||||
// platform) However, for host, ramdisk, vendor_ramdisk, recovery or
|
|
||||||
// bootstrap modules, always link to non-stub variant
|
|
||||||
useStubs = dep.(android.ApexModule).NotInPlatform() && !bootstrap
|
|
||||||
if useStubs {
|
|
||||||
// Another exception: if this module is a test for an APEX, then
|
|
||||||
// it is linked with the non-stub variant of a module in the APEX
|
|
||||||
// as if this is part of the APEX.
|
|
||||||
testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
|
|
||||||
for _, apexContents := range testFor.ApexContents {
|
|
||||||
if apexContents.DirectlyInApex(depName) {
|
|
||||||
useStubs = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if useStubs {
|
|
||||||
// Yet another exception: If this module and the dependency are
|
|
||||||
// available to the same APEXes then skip stubs between their
|
|
||||||
// platform variants. This complements the test_for case above,
|
|
||||||
// which avoids the stubs on a direct APEX library dependency, by
|
|
||||||
// avoiding stubs for indirect test dependencies as well.
|
|
||||||
//
|
|
||||||
// TODO(b/183882457): This doesn't work if the two libraries have
|
|
||||||
// only partially overlapping apex_available. For that test_for
|
|
||||||
// modules would need to be split into APEX variants and resolved
|
|
||||||
// separately for each APEX they have access to.
|
|
||||||
if android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
|
|
||||||
useStubs = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If building for APEX, use stubs when the parent is in any APEX that
|
|
||||||
// the child is not in.
|
|
||||||
useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// when to use (unspecified) stubs, use the latest one.
|
// when to use (unspecified) stubs, use the latest one.
|
||||||
if useStubs {
|
if shouldUseStubForApex(ctx, dep) {
|
||||||
stubs := sharedLibraryStubsInfo.SharedStubLibraries
|
stubs := sharedLibraryStubsInfo.SharedStubLibraries
|
||||||
toUse := stubs[len(stubs)-1]
|
toUse := stubs[len(stubs)-1]
|
||||||
sharedLibraryInfo = toUse.SharedLibraryInfo
|
sharedLibraryInfo = toUse.SharedLibraryInfo
|
||||||
|
@@ -23,7 +23,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
|
ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
|
||||||
|
stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)")
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -60,6 +61,12 @@ func updateImportedLibraryDependency(ctx android.BottomUpMutatorContext) {
|
|||||||
variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
|
variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
|
||||||
ctx.AddDependency(m, nil, variantName)
|
ctx.AddDependency(m, nil, variantName)
|
||||||
}
|
}
|
||||||
|
} else if m.IsStubs() {
|
||||||
|
targetVariant := "apex." + m.StubsVersion()
|
||||||
|
if inList(targetVariant, apiLibrary.properties.Variants) {
|
||||||
|
variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
|
||||||
|
ctx.AddDependency(m, nil, variantName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,15 +160,15 @@ func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps
|
|||||||
in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
|
in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLNDK variant
|
libName := m.BaseModuleName() + multitree.GetApiImportSuffix()
|
||||||
if m.UseVndk() && d.hasLLNDKStubs() {
|
|
||||||
apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
|
|
||||||
|
|
||||||
|
load_cc_variant := func(apiVariantModule string) {
|
||||||
var mod android.Module
|
var mod android.Module
|
||||||
|
|
||||||
ctx.VisitDirectDeps(func(depMod android.Module) {
|
ctx.VisitDirectDeps(func(depMod android.Module) {
|
||||||
if depMod.Name() == apiVariantModule {
|
if depMod.Name() == apiVariantModule {
|
||||||
mod = depMod
|
mod = depMod
|
||||||
|
libName = apiVariantModule
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -184,37 +191,17 @@ func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.UseVndk() && d.hasLLNDKStubs() {
|
||||||
|
// LLNDK variant
|
||||||
|
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", ""))
|
||||||
} else if m.IsSdkVariant() {
|
} else if m.IsSdkVariant() {
|
||||||
// NDK Variant
|
// NDK Variant
|
||||||
apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion())
|
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion()))
|
||||||
|
} else if m.IsStubs() {
|
||||||
var mod android.Module
|
// APEX Variant
|
||||||
|
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion()))
|
||||||
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 NDK properties to cc_api_library module
|
|
||||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append(
|
|
||||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs,
|
|
||||||
variantMod.exportProperties.Export_include_dirs...)
|
|
||||||
|
|
||||||
// Export headers as system include dirs if specified. Mostly for libc
|
|
||||||
if 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)
|
// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
|
||||||
@@ -237,20 +224,58 @@ func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps
|
|||||||
d.libraryDecorator.flagExporter.setProvider(ctx)
|
d.libraryDecorator.flagExporter.setProvider(ctx)
|
||||||
|
|
||||||
d.unstrippedOutputFile = in
|
d.unstrippedOutputFile = in
|
||||||
libName := d.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
|
libName += flags.Toolchain.ShlibSuffix()
|
||||||
|
|
||||||
tocFile := android.PathForModuleOut(ctx, libName+".toc")
|
tocFile := android.PathForModuleOut(ctx, libName+".toc")
|
||||||
d.tocFile = android.OptionalPathForPath(tocFile)
|
d.tocFile = android.OptionalPathForPath(tocFile)
|
||||||
TransformSharedObjectToToc(ctx, in, tocFile)
|
TransformSharedObjectToToc(ctx, in, tocFile)
|
||||||
|
|
||||||
|
outputFile := android.PathForModuleOut(ctx, libName)
|
||||||
|
|
||||||
|
// TODO(b/270485584) This copies with a new name, just to avoid conflict with prebuilts.
|
||||||
|
// We can just use original input if there is any way to avoid name conflict without copy.
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: android.Cp,
|
||||||
|
Description: "API surface imported library",
|
||||||
|
Input: in,
|
||||||
|
Output: outputFile,
|
||||||
|
Args: map[string]string{
|
||||||
|
"cpFlags": "-L",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
|
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
|
||||||
SharedLibrary: in,
|
SharedLibrary: outputFile,
|
||||||
Target: ctx.Target(),
|
Target: ctx.Target(),
|
||||||
|
|
||||||
TableOfContents: d.tocFile,
|
TableOfContents: d.tocFile,
|
||||||
})
|
})
|
||||||
|
|
||||||
return in
|
d.shareStubs(ctx)
|
||||||
|
|
||||||
|
return outputFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// Share additional information about stub libraries with provider
|
||||||
|
func (d *apiLibraryDecorator) shareStubs(ctx ModuleContext) {
|
||||||
|
stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
|
||||||
|
if len(stubs) > 0 {
|
||||||
|
var stubsInfo []SharedStubLibrary
|
||||||
|
for _, stub := range stubs {
|
||||||
|
stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo)
|
||||||
|
flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo)
|
||||||
|
stubsInfo = append(stubsInfo, SharedStubLibrary{
|
||||||
|
Version: moduleLibraryInterface(stub).stubsVersion(),
|
||||||
|
SharedLibraryInfo: stubInfo,
|
||||||
|
FlagExporterInfo: flagInfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{
|
||||||
|
SharedStubLibraries: stubsInfo,
|
||||||
|
|
||||||
|
IsLLNDK: ctx.IsLlndk(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) availableFor(what string) bool {
|
func (d *apiLibraryDecorator) availableFor(what string) bool {
|
||||||
@@ -258,6 +283,19 @@ func (d *apiLibraryDecorator) availableFor(what string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *apiLibraryDecorator) hasApexStubs() bool {
|
||||||
|
for _, variant := range d.properties.Variants {
|
||||||
|
if strings.HasPrefix(variant, "apex") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *apiLibraryDecorator) hasStubsVariants() bool {
|
||||||
|
return d.hasApexStubs()
|
||||||
|
}
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
|
func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
|
||||||
m, ok := ctx.Module().(*Module)
|
m, ok := ctx.Module().(*Module)
|
||||||
|
|
||||||
@@ -265,14 +303,8 @@ func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []st
|
|||||||
return nil
|
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
|
// TODO(b/244244438) Create more version information for NDK and APEX variations
|
||||||
// NDK variants
|
// NDK variants
|
||||||
|
|
||||||
if m.IsSdkVariant() {
|
if m.IsSdkVariant() {
|
||||||
// TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant.
|
// TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant.
|
||||||
if d.hasNDKStubs() {
|
if d.hasNDKStubs() {
|
||||||
@@ -280,6 +312,17 @@ func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.hasLLNDKStubs() && m.UseVndk() {
|
||||||
|
// LLNDK libraries only need a single stubs variant.
|
||||||
|
return []string{android.FutureApiLevel.String()}
|
||||||
|
}
|
||||||
|
|
||||||
|
stubsVersions := d.getStubVersions()
|
||||||
|
|
||||||
|
if len(stubsVersions) != 0 {
|
||||||
|
return stubsVersions
|
||||||
|
}
|
||||||
|
|
||||||
if m.MinSdkVersion() == "" {
|
if m.MinSdkVersion() == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -319,6 +362,18 @@ func (d *apiLibraryDecorator) getNdkVersions() []string {
|
|||||||
return ndkVersions
|
return ndkVersions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *apiLibraryDecorator) getStubVersions() []string {
|
||||||
|
stubVersions := []string{}
|
||||||
|
|
||||||
|
for _, variant := range d.properties.Variants {
|
||||||
|
if match := stubVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
|
||||||
|
stubVersions = append(stubVersions, match[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stubVersions
|
||||||
|
}
|
||||||
|
|
||||||
// 'cc_api_headers' is similar with 'cc_api_library', but which replaces
|
// 'cc_api_headers' is similar with 'cc_api_library', but which replaces
|
||||||
// header libraries. The module will replace any dependencies to existing
|
// header libraries. The module will replace any dependencies to existing
|
||||||
// original header libraries.
|
// original header libraries.
|
||||||
@@ -433,7 +488,7 @@ func BuildApiVariantName(baseName string, variant string, version string) string
|
|||||||
// Implement ImageInterface to generate image variants
|
// Implement ImageInterface to generate image variants
|
||||||
func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
|
func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
|
||||||
func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
|
func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
|
||||||
return String(v.properties.Variant) == "ndk"
|
return inList(String(v.properties.Variant), []string{"ndk", "apex"})
|
||||||
}
|
}
|
||||||
func (v *CcApiVariant) RamdiskVariantNeeded(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) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
|
||||||
|
@@ -41,6 +41,7 @@ func TestApiLibraryReplacesExistingModule(t *testing.T) {
|
|||||||
cc_library {
|
cc_library {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
shared_libs: ["libbar"],
|
shared_libs: ["libbar"],
|
||||||
|
vendor_available: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_library {
|
cc_library {
|
||||||
@@ -49,6 +50,7 @@ func TestApiLibraryReplacesExistingModule(t *testing.T) {
|
|||||||
|
|
||||||
cc_api_library {
|
cc_api_library {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
|
vendor_available: true,
|
||||||
src: "libbar.so",
|
src: "libbar.so",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +59,6 @@ func TestApiLibraryReplacesExistingModule(t *testing.T) {
|
|||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libbar",
|
"libbar",
|
||||||
],
|
],
|
||||||
header_libs: [],
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -67,8 +68,14 @@ func TestApiLibraryReplacesExistingModule(t *testing.T) {
|
|||||||
libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
|
libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
|
||||||
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
|
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
|
||||||
|
|
||||||
android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbar))
|
android.AssertBoolEquals(t, "original library should be linked with non-stub variant", true, hasDirectDependency(t, ctx, libfoo, libbar))
|
||||||
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
|
android.AssertBoolEquals(t, "Stub library from API surface should be not linked with non-stub variant", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
|
||||||
|
|
||||||
|
libfooVendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||||
|
libbarApiImportVendor := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||||
|
|
||||||
|
android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfooVendor, libbar))
|
||||||
|
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfooVendor, libbarApiImportVendor))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
|
func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
|
||||||
@@ -76,11 +83,13 @@ func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
|
|||||||
cc_library {
|
cc_library {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
shared_libs: ["libbar"],
|
shared_libs: ["libbar"],
|
||||||
|
vendor: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_api_library {
|
cc_api_library {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
src: "libbar.so",
|
src: "libbar.so",
|
||||||
|
vendor_available: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
api_imports {
|
api_imports {
|
||||||
@@ -88,14 +97,13 @@ func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
|
|||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libbar",
|
"libbar",
|
||||||
],
|
],
|
||||||
header_libs: [],
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
||||||
|
|
||||||
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
|
libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||||
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
|
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||||
|
|
||||||
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
|
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
|
||||||
}
|
}
|
||||||
@@ -105,143 +113,36 @@ func TestApiLibraryShouldNotReplaceWithoutApiImport(t *testing.T) {
|
|||||||
cc_library {
|
cc_library {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
shared_libs: ["libbar"],
|
shared_libs: ["libbar"],
|
||||||
|
vendor_available: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_library {
|
cc_library {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
|
vendor_available: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_api_library {
|
cc_api_library {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
src: "libbar.so",
|
src: "libbar.so",
|
||||||
|
vendor_available: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
api_imports {
|
api_imports {
|
||||||
name: "api_imports",
|
name: "api_imports",
|
||||||
shared_libs: [],
|
shared_libs: [],
|
||||||
header_libs: [],
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
||||||
|
|
||||||
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
|
libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||||
libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
|
libbar := ctx.ModuleForTests("libbar", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||||
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
|
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
|
||||||
|
|
||||||
android.AssertBoolEquals(t, "original library should be linked", true, hasDirectDependency(t, ctx, libfoo, libbar))
|
android.AssertBoolEquals(t, "original library should be linked", true, hasDirectDependency(t, ctx, libfoo, libbar))
|
||||||
android.AssertBoolEquals(t, "Stub library from API surface should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
|
android.AssertBoolEquals(t, "Stub library from API surface should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApiHeaderReplacesExistingModule(t *testing.T) {
|
|
||||||
bp := `
|
|
||||||
cc_library {
|
|
||||||
name: "libfoo",
|
|
||||||
header_libs: ["libfoo_headers"],
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_api_library {
|
|
||||||
name: "libfoo",
|
|
||||||
header_libs: ["libfoo_headers"],
|
|
||||||
src: "libfoo.so",
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_library_headers {
|
|
||||||
name: "libfoo_headers",
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_api_headers {
|
|
||||||
name: "libfoo_headers",
|
|
||||||
}
|
|
||||||
|
|
||||||
api_imports {
|
|
||||||
name: "api_imports",
|
|
||||||
shared_libs: [
|
|
||||||
"libfoo",
|
|
||||||
],
|
|
||||||
header_libs: [
|
|
||||||
"libfoo_headers",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
|
||||||
|
|
||||||
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
|
|
||||||
libfooApiImport := ctx.ModuleForTests("libfoo.apiimport", "android_arm64_armv8-a_shared").Module()
|
|
||||||
libfooHeader := ctx.ModuleForTests("libfoo_headers", "android_arm64_armv8-a").Module()
|
|
||||||
libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
|
|
||||||
|
|
||||||
android.AssertBoolEquals(t, "original header should not be used for original library", false, hasDirectDependency(t, ctx, libfoo, libfooHeader))
|
|
||||||
android.AssertBoolEquals(t, "Header from API surface should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
|
|
||||||
android.AssertBoolEquals(t, "original header should not be used for library imported from API surface", false, hasDirectDependency(t, ctx, libfooApiImport, libfooHeader))
|
|
||||||
android.AssertBoolEquals(t, "Header from API surface should be used for library imported from API surface", true, hasDirectDependency(t, ctx, libfooApiImport, libfooHeaderApiImport))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApiHeadersDoNotRequireOriginalModule(t *testing.T) {
|
|
||||||
bp := `
|
|
||||||
cc_library {
|
|
||||||
name: "libfoo",
|
|
||||||
header_libs: ["libfoo_headers"],
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_api_headers {
|
|
||||||
name: "libfoo_headers",
|
|
||||||
}
|
|
||||||
|
|
||||||
api_imports {
|
|
||||||
name: "api_imports",
|
|
||||||
shared_libs: [
|
|
||||||
"libfoo",
|
|
||||||
],
|
|
||||||
header_libs: [
|
|
||||||
"libfoo_headers",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
|
||||||
|
|
||||||
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
|
|
||||||
libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
|
|
||||||
|
|
||||||
android.AssertBoolEquals(t, "Header from API surface should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApiHeadersShouldNotReplaceWithoutApiImport(t *testing.T) {
|
|
||||||
bp := `
|
|
||||||
cc_library {
|
|
||||||
name: "libfoo",
|
|
||||||
header_libs: ["libfoo_headers"],
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_library_headers {
|
|
||||||
name: "libfoo_headers",
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_api_headers {
|
|
||||||
name: "libfoo_headers",
|
|
||||||
}
|
|
||||||
|
|
||||||
api_imports {
|
|
||||||
name: "api_imports",
|
|
||||||
shared_libs: [
|
|
||||||
"libfoo",
|
|
||||||
],
|
|
||||||
header_libs: [],
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
|
||||||
|
|
||||||
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
|
|
||||||
libfooHeader := ctx.ModuleForTests("libfoo_headers", "android_arm64_armv8-a").Module()
|
|
||||||
libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
|
|
||||||
|
|
||||||
android.AssertBoolEquals(t, "original header should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeader))
|
|
||||||
android.AssertBoolEquals(t, "Header from API surface should not be used for original library", false, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExportDirFromStubLibrary(t *testing.T) {
|
func TestExportDirFromStubLibrary(t *testing.T) {
|
||||||
bp := `
|
bp := `
|
||||||
cc_library {
|
cc_library {
|
||||||
@@ -330,7 +231,7 @@ func TestApiLibraryWithLlndkVariant(t *testing.T) {
|
|||||||
android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
|
android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
|
||||||
|
|
||||||
binFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
|
binFooLibFlags := 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", binFooLibFlags, "libbar_llndk.so")
|
android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar.llndk.apiimport.so")
|
||||||
|
|
||||||
binFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
|
binFooCFlags := 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", binFooCFlags, "-Ilibbar_llndk_include")
|
android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", binFooCFlags, "-Ilibbar_llndk_include")
|
||||||
@@ -354,6 +255,17 @@ func TestApiLibraryWithNdkVariant(t *testing.T) {
|
|||||||
stl: "c++_shared",
|
stl: "c++_shared",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "binqux",
|
||||||
|
srcs: ["binfoo.cc"],
|
||||||
|
shared_libs: ["libbar"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libbar",
|
||||||
|
srcs: ["libbar.cc"],
|
||||||
|
}
|
||||||
|
|
||||||
cc_api_library {
|
cc_api_library {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
// TODO(b/244244438) Remove src property once all variants are implemented.
|
// TODO(b/244244438) Remove src property once all variants are implemented.
|
||||||
@@ -417,10 +329,14 @@ func TestApiLibraryWithNdkVariant(t *testing.T) {
|
|||||||
android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
|
android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
|
||||||
|
|
||||||
binFooLibFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("ld").Args["libFlags"]
|
binFooLibFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("ld").Args["libFlags"]
|
||||||
android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar_ndk_29.so")
|
android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar.ndk.29.apiimport.so")
|
||||||
|
|
||||||
binFooCFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("cc").Args["cFlags"]
|
binFooCFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("cc").Args["cFlags"]
|
||||||
android.AssertStringDoesContain(t, "Binary using sdk should include headers from the NDK variant source", binFooCFlags, "-Ilibbar_ndk_29_include")
|
android.AssertStringDoesContain(t, "Binary using sdk should include headers from the NDK variant source", binFooCFlags, "-Ilibbar_ndk_29_include")
|
||||||
|
|
||||||
|
binQux := ctx.ModuleForTests("binqux", "android_arm64_armv8-a").Module()
|
||||||
|
android.AssertBoolEquals(t, "NDK Stub library from API surface should not be linked with nonSdk binary", false,
|
||||||
|
(hasDirectDependency(t, ctx, binQux, libbarApiImportv30) || hasDirectDependency(t, ctx, binQux, libbarApiImportv29)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApiLibraryWithMultipleVariants(t *testing.T) {
|
func TestApiLibraryWithMultipleVariants(t *testing.T) {
|
||||||
@@ -440,6 +356,11 @@ func TestApiLibraryWithMultipleVariants(t *testing.T) {
|
|||||||
shared_libs: ["libbar"],
|
shared_libs: ["libbar"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libbar",
|
||||||
|
srcs: ["libbar.cc"],
|
||||||
|
}
|
||||||
|
|
||||||
cc_api_library {
|
cc_api_library {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
// TODO(b/244244438) Remove src property once all variants are implemented.
|
// TODO(b/244244438) Remove src property once all variants are implemented.
|
||||||
@@ -450,6 +371,9 @@ func TestApiLibraryWithMultipleVariants(t *testing.T) {
|
|||||||
"ndk.29",
|
"ndk.29",
|
||||||
"ndk.30",
|
"ndk.30",
|
||||||
"ndk.current",
|
"ndk.current",
|
||||||
|
"apex.29",
|
||||||
|
"apex.30",
|
||||||
|
"apex.current",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,6 +401,30 @@ func TestApiLibraryWithMultipleVariants(t *testing.T) {
|
|||||||
export_include_dirs: ["libbar_ndk_current_include"]
|
export_include_dirs: ["libbar_ndk_current_include"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_api_variant {
|
||||||
|
name: "libbar",
|
||||||
|
variant: "apex",
|
||||||
|
version: "29",
|
||||||
|
src: "libbar_apex_29.so",
|
||||||
|
export_include_dirs: ["libbar_apex_29_include"]
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_api_variant {
|
||||||
|
name: "libbar",
|
||||||
|
variant: "apex",
|
||||||
|
version: "30",
|
||||||
|
src: "libbar_apex_30.so",
|
||||||
|
export_include_dirs: ["libbar_apex_30_include"]
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_api_variant {
|
||||||
|
name: "libbar",
|
||||||
|
variant: "apex",
|
||||||
|
version: "current",
|
||||||
|
src: "libbar_apex_current.so",
|
||||||
|
export_include_dirs: ["libbar_apex_current_include"]
|
||||||
|
}
|
||||||
|
|
||||||
cc_api_variant {
|
cc_api_variant {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
variant: "llndk",
|
variant: "llndk",
|
||||||
@@ -489,7 +437,9 @@ func TestApiLibraryWithMultipleVariants(t *testing.T) {
|
|||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libbar",
|
"libbar",
|
||||||
],
|
],
|
||||||
header_libs: [],
|
apex_shared_libs: [
|
||||||
|
"libbar",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
ctx := prepareForCcTest.RunTestWithBp(t, bp)
|
||||||
|
23
cc/sdk.go
23
cc/sdk.go
@@ -62,21 +62,26 @@ func sdkMutator(ctx android.BottomUpMutatorContext) {
|
|||||||
} else if isCcModule && ccModule.isImportedApiLibrary() {
|
} else if isCcModule && ccModule.isImportedApiLibrary() {
|
||||||
apiLibrary, _ := ccModule.linker.(*apiLibraryDecorator)
|
apiLibrary, _ := ccModule.linker.(*apiLibraryDecorator)
|
||||||
if apiLibrary.hasNDKStubs() && ccModule.canUseSdk() {
|
if apiLibrary.hasNDKStubs() && ccModule.canUseSdk() {
|
||||||
|
variations := []string{"sdk"}
|
||||||
|
if apiLibrary.hasApexStubs() {
|
||||||
|
variations = append(variations, "")
|
||||||
|
}
|
||||||
// Handle cc_api_library module with NDK stubs and variants only which can use SDK
|
// Handle cc_api_library module with NDK stubs and variants only which can use SDK
|
||||||
modules := ctx.CreateVariations("", "sdk")
|
modules := ctx.CreateVariations(variations...)
|
||||||
|
|
||||||
// Mark the SDK variant.
|
// Mark the SDK variant.
|
||||||
modules[1].(*Module).Properties.IsSdkVariant = true
|
modules[0].(*Module).Properties.IsSdkVariant = true
|
||||||
// SDK variant is not supposed to be installed
|
|
||||||
modules[1].(*Module).Properties.PreventInstall = true
|
|
||||||
|
|
||||||
if ctx.Config().UnbundledBuildApps() {
|
if ctx.Config().UnbundledBuildApps() {
|
||||||
// For an unbundled apps build, hide the platform variant from Make.
|
if apiLibrary.hasApexStubs() {
|
||||||
modules[0].(*Module).Properties.HideFromMake = true
|
// For an unbundled apps build, hide the platform variant from Make.
|
||||||
|
modules[1].(*Module).Properties.HideFromMake = true
|
||||||
|
modules[1].(*Module).Properties.PreventInstall = true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
|
// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
|
||||||
// exposed to Make.
|
// exposed to Make.
|
||||||
modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
|
modules[0].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
|
||||||
|
// SDK variant is not supposed to be installed
|
||||||
|
modules[0].(*Module).Properties.PreventInstall = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ccModule.Properties.Sdk_version = nil
|
ccModule.Properties.Sdk_version = nil
|
||||||
|
@@ -40,8 +40,9 @@ type ApiImports struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type apiImportsProperties struct {
|
type apiImportsProperties struct {
|
||||||
Shared_libs []string // List of C shared libraries from API surfaces
|
Shared_libs []string // List of C shared libraries from API surfaces
|
||||||
Header_libs []string // List of C header libraries from API surfaces
|
Header_libs []string // List of C header libraries from API surfaces
|
||||||
|
Apex_shared_libs []string // List of C shared libraries with APEX stubs
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'api_imports' is a module which describes modules available from API surfaces.
|
// 'api_imports' is a module which describes modules available from API surfaces.
|
||||||
@@ -60,7 +61,7 @@ func (imports *ApiImports) GenerateAndroidBuildActions(ctx android.ModuleContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ApiImportInfo struct {
|
type ApiImportInfo struct {
|
||||||
SharedLibs, HeaderLibs map[string]string
|
SharedLibs, HeaderLibs, ApexSharedLibs map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
var ApiImportsProvider = blueprint.NewMutatorProvider(ApiImportInfo{}, "deps")
|
var ApiImportsProvider = blueprint.NewMutatorProvider(ApiImportInfo{}, "deps")
|
||||||
@@ -78,10 +79,12 @@ func (imports *ApiImports) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||||||
|
|
||||||
sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
|
sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
|
||||||
headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
|
headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
|
||||||
|
apexSharedLibs := generateNameMapWithSuffix(imports.properties.Apex_shared_libs)
|
||||||
|
|
||||||
ctx.SetProvider(ApiImportsProvider, ApiImportInfo{
|
ctx.SetProvider(ApiImportsProvider, ApiImportInfo{
|
||||||
SharedLibs: sharedLibs,
|
SharedLibs: sharedLibs,
|
||||||
HeaderLibs: headerLibs,
|
HeaderLibs: headerLibs,
|
||||||
|
ApexSharedLibs: apexSharedLibs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user