Delete multitree api imports code
The mutltiree workflow has not been in use for a while. This CL cleans up the code that was added to support multitree. Details - Delete cc_api_library, cc_api_headers, cc_api_variant module types. These module types contain build rules for prebuilt stub .so and .h files - Update the DepsMutator of cc.Module to not create a dependency on a sibling cc_api_* module if it exists. e.g. do not create a dependency on libfoo.apiimports if libfoo is listed in `shared_libs`. - Remove cc_api_library from the stub/impl selection logic for cc modules Test: m nothing --no-skip-soong-tests Test: presbumits Change-Id: Ie194157fb3bbc630f384cdd9b694b0fba6786ded
This commit is contained in:
@@ -15,7 +15,6 @@ bootstrap_go_package {
|
|||||||
"soong-cc",
|
"soong-cc",
|
||||||
"soong-filesystem",
|
"soong-filesystem",
|
||||||
"soong-java",
|
"soong-java",
|
||||||
"soong-multitree",
|
|
||||||
"soong-provenance",
|
"soong-provenance",
|
||||||
"soong-python",
|
"soong-python",
|
||||||
"soong-rust",
|
"soong-rust",
|
||||||
|
@@ -32,7 +32,6 @@ import (
|
|||||||
prebuilt_etc "android/soong/etc"
|
prebuilt_etc "android/soong/etc"
|
||||||
"android/soong/filesystem"
|
"android/soong/filesystem"
|
||||||
"android/soong/java"
|
"android/soong/java"
|
||||||
"android/soong/multitree"
|
|
||||||
"android/soong/rust"
|
"android/soong/rust"
|
||||||
"android/soong/sh"
|
"android/soong/sh"
|
||||||
)
|
)
|
||||||
@@ -438,7 +437,6 @@ type apexBundle struct {
|
|||||||
android.ModuleBase
|
android.ModuleBase
|
||||||
android.DefaultableModuleBase
|
android.DefaultableModuleBase
|
||||||
android.OverridableModuleBase
|
android.OverridableModuleBase
|
||||||
multitree.ExportableModuleBase
|
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
properties apexBundleProperties
|
properties apexBundleProperties
|
||||||
@@ -1406,8 +1404,6 @@ func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Modu
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ multitree.Exportable = (*apexBundle)(nil)
|
|
||||||
|
|
||||||
func (a *apexBundle) Exportable() bool {
|
func (a *apexBundle) Exportable() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -2540,7 +2536,6 @@ func newApexBundle() *apexBundle {
|
|||||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
||||||
android.InitDefaultableModule(module)
|
android.InitDefaultableModule(module)
|
||||||
android.InitOverridableModule(module, &module.overridableProperties.Overrides)
|
android.InitOverridableModule(module, &module.overridableProperties.Overrides)
|
||||||
multitree.InitExportableModule(module)
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10274,208 +10274,6 @@ func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
|
|
||||||
bp := `
|
|
||||||
apex {
|
|
||||||
name: "myapex",
|
|
||||||
key: "myapex.key",
|
|
||||||
native_shared_libs: ["libbaz"],
|
|
||||||
binaries: ["binfoo"],
|
|
||||||
min_sdk_version: "29",
|
|
||||||
}
|
|
||||||
apex_key {
|
|
||||||
name: "myapex.key",
|
|
||||||
}
|
|
||||||
cc_binary {
|
|
||||||
name: "binfoo",
|
|
||||||
shared_libs: ["libbar", "libbaz", "libqux",],
|
|
||||||
apex_available: ["myapex"],
|
|
||||||
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 {
|
|
||||||
name: "libbar",
|
|
||||||
src: "libbar_stub.so",
|
|
||||||
min_sdk_version: "29",
|
|
||||||
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 {
|
|
||||||
name: "api_imports",
|
|
||||||
apex_shared_libs: [
|
|
||||||
"libbar",
|
|
||||||
"libbaz",
|
|
||||||
"libqux",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
`
|
|
||||||
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_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(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_apex29").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")
|
|
||||||
|
|
||||||
// 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) {
|
||||||
bp := `
|
bp := `
|
||||||
apex {
|
apex {
|
||||||
@@ -10514,21 +10312,6 @@ func TestTrimmedApex(t *testing.T) {
|
|||||||
apex_available: ["myapex","mydcla"],
|
apex_available: ["myapex","mydcla"],
|
||||||
min_sdk_version: "29",
|
min_sdk_version: "29",
|
||||||
}
|
}
|
||||||
cc_api_library {
|
|
||||||
name: "libc",
|
|
||||||
src: "libc.so",
|
|
||||||
min_sdk_version: "29",
|
|
||||||
recovery_available: true,
|
|
||||||
vendor_available: true,
|
|
||||||
product_available: true,
|
|
||||||
}
|
|
||||||
api_imports {
|
|
||||||
name: "api_imports",
|
|
||||||
shared_libs: [
|
|
||||||
"libc",
|
|
||||||
],
|
|
||||||
header_libs: [],
|
|
||||||
}
|
|
||||||
`
|
`
|
||||||
ctx := testApex(t, bp)
|
ctx := testApex(t, bp)
|
||||||
module := ctx.ModuleForTests("myapex", "android_common_myapex")
|
module := ctx.ModuleForTests("myapex", "android_common_myapex")
|
||||||
|
@@ -16,7 +16,6 @@ bootstrap_go_package {
|
|||||||
"soong-etc",
|
"soong-etc",
|
||||||
"soong-fuzz",
|
"soong-fuzz",
|
||||||
"soong-genrule",
|
"soong-genrule",
|
||||||
"soong-multitree",
|
|
||||||
"soong-testing",
|
"soong-testing",
|
||||||
"soong-tradefed",
|
"soong-tradefed",
|
||||||
],
|
],
|
||||||
@@ -65,7 +64,6 @@ bootstrap_go_package {
|
|||||||
"library.go",
|
"library.go",
|
||||||
"library_headers.go",
|
"library_headers.go",
|
||||||
"library_sdk_member.go",
|
"library_sdk_member.go",
|
||||||
"library_stub.go",
|
|
||||||
"native_bridge_sdk_trait.go",
|
"native_bridge_sdk_trait.go",
|
||||||
"object.go",
|
"object.go",
|
||||||
"test.go",
|
"test.go",
|
||||||
|
@@ -21,7 +21,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/multitree"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -479,34 +478,6 @@ func (p *prebuiltBinaryLinker) AndroidMkEntries(ctx AndroidMkContext, entries *a
|
|||||||
androidMkWritePrebuiltOptions(p.baseLinker, entries)
|
androidMkWritePrebuiltOptions(p.baseLinker, entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
|
|
||||||
entries.Class = "SHARED_LIBRARIES"
|
|
||||||
entries.SubName += multitree.GetApiImportSuffix()
|
|
||||||
|
|
||||||
entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
|
||||||
a.libraryDecorator.androidMkWriteExportedFlags(entries)
|
|
||||||
src := *a.properties.Src
|
|
||||||
path, file := filepath.Split(src)
|
|
||||||
stem, suffix, ext := android.SplitFileExt(file)
|
|
||||||
entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
|
|
||||||
entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
|
|
||||||
entries.SetString("LOCAL_MODULE_STEM", stem)
|
|
||||||
entries.SetString("LOCAL_MODULE_PATH", path)
|
|
||||||
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
|
|
||||||
entries.SetString("LOCAL_SOONG_TOC", a.toc().String())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiHeadersDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
|
|
||||||
entries.Class = "HEADER_LIBRARIES"
|
|
||||||
entries.SubName += multitree.GetApiImportSuffix()
|
|
||||||
|
|
||||||
entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
|
||||||
a.libraryDecorator.androidMkWriteExportedFlags(entries)
|
|
||||||
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkEntries) {
|
func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkEntries) {
|
||||||
allow := linker.Properties.Allow_undefined_symbols
|
allow := linker.Properties.Allow_undefined_symbols
|
||||||
if allow != nil {
|
if allow != nil {
|
||||||
|
119
cc/cc.go
119
cc/cc.go
@@ -34,7 +34,6 @@ import (
|
|||||||
"android/soong/cc/config"
|
"android/soong/cc/config"
|
||||||
"android/soong/fuzz"
|
"android/soong/fuzz"
|
||||||
"android/soong/genrule"
|
"android/soong/genrule"
|
||||||
"android/soong/multitree"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -2361,24 +2360,6 @@ func AddSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext, mo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetApiImports(c LinkableInterface, actx android.BottomUpMutatorContext) multitree.ApiImportInfo {
|
|
||||||
apiImportInfo := multitree.ApiImportInfo{}
|
|
||||||
|
|
||||||
if c.Device() {
|
|
||||||
var apiImportModule []blueprint.Module
|
|
||||||
if actx.OtherModuleExists("api_imports") {
|
|
||||||
apiImportModule = actx.AddDependency(c, nil, "api_imports")
|
|
||||||
if len(apiImportModule) > 0 && apiImportModule[0] != nil {
|
|
||||||
apiInfo, _ := android.OtherModuleProvider(actx, apiImportModule[0], multitree.ApiImportsProvider)
|
|
||||||
apiImportInfo = apiInfo
|
|
||||||
android.SetProvider(actx, multitree.ApiImportsProvider, apiInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return apiImportInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetReplaceModuleName(lib string, replaceMap map[string]string) string {
|
func GetReplaceModuleName(lib string, replaceMap map[string]string) string {
|
||||||
if snapshot, ok := replaceMap[lib]; ok {
|
if snapshot, ok := replaceMap[lib]; ok {
|
||||||
return snapshot
|
return snapshot
|
||||||
@@ -2448,11 +2429,6 @@ func (c *Module) shouldUseApiSurface() bool {
|
|||||||
// NDK Variant
|
// NDK Variant
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.isImportedApiLibrary() {
|
|
||||||
// API Library should depend on API headers
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@@ -2472,19 +2448,10 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
ctx.ctx = ctx
|
ctx.ctx = ctx
|
||||||
|
|
||||||
deps := c.deps(ctx)
|
deps := c.deps(ctx)
|
||||||
apiImportInfo := GetApiImports(c, actx)
|
|
||||||
|
|
||||||
apiNdkLibs := []string{}
|
apiNdkLibs := []string{}
|
||||||
apiLateNdkLibs := []string{}
|
apiLateNdkLibs := []string{}
|
||||||
|
|
||||||
if c.shouldUseApiSurface() {
|
|
||||||
deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, 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.ReexportHeaderLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportHeaderLibHeaders, apiImportInfo.SharedLibs, ctx.Config())
|
|
||||||
deps.ReexportSharedLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportSharedLibHeaders, apiImportInfo.SharedLibs, ctx.Config())
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs
|
c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs
|
||||||
|
|
||||||
variantNdkLibs := []string{}
|
variantNdkLibs := []string{}
|
||||||
@@ -2501,11 +2468,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
depTag.reexportFlags = true
|
depTag.reexportFlags = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check header lib replacement from API surface first, and then check again with VSDK
|
|
||||||
if c.shouldUseApiSurface() {
|
|
||||||
lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.isNDKStubLibrary() {
|
if c.isNDKStubLibrary() {
|
||||||
variationExists := actx.OtherModuleDependencyVariantExists(nil, lib)
|
variationExists := actx.OtherModuleDependencyVariantExists(nil, lib)
|
||||||
if variationExists {
|
if variationExists {
|
||||||
@@ -2515,7 +2477,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
// any variants.
|
// any variants.
|
||||||
actx.AddFarVariationDependencies([]blueprint.Variation{}, depTag, lib)
|
actx.AddFarVariationDependencies([]blueprint.Variation{}, depTag, lib)
|
||||||
}
|
}
|
||||||
} else if c.IsStubs() && !c.isImportedApiLibrary() {
|
} else if c.IsStubs() {
|
||||||
actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
|
actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
|
||||||
depTag, lib)
|
depTag, lib)
|
||||||
} else {
|
} else {
|
||||||
@@ -2591,24 +2553,14 @@ 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"},
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
|
|
||||||
AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
|
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 {
|
||||||
depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
|
depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
|
||||||
actx.AddVariationDependencies([]blueprint.Variation{
|
actx.AddVariationDependencies([]blueprint.Variation{
|
||||||
@@ -2701,7 +2653,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateImportedLibraryDependency(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BeginMutator(ctx android.BottomUpMutatorContext) {
|
func BeginMutator(ctx android.BottomUpMutatorContext) {
|
||||||
@@ -2730,10 +2681,6 @@ func checkLinkType(ctx android.BaseModuleContext, from LinkableInterface, to Lin
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/244244438) : Remove this once all variants are implemented
|
|
||||||
if ccFrom, ok := from.(*Module); ok && ccFrom.isImportedApiLibrary() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if from.SdkVersion() == "" {
|
if from.SdkVersion() == "" {
|
||||||
// Platform code can link to anything
|
// Platform code can link to anything
|
||||||
return
|
return
|
||||||
@@ -2756,10 +2703,6 @@ func checkLinkType(ctx android.BaseModuleContext, from LinkableInterface, to Lin
|
|||||||
// the NDK.
|
// the NDK.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c.isImportedApiLibrary() {
|
|
||||||
// Imported library from the API surface is a stub library built against interface definition.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Module().Name() == "libc++" {
|
if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Module().Name() == "libc++" {
|
||||||
@@ -2935,47 +2878,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
|
|
||||||
skipModuleList := map[string]bool{}
|
skipModuleList := map[string]bool{}
|
||||||
|
|
||||||
var apiImportInfo multitree.ApiImportInfo
|
|
||||||
hasApiImportInfo := false
|
|
||||||
|
|
||||||
ctx.VisitDirectDeps(func(dep android.Module) {
|
|
||||||
if dep.Name() == "api_imports" {
|
|
||||||
apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider)
|
|
||||||
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)
|
||||||
@@ -3404,17 +3306,7 @@ func ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool {
|
|||||||
// bootstrap modules, always link to non-stub variant
|
// bootstrap modules, always link to non-stub variant
|
||||||
isNotInPlatform := dep.(android.ApexModule).NotInPlatform()
|
isNotInPlatform := dep.(android.ApexModule).NotInPlatform()
|
||||||
|
|
||||||
isApexImportedApiLibrary := false
|
useStubs = isNotInPlatform && !bootstrap
|
||||||
|
|
||||||
if cc, ok := dep.(*Module); ok {
|
|
||||||
if apiLibrary, ok := cc.linker.(*apiLibraryDecorator); ok {
|
|
||||||
if apiLibrary.hasApexStubs() {
|
|
||||||
isApexImportedApiLibrary = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useStubs = (isNotInPlatform || isApexImportedApiLibrary) && !bootstrap
|
|
||||||
|
|
||||||
if useStubs {
|
if useStubs {
|
||||||
// Another exception: if this module is a test for an APEX, then
|
// Another exception: if this module is a test for an APEX, then
|
||||||
@@ -3439,7 +3331,7 @@ func ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool {
|
|||||||
// only partially overlapping apex_available. For that test_for
|
// only partially overlapping apex_available. For that test_for
|
||||||
// modules would need to be split into APEX variants and resolved
|
// modules would need to be split into APEX variants and resolved
|
||||||
// separately for each APEX they have access to.
|
// separately for each APEX they have access to.
|
||||||
if !isApexImportedApiLibrary && android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
|
if android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
|
||||||
useStubs = false
|
useStubs = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4023,11 +3915,6 @@ func (c *Module) IsSdkVariant() bool {
|
|||||||
return c.Properties.IsSdkVariant
|
return c.Properties.IsSdkVariant
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) isImportedApiLibrary() bool {
|
|
||||||
_, ok := c.linker.(*apiLibraryDecorator)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func kytheExtractAllFactory() android.Singleton {
|
func kytheExtractAllFactory() android.Singleton {
|
||||||
return &kytheExtractAllSingleton{}
|
return &kytheExtractAllSingleton{}
|
||||||
}
|
}
|
||||||
|
@@ -2350,9 +2350,8 @@ func (versionTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, varia
|
|||||||
if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
|
if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
|
||||||
isLLNDK := m.IsLlndk()
|
isLLNDK := m.IsLlndk()
|
||||||
isVendorPublicLibrary := m.IsVendorPublicLibrary()
|
isVendorPublicLibrary := m.IsVendorPublicLibrary()
|
||||||
isImportedApiLibrary := m.isImportedApiLibrary()
|
|
||||||
|
|
||||||
if variation != "" || isLLNDK || isVendorPublicLibrary || isImportedApiLibrary {
|
if variation != "" || isLLNDK || isVendorPublicLibrary {
|
||||||
// A stubs or LLNDK stubs variant.
|
// A stubs or LLNDK stubs variant.
|
||||||
if m.sanitize != nil {
|
if m.sanitize != nil {
|
||||||
m.sanitize.Properties.ForceDisable = true
|
m.sanitize.Properties.ForceDisable = true
|
||||||
|
@@ -1,512 +0,0 @@
|
|||||||
// Copyright 2021 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package cc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"android/soong/android"
|
|
||||||
"android/soong/multitree"
|
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
|
|
||||||
stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterLibraryStubBuildComponents(android.InitRegistrationContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
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.InVendorOrProduct() && apiLibrary.hasLLNDKStubs() {
|
|
||||||
// Add LLNDK variant dependency
|
|
||||||
if inList("llndk", apiLibrary.properties.Variants) {
|
|
||||||
variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
|
|
||||||
ctx.AddDependency(m, nil, variantName)
|
|
||||||
}
|
|
||||||
} else if m.IsSdkVariant() {
|
|
||||||
// Add NDK variant dependencies
|
|
||||||
targetVariant := "ndk." + m.StubsVersion()
|
|
||||||
if inList(targetVariant, apiLibrary.properties.Variants) {
|
|
||||||
variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'cc_api_library' is a module type which is from the exported API surface
|
|
||||||
// with C shared library type. The module will replace original module, and
|
|
||||||
// offer a link to the module that generates shared library object from the
|
|
||||||
// map file.
|
|
||||||
type apiLibraryProperties struct {
|
|
||||||
Src *string `android:"arch_variant"`
|
|
||||||
Variants []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiLibraryDecorator struct {
|
|
||||||
*libraryDecorator
|
|
||||||
properties apiLibraryProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
func CcApiLibraryFactory() android.Module {
|
|
||||||
module, decorator := NewLibrary(android.DeviceSupported)
|
|
||||||
apiLibraryDecorator := &apiLibraryDecorator{
|
|
||||||
libraryDecorator: decorator,
|
|
||||||
}
|
|
||||||
apiLibraryDecorator.BuildOnlyShared()
|
|
||||||
|
|
||||||
module.stl = nil
|
|
||||||
module.sanitize = nil
|
|
||||||
decorator.disableStripping()
|
|
||||||
|
|
||||||
module.compiler = nil
|
|
||||||
module.linker = apiLibraryDecorator
|
|
||||||
module.installer = nil
|
|
||||||
module.library = apiLibraryDecorator
|
|
||||||
module.AddProperties(&module.Properties, &apiLibraryDecorator.properties)
|
|
||||||
|
|
||||||
// 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{}
|
|
||||||
}
|
|
||||||
|
|
||||||
apiLibraryDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
|
|
||||||
apiLibraryDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
|
|
||||||
|
|
||||||
module.Init()
|
|
||||||
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) Name(basename string) string {
|
|
||||||
return basename + multitree.GetApiImportSuffix()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export include dirs without checking for existence.
|
|
||||||
// The directories are not guaranteed to exist during Soong analysis.
|
|
||||||
func (d *apiLibraryDecorator) exportIncludes(ctx ModuleContext) {
|
|
||||||
exporterProps := d.flagExporter.Properties
|
|
||||||
for _, dir := range exporterProps.Export_include_dirs.GetOrDefault(ctx, nil) {
|
|
||||||
d.dirs = append(d.dirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir))
|
|
||||||
}
|
|
||||||
// system headers
|
|
||||||
for _, dir := range exporterProps.Export_system_include_dirs {
|
|
||||||
d.systemDirs = append(d.systemDirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) linkerInit(ctx BaseModuleContext) {
|
|
||||||
d.baseLinker.linkerInit(ctx)
|
|
||||||
|
|
||||||
if d.hasNDKStubs() {
|
|
||||||
// Set SDK version of module as current
|
|
||||||
ctx.Module().(*Module).Properties.Sdk_version = StringPtr("current")
|
|
||||||
|
|
||||||
// Add NDK stub as NDK known libs
|
|
||||||
name := ctx.ModuleName()
|
|
||||||
|
|
||||||
ndkKnownLibsLock.Lock()
|
|
||||||
ndkKnownLibs := getNDKKnownLibs(ctx.Config())
|
|
||||||
if !inList(name, *ndkKnownLibs) {
|
|
||||||
*ndkKnownLibs = append(*ndkKnownLibs, name)
|
|
||||||
}
|
|
||||||
ndkKnownLibsLock.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
|
|
||||||
m, _ := ctx.Module().(*Module)
|
|
||||||
|
|
||||||
var in android.Path
|
|
||||||
|
|
||||||
// src might not exist during the beginning of soong analysis in Multi-tree
|
|
||||||
if src := String(d.properties.Src); src != "" {
|
|
||||||
in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
|
|
||||||
}
|
|
||||||
|
|
||||||
libName := m.BaseModuleName() + multitree.GetApiImportSuffix()
|
|
||||||
|
|
||||||
load_cc_variant := func(apiVariantModule string) {
|
|
||||||
var mod android.Module
|
|
||||||
|
|
||||||
ctx.VisitDirectDeps(func(depMod android.Module) {
|
|
||||||
if depMod.Name() == apiVariantModule {
|
|
||||||
mod = depMod
|
|
||||||
libName = apiVariantModule
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if mod != nil {
|
|
||||||
variantMod, ok := mod.(*CcApiVariant)
|
|
||||||
if ok {
|
|
||||||
in = variantMod.Src()
|
|
||||||
|
|
||||||
// Copy LLDNK properties to cc_api_library module
|
|
||||||
exportIncludeDirs := append(d.libraryDecorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil),
|
|
||||||
variantMod.exportProperties.Export_include_dirs...)
|
|
||||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](
|
|
||||||
nil,
|
|
||||||
[]proptools.ConfigurableCase[[]string]{
|
|
||||||
proptools.NewConfigurableCase[[]string](nil, &exportIncludeDirs),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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.GetOrDefault(ctx, nil)...)
|
|
||||||
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](nil, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.InVendorOrProduct() && d.hasLLNDKStubs() {
|
|
||||||
// LLNDK variant
|
|
||||||
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", ""))
|
|
||||||
} else if m.IsSdkVariant() {
|
|
||||||
// NDK Variant
|
|
||||||
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion()))
|
|
||||||
} else if m.IsStubs() {
|
|
||||||
// APEX Variant
|
|
||||||
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
|
|
||||||
d.exportIncludes(ctx)
|
|
||||||
d.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
|
|
||||||
d.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
|
|
||||||
d.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
|
|
||||||
d.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
|
|
||||||
d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
|
|
||||||
|
|
||||||
if in == nil {
|
|
||||||
ctx.PropertyErrorf("src", "Unable to locate source property")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
// Creating this dependency ensures that the headers are assembled before compilation of rdeps begins.
|
|
||||||
d.libraryDecorator.reexportDeps(in)
|
|
||||||
d.libraryDecorator.flagExporter.setProvider(ctx)
|
|
||||||
|
|
||||||
d.unstrippedOutputFile = in
|
|
||||||
libName += flags.Toolchain.ShlibSuffix()
|
|
||||||
|
|
||||||
tocFile := android.PathForModuleOut(ctx, libName+".toc")
|
|
||||||
d.tocFile = android.OptionalPathForPath(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",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
|
|
||||||
SharedLibrary: outputFile,
|
|
||||||
Target: ctx.Target(),
|
|
||||||
|
|
||||||
TableOfContents: d.tocFile,
|
|
||||||
})
|
|
||||||
|
|
||||||
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, _ := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
|
|
||||||
flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
|
|
||||||
stubsInfo = append(stubsInfo, SharedStubLibrary{
|
|
||||||
Version: moduleLibraryInterface(stub).stubsVersion(),
|
|
||||||
SharedLibraryInfo: stubInfo,
|
|
||||||
FlagExporterInfo: flagInfo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
|
|
||||||
SharedStubLibraries: stubsInfo,
|
|
||||||
|
|
||||||
IsLLNDK: ctx.IsLlndk(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) availableFor(what string) bool {
|
|
||||||
// Stub from API surface should be available for any APEX.
|
|
||||||
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.BaseModuleContext) []string {
|
|
||||||
m, ok := ctx.Module().(*Module)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(b/244244438) Create more version information for NDK and APEX variations
|
|
||||||
// NDK variants
|
|
||||||
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.
|
|
||||||
if d.hasNDKStubs() {
|
|
||||||
return d.getNdkVersions()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.hasLLNDKStubs() && m.InVendorOrProduct() {
|
|
||||||
// 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() == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
firstVersion, err := nativeApiLevelFromUser(ctx,
|
|
||||||
m.MinSdkVersion())
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return ndkLibraryVersions(ctx, firstVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) hasLLNDKStubs() bool {
|
|
||||||
return inList("llndk", d.properties.Variants)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) hasNDKStubs() bool {
|
|
||||||
for _, variant := range d.properties.Variants {
|
|
||||||
if ndkVariantRegex.MatchString(variant) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiLibraryDecorator) getNdkVersions() []string {
|
|
||||||
ndkVersions := []string{}
|
|
||||||
|
|
||||||
for _, variant := range d.properties.Variants {
|
|
||||||
if match := ndkVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
|
|
||||||
ndkVersions = append(ndkVersions, match[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
// header libraries. The module will replace any dependencies to existing
|
|
||||||
// original header libraries.
|
|
||||||
type apiHeadersDecorator struct {
|
|
||||||
*libraryDecorator
|
|
||||||
}
|
|
||||||
|
|
||||||
func CcApiHeadersFactory() android.Module {
|
|
||||||
module, decorator := NewLibrary(android.DeviceSupported)
|
|
||||||
apiHeadersDecorator := &apiHeadersDecorator{
|
|
||||||
libraryDecorator: decorator,
|
|
||||||
}
|
|
||||||
apiHeadersDecorator.HeaderOnly()
|
|
||||||
|
|
||||||
module.stl = nil
|
|
||||||
module.sanitize = nil
|
|
||||||
decorator.disableStripping()
|
|
||||||
|
|
||||||
module.compiler = nil
|
|
||||||
module.linker = apiHeadersDecorator
|
|
||||||
module.installer = nil
|
|
||||||
|
|
||||||
// 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{}
|
|
||||||
}
|
|
||||||
|
|
||||||
apiHeadersDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
|
|
||||||
apiHeadersDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
|
|
||||||
|
|
||||||
module.Init()
|
|
||||||
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *apiHeadersDecorator) Name(basename string) string {
|
|
||||||
return basename + multitree.GetApiImportSuffix()
|
|
||||||
}
|
|
||||||
|
|
||||||
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 to export
|
|
||||||
Export_include_dirs []string `android:"arch_variant"`
|
|
||||||
|
|
||||||
// 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 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(), String(v.properties.Src))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *CcApiVariant) Name() string {
|
|
||||||
version := 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) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
||||||
return String(v.properties.Variant) == "llndk"
|
|
||||||
}
|
|
||||||
func (v *CcApiVariant) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
||||||
return String(v.properties.Variant) == "llndk"
|
|
||||||
}
|
|
||||||
func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
|
|
||||||
return inList(String(v.properties.Variant), []string{"ndk", "apex"})
|
|
||||||
}
|
|
||||||
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 { return nil }
|
|
||||||
func (v *CcApiVariant) SetImageVariation(ctx android.BaseModuleContext, variation string) {
|
|
||||||
}
|
|
12
cc/sdk.go
12
cc/sdk.go
@@ -51,13 +51,6 @@ func (sdkTransitionMutator) Split(ctx android.BaseModuleContext) []string {
|
|||||||
return []string{""}
|
return []string{""}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *CcApiVariant:
|
|
||||||
ccApiVariant, _ := ctx.Module().(*CcApiVariant)
|
|
||||||
if String(ccApiVariant.properties.Variant) == "ndk" {
|
|
||||||
return []string{"sdk"}
|
|
||||||
} else {
|
|
||||||
return []string{""}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{""}
|
return []string{""}
|
||||||
@@ -84,11 +77,6 @@ func (sdkTransitionMutator) IncomingTransition(ctx android.IncomingTransitionCon
|
|||||||
return incomingVariation
|
return incomingVariation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *CcApiVariant:
|
|
||||||
ccApiVariant, _ := ctx.Module().(*CcApiVariant)
|
|
||||||
if String(ccApiVariant.properties.Variant) == "ndk" {
|
|
||||||
return "sdk"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.IsAddingDependency() {
|
if ctx.IsAddingDependency() {
|
||||||
|
@@ -20,7 +20,6 @@ import (
|
|||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/genrule"
|
"android/soong/genrule"
|
||||||
"android/soong/multitree"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
|
func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
|
||||||
@@ -29,9 +28,6 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
|
|||||||
RegisterBinaryBuildComponents(ctx)
|
RegisterBinaryBuildComponents(ctx)
|
||||||
RegisterLibraryBuildComponents(ctx)
|
RegisterLibraryBuildComponents(ctx)
|
||||||
RegisterLibraryHeadersBuildComponents(ctx)
|
RegisterLibraryHeadersBuildComponents(ctx)
|
||||||
RegisterLibraryStubBuildComponents(ctx)
|
|
||||||
|
|
||||||
multitree.RegisterApiImportsModule(ctx)
|
|
||||||
|
|
||||||
ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool)
|
ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool)
|
||||||
ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)
|
ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)
|
||||||
|
@@ -1,20 +0,0 @@
|
|||||||
package {
|
|
||||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap_go_package {
|
|
||||||
name: "soong-multitree",
|
|
||||||
pkgPath: "android/soong/multitree",
|
|
||||||
deps: [
|
|
||||||
"blueprint",
|
|
||||||
"soong-android",
|
|
||||||
],
|
|
||||||
srcs: [
|
|
||||||
"api_imports.go",
|
|
||||||
"api_surface.go",
|
|
||||||
"export.go",
|
|
||||||
"metadata.go",
|
|
||||||
"import.go",
|
|
||||||
],
|
|
||||||
pluginFor: ["soong_build"],
|
|
||||||
}
|
|
@@ -1,102 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package multitree
|
|
||||||
|
|
||||||
import (
|
|
||||||
"android/soong/android"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
apiImportNameSuffix = ".apiimport"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterApiImportsModule(android.InitRegistrationContext)
|
|
||||||
android.RegisterMakeVarsProvider(pctx, makeVarsProvider)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterApiImportsModule(ctx android.RegistrationContext) {
|
|
||||||
ctx.RegisterModuleType("api_imports", apiImportsFactory)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApiImports struct {
|
|
||||||
android.ModuleBase
|
|
||||||
properties apiImportsProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiImportsProperties struct {
|
|
||||||
Shared_libs []string // List of C shared 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.
|
|
||||||
// This module is required to get the list of all imported API modules, because
|
|
||||||
// it is discouraged to loop and fetch all modules from its type information. The
|
|
||||||
// only module with name 'api_imports' will be used from the build.
|
|
||||||
func apiImportsFactory() android.Module {
|
|
||||||
module := &ApiImports{}
|
|
||||||
module.AddProperties(&module.properties)
|
|
||||||
android.InitAndroidModule(module)
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
func (imports *ApiImports) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
||||||
// ApiImport module does not generate any build actions
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApiImportInfo struct {
|
|
||||||
SharedLibs, HeaderLibs, ApexSharedLibs map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
var ApiImportsProvider = blueprint.NewMutatorProvider[ApiImportInfo]("deps")
|
|
||||||
|
|
||||||
// Store module lists into ApiImportInfo and share it over mutator provider.
|
|
||||||
func (imports *ApiImports) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
||||||
generateNameMapWithSuffix := func(names []string) map[string]string {
|
|
||||||
moduleNameMap := make(map[string]string)
|
|
||||||
for _, name := range names {
|
|
||||||
moduleNameMap[name] = name + apiImportNameSuffix
|
|
||||||
}
|
|
||||||
|
|
||||||
return moduleNameMap
|
|
||||||
}
|
|
||||||
|
|
||||||
sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
|
|
||||||
headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
|
|
||||||
apexSharedLibs := generateNameMapWithSuffix(imports.properties.Apex_shared_libs)
|
|
||||||
|
|
||||||
android.SetProvider(ctx, ApiImportsProvider, ApiImportInfo{
|
|
||||||
SharedLibs: sharedLibs,
|
|
||||||
HeaderLibs: headerLibs,
|
|
||||||
ApexSharedLibs: apexSharedLibs,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetApiImportSuffix() string {
|
|
||||||
return apiImportNameSuffix
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeVarsProvider(ctx android.MakeVarsContext) {
|
|
||||||
ctx.VisitAllModules(func(m android.Module) {
|
|
||||||
if i, ok := m.(*ApiImports); ok {
|
|
||||||
ctx.Strict("API_IMPORTED_SHARED_LIBRARIES", strings.Join(i.properties.Shared_libs, " "))
|
|
||||||
ctx.Strict("API_IMPORTED_HEADER_LIBRARIES", strings.Join(i.properties.Header_libs, " "))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@@ -1,109 +0,0 @@
|
|||||||
// Copyright 2021 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package multitree
|
|
||||||
|
|
||||||
import (
|
|
||||||
"android/soong/android"
|
|
||||||
"github.com/google/blueprint"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
pctx = android.NewPackageContext("android/soong/multitree")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterApiSurfaceBuildComponents(android.InitRegistrationContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
var PrepareForTestWithApiSurface = android.FixtureRegisterWithContext(RegisterApiSurfaceBuildComponents)
|
|
||||||
|
|
||||||
func RegisterApiSurfaceBuildComponents(ctx android.RegistrationContext) {
|
|
||||||
ctx.RegisterModuleType("api_surface", ApiSurfaceFactory)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApiSurface struct {
|
|
||||||
android.ModuleBase
|
|
||||||
ExportableModuleBase
|
|
||||||
properties apiSurfaceProperties
|
|
||||||
|
|
||||||
taggedOutputs map[string]android.Paths
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiSurfaceProperties struct {
|
|
||||||
Contributions []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func ApiSurfaceFactory() android.Module {
|
|
||||||
module := &ApiSurface{}
|
|
||||||
module.AddProperties(&module.properties)
|
|
||||||
android.InitAndroidModule(module)
|
|
||||||
InitExportableModule(module)
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
func (surface *ApiSurface) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
||||||
if surface.properties.Contributions != nil {
|
|
||||||
ctx.AddVariationDependencies(nil, nil, surface.properties.Contributions...)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
func (surface *ApiSurface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
||||||
contributionFiles := make(map[string]android.Paths)
|
|
||||||
var allOutputs android.Paths
|
|
||||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
|
||||||
if contribution, ok := child.(ApiContribution); ok {
|
|
||||||
copied := contribution.CopyFilesWithTag(ctx)
|
|
||||||
for tag, files := range copied {
|
|
||||||
contributionFiles[child.Name()+"#"+tag] = files
|
|
||||||
}
|
|
||||||
for _, paths := range copied {
|
|
||||||
allOutputs = append(allOutputs, paths...)
|
|
||||||
}
|
|
||||||
return false // no transitive dependencies
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// phony target
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: blueprint.Phony,
|
|
||||||
Output: android.PathForPhony(ctx, ctx.ModuleName()),
|
|
||||||
Inputs: allOutputs,
|
|
||||||
})
|
|
||||||
|
|
||||||
surface.taggedOutputs = contributionFiles
|
|
||||||
|
|
||||||
ctx.SetOutputFiles(allOutputs, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (surface *ApiSurface) TaggedOutputs() map[string]android.Paths {
|
|
||||||
return surface.taggedOutputs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (surface *ApiSurface) Exportable() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ Exportable = (*ApiSurface)(nil)
|
|
||||||
|
|
||||||
type ApiContribution interface {
|
|
||||||
// copy files necessaryt to construct an API surface
|
|
||||||
// For C, it will be map.txt and .h files
|
|
||||||
// For Java, it will be api.txt
|
|
||||||
CopyFilesWithTag(ctx android.ModuleContext) map[string]android.Paths // output paths
|
|
||||||
|
|
||||||
// Generate Android.bp in out/ to use the exported .txt files
|
|
||||||
// GenerateBuildFiles(ctx ModuleContext) Paths //output paths
|
|
||||||
}
|
|
@@ -1,66 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package multitree
|
|
||||||
|
|
||||||
import (
|
|
||||||
"android/soong/android"
|
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
|
||||||
)
|
|
||||||
|
|
||||||
type moduleExportProperty struct {
|
|
||||||
// True if the module is exported to the other components in a multi-tree.
|
|
||||||
// Any components in the multi-tree can import this module to use.
|
|
||||||
Export *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExportableModuleBase struct {
|
|
||||||
properties moduleExportProperty
|
|
||||||
}
|
|
||||||
|
|
||||||
type Exportable interface {
|
|
||||||
// Properties for the exporable module.
|
|
||||||
exportableModuleProps() *moduleExportProperty
|
|
||||||
|
|
||||||
// Check if this module can be exported.
|
|
||||||
// If this returns false, the module will not be exported regardless of the 'export' value.
|
|
||||||
Exportable() bool
|
|
||||||
|
|
||||||
// Returns 'true' if this module has 'export: true'
|
|
||||||
// This module will not be exported if it returns 'false' to 'Exportable()' interface even if
|
|
||||||
// it has 'export: true'.
|
|
||||||
IsExported() bool
|
|
||||||
|
|
||||||
// Map from tags to outputs.
|
|
||||||
// Each module can tag their outputs for convenience.
|
|
||||||
TaggedOutputs() map[string]android.Paths
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExportableModule interface {
|
|
||||||
android.Module
|
|
||||||
Exportable
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitExportableModule(module ExportableModule) {
|
|
||||||
module.AddProperties(module.exportableModuleProps())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ExportableModuleBase) exportableModuleProps() *moduleExportProperty {
|
|
||||||
return &m.properties
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ExportableModuleBase) IsExported() bool {
|
|
||||||
return proptools.Bool(m.properties.Export)
|
|
||||||
}
|
|
@@ -1,96 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package multitree
|
|
||||||
|
|
||||||
import (
|
|
||||||
"android/soong/android"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
nameSuffix = ".imported"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MultitreeImportedModuleInterface interface {
|
|
||||||
GetMultitreeImportedModuleName() string
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
android.RegisterModuleType("imported_filegroup", importedFileGroupFactory)
|
|
||||||
|
|
||||||
android.PreArchMutators(RegisterMultitreePreArchMutators)
|
|
||||||
}
|
|
||||||
|
|
||||||
type importedFileGroupProperties struct {
|
|
||||||
// Imported modules from the other components in a multi-tree
|
|
||||||
Imported []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type importedFileGroup struct {
|
|
||||||
android.ModuleBase
|
|
||||||
|
|
||||||
properties importedFileGroupProperties
|
|
||||||
srcs android.Paths
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ifg *importedFileGroup) Name() string {
|
|
||||||
return ifg.BaseModuleName() + nameSuffix
|
|
||||||
}
|
|
||||||
|
|
||||||
func importedFileGroupFactory() android.Module {
|
|
||||||
module := &importedFileGroup{}
|
|
||||||
module.AddProperties(&module.properties)
|
|
||||||
|
|
||||||
android.InitAndroidModule(module)
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ MultitreeImportedModuleInterface = (*importedFileGroup)(nil)
|
|
||||||
|
|
||||||
func (ifg *importedFileGroup) GetMultitreeImportedModuleName() string {
|
|
||||||
// The base module name of the imported filegroup is used as the imported module name
|
|
||||||
return ifg.BaseModuleName()
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ android.SourceFileProducer = (*importedFileGroup)(nil)
|
|
||||||
|
|
||||||
func (ifg *importedFileGroup) Srcs() android.Paths {
|
|
||||||
return ifg.srcs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ifg *importedFileGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
||||||
// srcs from this module must not be used. Adding a dot path to avoid the empty
|
|
||||||
// source failure. Still soong returns error when a module wants to build against
|
|
||||||
// this source, which is intended.
|
|
||||||
ifg.srcs = android.PathsForModuleSrc(ctx, []string{"."})
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterMultitreePreArchMutators(ctx android.RegisterMutatorsContext) {
|
|
||||||
ctx.BottomUp("multitree_imported_rename", MultitreeImportedRenameMutator).Parallel()
|
|
||||||
}
|
|
||||||
|
|
||||||
func MultitreeImportedRenameMutator(ctx android.BottomUpMutatorContext) {
|
|
||||||
if m, ok := ctx.Module().(MultitreeImportedModuleInterface); ok {
|
|
||||||
name := m.GetMultitreeImportedModuleName()
|
|
||||||
if !ctx.OtherModuleExists(name) {
|
|
||||||
// Provide an empty filegroup not to break the build while updating the metadata.
|
|
||||||
// In other cases, soong will report an error to guide users to run 'm update-meta'
|
|
||||||
// first.
|
|
||||||
if !ctx.Config().TargetMultitreeUpdateMeta() {
|
|
||||||
ctx.ModuleErrorf("\"%s\" filegroup must be imported.\nRun 'm update-meta' first to import the filegroup.", name)
|
|
||||||
}
|
|
||||||
ctx.Rename(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,74 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package multitree
|
|
||||||
|
|
||||||
import (
|
|
||||||
"android/soong/android"
|
|
||||||
"encoding/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
android.RegisterParallelSingletonType("update-meta", UpdateMetaSingleton)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateMetaSingleton() android.Singleton {
|
|
||||||
return &updateMetaSingleton{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsonImported struct {
|
|
||||||
FileGroups map[string][]string `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type metadataJsonFlags struct {
|
|
||||||
Imported jsonImported `json:",omitempty"`
|
|
||||||
Exported map[string][]string `json:",omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type updateMetaSingleton struct {
|
|
||||||
importedModules []string
|
|
||||||
generatedMetadataFile android.OutputPath
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *updateMetaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
|
||||||
metadata := metadataJsonFlags{
|
|
||||||
Imported: jsonImported{
|
|
||||||
FileGroups: make(map[string][]string),
|
|
||||||
},
|
|
||||||
Exported: make(map[string][]string),
|
|
||||||
}
|
|
||||||
ctx.VisitAllModules(func(module android.Module) {
|
|
||||||
if ifg, ok := module.(*importedFileGroup); ok {
|
|
||||||
metadata.Imported.FileGroups[ifg.BaseModuleName()] = ifg.properties.Imported
|
|
||||||
}
|
|
||||||
if e, ok := module.(ExportableModule); ok {
|
|
||||||
if e.IsExported() && e.Exportable() {
|
|
||||||
for tag, files := range e.TaggedOutputs() {
|
|
||||||
// TODO(b/219846705): refactor this to a dictionary
|
|
||||||
metadata.Exported[e.Name()+":"+tag] = append(metadata.Exported[e.Name()+":"+tag], files.Strings()...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
jsonStr, err := json.Marshal(metadata)
|
|
||||||
if err != nil {
|
|
||||||
ctx.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
s.generatedMetadataFile = android.PathForOutput(ctx, "multitree", "metadata.json")
|
|
||||||
android.WriteFileRule(ctx, s.generatedMetadataFile, string(jsonStr))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *updateMetaSingleton) MakeVars(ctx android.MakeVarsContext) {
|
|
||||||
ctx.Strict("MULTITREE_METADATA", s.generatedMetadataFile.String())
|
|
||||||
}
|
|
57
rust/rust.go
57
rust/rust.go
@@ -29,7 +29,6 @@ import (
|
|||||||
"android/soong/cc"
|
"android/soong/cc"
|
||||||
cc_config "android/soong/cc/config"
|
cc_config "android/soong/cc/config"
|
||||||
"android/soong/fuzz"
|
"android/soong/fuzz"
|
||||||
"android/soong/multitree"
|
|
||||||
"android/soong/rust/config"
|
"android/soong/rust/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1218,47 +1217,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
|
|
||||||
skipModuleList := map[string]bool{}
|
skipModuleList := map[string]bool{}
|
||||||
|
|
||||||
var apiImportInfo multitree.ApiImportInfo
|
|
||||||
hasApiImportInfo := false
|
|
||||||
|
|
||||||
ctx.VisitDirectDeps(func(dep android.Module) {
|
|
||||||
if dep.Name() == "api_imports" {
|
|
||||||
apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider)
|
|
||||||
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 cc.ShouldUseStubForApex(ctx, dep) {
|
|
||||||
skipModuleList[depName] = true
|
|
||||||
} else {
|
|
||||||
skipModuleList[apiLibrary] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var transitiveAndroidMkSharedLibs []*android.DepSet[string]
|
var transitiveAndroidMkSharedLibs []*android.DepSet[string]
|
||||||
var directAndroidMkSharedLibs []string
|
var directAndroidMkSharedLibs []string
|
||||||
|
|
||||||
@@ -1609,13 +1567,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
deps := mod.deps(ctx)
|
deps := mod.deps(ctx)
|
||||||
var commonDepVariations []blueprint.Variation
|
var commonDepVariations []blueprint.Variation
|
||||||
|
|
||||||
apiImportInfo := cc.GetApiImports(mod, actx)
|
|
||||||
if mod.usePublicApi() || mod.useVendorApi() {
|
|
||||||
for idx, lib := range deps.SharedLibs {
|
|
||||||
deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.Os() == android.Android {
|
if ctx.Os() == android.Android {
|
||||||
deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs)
|
deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs)
|
||||||
}
|
}
|
||||||
@@ -1708,17 +1659,9 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
variations := []blueprint.Variation{
|
variations := []blueprint.Variation{
|
||||||
{Mutator: "link", Variation: "shared"},
|
{Mutator: "link", Variation: "shared"},
|
||||||
}
|
}
|
||||||
// For core variant, add a dep on the implementation (if it exists) and its .apiimport (if it exists)
|
|
||||||
// GenerateAndroidBuildActions will pick the correct impl/stub based on the api_domain boundary
|
|
||||||
if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
|
|
||||||
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
|
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok {
|
|
||||||
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, apiLibraryName, version, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, lib := range deps.WholeStaticLibs {
|
for _, lib := range deps.WholeStaticLibs {
|
||||||
depTag := cc.StaticDepTag(true)
|
depTag := cc.StaticDepTag(true)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user