Loading apex/apex_test.go +58 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import ( "strings" "testing" "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" Loading Loading @@ -9544,6 +9545,63 @@ func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) { } } func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) { bp := ` apex { name: "myapex", key: "myapex.key", native_shared_libs: ["libfoo"], min_sdk_version: "29", } apex_key { name: "myapex.key", } cc_library { name: "libfoo", shared_libs: ["libc"], apex_available: ["myapex"], min_sdk_version: "29", } cc_api_library { name: "libc", src: "libc.so", min_sdk_version: "29", recovery_available: true, } api_imports { name: "api_imports", shared_libs: [ "libc", ], header_libs: [], } ` 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 } libfooApexVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex29").Module() libcApexVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared_apex29").Module() android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(libfooApexVariant, libcApexVariant)) // libfoo core variant should be buildable in the same inner tree since // certain mcombo files might build system and apexes in the same inner tree // libfoo core variant should link against source libc libfooCoreVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 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)) } func TestMain(m *testing.M) { os.Exit(m.Run()) } cc/cc.go +88 −25 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import ( "android/soong/cc/config" "android/soong/fuzz" "android/soong/genrule" "android/soong/multitree" "android/soong/snapshot" ) Loading Loading @@ -2183,6 +2184,24 @@ 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 := actx.OtherModuleProvider(apiImportModule[0], multitree.ApiImportsProvider).(multitree.ApiImportInfo) apiImportInfo = apiInfo actx.SetProvider(multitree.ApiImportsProvider, apiInfo) } } } return apiImportInfo } func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo { // Only device modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of // SnapshotInfo, which provides no mappings. Loading @@ -2208,8 +2227,8 @@ func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android. return **snapshotInfo } func RewriteSnapshotLib(lib string, snapshotMap map[string]string) string { if snapshot, ok := snapshotMap[lib]; ok { func GetReplaceModuleName(lib string, replaceMap map[string]string) string { if snapshot, ok := replaceMap[lib]; ok { return snapshot } Loading @@ -2220,12 +2239,17 @@ func RewriteSnapshotLib(lib string, snapshotMap map[string]string) string { // of names: // // 1. Name of an NDK library that refers to a prebuilt module. // // For each of these, it adds the name of the prebuilt module (which will be in // prebuilts/ndk) to the list of nonvariant libs. // // 2. Name of an NDK library that refers to an ndk_library module. // // For each of these, it adds the name of the ndk_library module to the list of // variant libs. // // 3. Anything else (so anything that isn't an NDK library). // // It adds these to the nonvariantLibs list. // // The caller can then know to add the variantLibs dependencies differently from the Loading @@ -2238,11 +2262,11 @@ func RewriteLibs(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android. // strip #version suffix out name, _ := StubsLibNameAndVersion(entry) if c.InRecovery() { nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) } else if c.UseSdk() && inList(name, *getNDKKnownLibs(config)) { variantLibs = append(variantLibs, name+ndkLibrarySuffix) } else if c.UseVndk() { nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) } else { // put name#version back nonvariantLibs = append(nonvariantLibs, entry) Loading @@ -2251,6 +2275,25 @@ func RewriteLibs(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android. return nonvariantLibs, variantLibs } func updateDepsWithApiImports(deps Deps, apiImports multitree.ApiImportInfo) Deps { for idx, lib := range deps.SharedLibs { deps.SharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs) } for idx, lib := range deps.LateSharedLibs { deps.LateSharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs) } for idx, lib := range deps.RuntimeLibs { deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs) } for idx, lib := range deps.HeaderLibs { deps.HeaderLibs[idx] = GetReplaceModuleName(lib, apiImports.HeaderLibs) } return deps } func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if !c.Enabled() { return Loading @@ -2266,6 +2309,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps := c.deps(ctx) apiImportInfo := GetApiImports(c, actx) deps = updateDepsWithApiImports(deps, apiImportInfo) c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs var snapshotInfo *SnapshotInfo Loading @@ -2278,7 +2324,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps.ReexportSharedLibHeaders, _ = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.ReexportSharedLibHeaders) for idx, lib := range deps.RuntimeLibs { deps.RuntimeLibs[idx] = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs) deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs) } } Loading @@ -2288,7 +2334,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag.reexportFlags = true } lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs) lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs) if c.IsStubs() { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), Loading @@ -2301,11 +2347,21 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if c.isNDKStubLibrary() { // NDK stubs depend on their implementation because the ABI dumps are // generated from the implementation library. apiImportName := c.BaseModuleName() + multitree.GetApiImportSuffix() // If original library exists as imported API, set dependency on the imported library if actx.OtherModuleExists(apiImportName) { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation(), blueprint.Variation{Mutator: "link", Variation: "shared"}, ), stubImplementation, apiImportName) } else { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation(), blueprint.Variation{Mutator: "link", Variation: "shared"}, ), stubImplementation, c.BaseModuleName()) } } // sysprop_library has to support both C++ and Java. So sysprop_library internally creates one // C++ implementation library and one Java implementation library. When a module links against Loading @@ -2320,7 +2376,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { lib = impl } lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, Loading @@ -2340,7 +2396,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { lib = impl } lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, Loading @@ -2354,7 +2410,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, RewriteSnapshotLib(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) }, depTag, GetReplaceModuleName(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) } // shared lib names without the #version suffix Loading Loading @@ -2386,14 +2442,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) } for _, lib := range deps.UnexportedStaticLibs { depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, unexportedSymbols: true} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) } for _, lib := range deps.LateSharedLibs { Loading Loading @@ -2434,11 +2490,11 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...) for _, crt := range deps.CrtBegin { actx.AddVariationDependencies(crtVariations, CrtBeginDepTag, RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) } for _, crt := range deps.CrtEnd { actx.AddVariationDependencies(crtVariations, CrtEndDepTag, RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) } if deps.DynamicLinker != "" { actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker) Loading @@ -2463,7 +2519,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { actx.AddVariationDependencies([]blueprint.Variation{ c.ImageVariation(), {Mutator: "link", Variation: "shared"}, }, vndkExtDepTag, RewriteSnapshotLib(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs)) }, vndkExtDepTag, GetReplaceModuleName(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs)) } } } Loading Loading @@ -3185,6 +3241,11 @@ func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableI return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix() } // Remove API import suffix if exists if _, ok := ccDepModule.linker.(*apiLibraryDecorator); ok { libName = strings.TrimSuffix(libName, multitree.GetApiImportSuffix()) } } if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && Loading Loading @@ -3520,6 +3581,10 @@ func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, if _, ok := c.linker.(prebuiltLinkerInterface); ok { return nil } if _, ok := c.linker.(*apiLibraryDecorator); ok { return nil } minSdkVersion := c.MinSdkVersion() if minSdkVersion == "apex_inherit" { return nil Loading Loading @@ -3637,9 +3702,7 @@ func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } } // // Defaults // type Defaults struct { android.ModuleBase android.DefaultsModuleBase Loading cc/library_stub.go +87 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package cc import ( "android/soong/android" "android/soong/multitree" "strings" ) func init() { Loading @@ -25,10 +26,96 @@ func init() { func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) { // cc_api_stub_library shares a lot of ndk_library, and this will be refactored later ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory) ctx.RegisterModuleType("cc_api_stub_library", CcApiStubLibraryFactory) ctx.RegisterModuleType("cc_api_contribution", CcApiContributionFactory) } // '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"` } 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.AddProperties(&module.Properties, &apiLibraryDecorator.properties) // Mark module as stub, so APEX would not include this stub in the package. module.library.setBuildStubs(true) // Prevent default system libs (libc, libm, and libdl) from being linked if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil { apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{} } module.Init() return module } func (d *apiLibraryDecorator) Name(basename string) string { return basename + multitree.GetApiImportSuffix() } func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path { // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared) d.libraryDecorator.flagExporter.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...) d.libraryDecorator.flagExporter.setProvider(ctx) in := android.PathForModuleSrc(ctx, *d.properties.Src) d.unstrippedOutputFile = in libName := d.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix() tocFile := android.PathForModuleOut(ctx, libName+".toc") d.tocFile = android.OptionalPathForPath(tocFile) TransformSharedObjectToToc(ctx, in, tocFile) ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ SharedLibrary: in, Target: ctx.Target(), TableOfContents: d.tocFile, }) return in } func (d *apiLibraryDecorator) availableFor(what string) bool { // Stub from API surface should be available for any APEX. return true } func (d *apiLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { d.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), multitree.GetApiImportSuffix()) return d.libraryDecorator.linkerFlags(ctx, flags) } func CcApiStubLibraryFactory() android.Module { module, decorator := NewLibrary(android.DeviceSupported) apiStubDecorator := &apiStubDecorator{ Loading cc/library_stub_test.go +110 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import ( "android/soong/android" "android/soong/multitree" "github.com/google/blueprint" ) func TestCcApiStubLibraryOutputFiles(t *testing.T) { Loading Loading @@ -106,3 +108,111 @@ func TestApiSurfaceOutputs(t *testing.T) { android.AssertStringEquals(t, "name", "foo.mysdk", api_surface_gen_rule_args["name"]) android.AssertStringEquals(t, "symbol_file", "foo.map.txt", api_surface_gen_rule_args["symbol_file"])*/ } func hasDirectDependency(t *testing.T, ctx *android.TestResult, from android.Module, to android.Module) bool { t.Helper() var found bool ctx.VisitDirectDeps(from, func(dep blueprint.Module) { if dep == to { found = true } }) return found } func TestApiLibraryReplacesExistingModule(t *testing.T) { bp := ` cc_library { name: "libfoo", shared_libs: ["libbar"], } cc_library { name: "libbar", } cc_api_library { name: "libbar", src: "libbar.so", } api_imports { name: "api_imports", shared_libs: [ "libbar", ], header_libs: [], } ` ctx := prepareForCcTest.RunTestWithBp(t, bp) libfoo := ctx.ModuleForTests("libfoo", "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() android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbar)) android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport)) } func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) { bp := ` cc_library { name: "libfoo", shared_libs: ["libbar"], } cc_api_library { name: "libbar", src: "libbar.so", } api_imports { name: "api_imports", shared_libs: [ "libbar", ], header_libs: [], } ` ctx := prepareForCcTest.RunTestWithBp(t, bp) libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module() android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport)) } func TestApiLibraryShouldNotReplaceWithoutApiImport(t *testing.T) { bp := ` cc_library { name: "libfoo", shared_libs: ["libbar"], } cc_library { name: "libbar", } cc_api_library { name: "libbar", src: "libbar.so", } api_imports { name: "api_imports", shared_libs: [], header_libs: [], } ` ctx := prepareForCcTest.RunTestWithBp(t, bp) libfoo := ctx.ModuleForTests("libfoo", "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() 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)) } cc/testing.go +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import ( "android/soong/android" "android/soong/genrule" "android/soong/multitree" "android/soong/snapshot" ) Loading @@ -31,6 +32,8 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterLibraryHeadersBuildComponents(ctx) RegisterLibraryStubBuildComponents(ctx) multitree.RegisterApiImportsModule(ctx) ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory) ctx.RegisterModuleType("cc_object", ObjectFactory) ctx.RegisterModuleType("cc_genrule", GenRuleFactory) Loading Loading
apex/apex_test.go +58 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import ( "strings" "testing" "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" Loading Loading @@ -9544,6 +9545,63 @@ func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) { } } func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) { bp := ` apex { name: "myapex", key: "myapex.key", native_shared_libs: ["libfoo"], min_sdk_version: "29", } apex_key { name: "myapex.key", } cc_library { name: "libfoo", shared_libs: ["libc"], apex_available: ["myapex"], min_sdk_version: "29", } cc_api_library { name: "libc", src: "libc.so", min_sdk_version: "29", recovery_available: true, } api_imports { name: "api_imports", shared_libs: [ "libc", ], header_libs: [], } ` 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 } libfooApexVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex29").Module() libcApexVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared_apex29").Module() android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(libfooApexVariant, libcApexVariant)) // libfoo core variant should be buildable in the same inner tree since // certain mcombo files might build system and apexes in the same inner tree // libfoo core variant should link against source libc libfooCoreVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 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)) } func TestMain(m *testing.M) { os.Exit(m.Run()) }
cc/cc.go +88 −25 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import ( "android/soong/cc/config" "android/soong/fuzz" "android/soong/genrule" "android/soong/multitree" "android/soong/snapshot" ) Loading Loading @@ -2183,6 +2184,24 @@ 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 := actx.OtherModuleProvider(apiImportModule[0], multitree.ApiImportsProvider).(multitree.ApiImportInfo) apiImportInfo = apiInfo actx.SetProvider(multitree.ApiImportsProvider, apiInfo) } } } return apiImportInfo } func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo { // Only device modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of // SnapshotInfo, which provides no mappings. Loading @@ -2208,8 +2227,8 @@ func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android. return **snapshotInfo } func RewriteSnapshotLib(lib string, snapshotMap map[string]string) string { if snapshot, ok := snapshotMap[lib]; ok { func GetReplaceModuleName(lib string, replaceMap map[string]string) string { if snapshot, ok := replaceMap[lib]; ok { return snapshot } Loading @@ -2220,12 +2239,17 @@ func RewriteSnapshotLib(lib string, snapshotMap map[string]string) string { // of names: // // 1. Name of an NDK library that refers to a prebuilt module. // // For each of these, it adds the name of the prebuilt module (which will be in // prebuilts/ndk) to the list of nonvariant libs. // // 2. Name of an NDK library that refers to an ndk_library module. // // For each of these, it adds the name of the ndk_library module to the list of // variant libs. // // 3. Anything else (so anything that isn't an NDK library). // // It adds these to the nonvariantLibs list. // // The caller can then know to add the variantLibs dependencies differently from the Loading @@ -2238,11 +2262,11 @@ func RewriteLibs(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android. // strip #version suffix out name, _ := StubsLibNameAndVersion(entry) if c.InRecovery() { nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) } else if c.UseSdk() && inList(name, *getNDKKnownLibs(config)) { variantLibs = append(variantLibs, name+ndkLibrarySuffix) } else if c.UseVndk() { nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs)) } else { // put name#version back nonvariantLibs = append(nonvariantLibs, entry) Loading @@ -2251,6 +2275,25 @@ func RewriteLibs(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android. return nonvariantLibs, variantLibs } func updateDepsWithApiImports(deps Deps, apiImports multitree.ApiImportInfo) Deps { for idx, lib := range deps.SharedLibs { deps.SharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs) } for idx, lib := range deps.LateSharedLibs { deps.LateSharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs) } for idx, lib := range deps.RuntimeLibs { deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs) } for idx, lib := range deps.HeaderLibs { deps.HeaderLibs[idx] = GetReplaceModuleName(lib, apiImports.HeaderLibs) } return deps } func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if !c.Enabled() { return Loading @@ -2266,6 +2309,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps := c.deps(ctx) apiImportInfo := GetApiImports(c, actx) deps = updateDepsWithApiImports(deps, apiImportInfo) c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs var snapshotInfo *SnapshotInfo Loading @@ -2278,7 +2324,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps.ReexportSharedLibHeaders, _ = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.ReexportSharedLibHeaders) for idx, lib := range deps.RuntimeLibs { deps.RuntimeLibs[idx] = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs) deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs) } } Loading @@ -2288,7 +2334,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag.reexportFlags = true } lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs) lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs) if c.IsStubs() { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()), Loading @@ -2301,11 +2347,21 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if c.isNDKStubLibrary() { // NDK stubs depend on their implementation because the ABI dumps are // generated from the implementation library. apiImportName := c.BaseModuleName() + multitree.GetApiImportSuffix() // If original library exists as imported API, set dependency on the imported library if actx.OtherModuleExists(apiImportName) { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation(), blueprint.Variation{Mutator: "link", Variation: "shared"}, ), stubImplementation, apiImportName) } else { actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation(), blueprint.Variation{Mutator: "link", Variation: "shared"}, ), stubImplementation, c.BaseModuleName()) } } // sysprop_library has to support both C++ and Java. So sysprop_library internally creates one // C++ implementation library and one Java implementation library. When a module links against Loading @@ -2320,7 +2376,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { lib = impl } lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, Loading @@ -2340,7 +2396,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { lib = impl } lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, Loading @@ -2354,7 +2410,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, RewriteSnapshotLib(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) }, depTag, GetReplaceModuleName(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) } // shared lib names without the #version suffix Loading Loading @@ -2386,14 +2442,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) } for _, lib := range deps.UnexportedStaticLibs { depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, unexportedSymbols: true} actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, depTag, RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)) } for _, lib := range deps.LateSharedLibs { Loading Loading @@ -2434,11 +2490,11 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...) for _, crt := range deps.CrtBegin { actx.AddVariationDependencies(crtVariations, CrtBeginDepTag, RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) } for _, crt := range deps.CrtEnd { actx.AddVariationDependencies(crtVariations, CrtEndDepTag, RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects)) } if deps.DynamicLinker != "" { actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker) Loading @@ -2463,7 +2519,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { actx.AddVariationDependencies([]blueprint.Variation{ c.ImageVariation(), {Mutator: "link", Variation: "shared"}, }, vndkExtDepTag, RewriteSnapshotLib(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs)) }, vndkExtDepTag, GetReplaceModuleName(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs)) } } } Loading Loading @@ -3185,6 +3241,11 @@ func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableI return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix() } // Remove API import suffix if exists if _, ok := ccDepModule.linker.(*apiLibraryDecorator); ok { libName = strings.TrimSuffix(libName, multitree.GetApiImportSuffix()) } } if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && Loading Loading @@ -3520,6 +3581,10 @@ func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, if _, ok := c.linker.(prebuiltLinkerInterface); ok { return nil } if _, ok := c.linker.(*apiLibraryDecorator); ok { return nil } minSdkVersion := c.MinSdkVersion() if minSdkVersion == "apex_inherit" { return nil Loading Loading @@ -3637,9 +3702,7 @@ func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } } // // Defaults // type Defaults struct { android.ModuleBase android.DefaultsModuleBase Loading
cc/library_stub.go +87 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package cc import ( "android/soong/android" "android/soong/multitree" "strings" ) func init() { Loading @@ -25,10 +26,96 @@ func init() { func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) { // cc_api_stub_library shares a lot of ndk_library, and this will be refactored later ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory) ctx.RegisterModuleType("cc_api_stub_library", CcApiStubLibraryFactory) ctx.RegisterModuleType("cc_api_contribution", CcApiContributionFactory) } // '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"` } 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.AddProperties(&module.Properties, &apiLibraryDecorator.properties) // Mark module as stub, so APEX would not include this stub in the package. module.library.setBuildStubs(true) // Prevent default system libs (libc, libm, and libdl) from being linked if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil { apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{} } module.Init() return module } func (d *apiLibraryDecorator) Name(basename string) string { return basename + multitree.GetApiImportSuffix() } func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path { // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared) d.libraryDecorator.flagExporter.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...) d.libraryDecorator.flagExporter.setProvider(ctx) in := android.PathForModuleSrc(ctx, *d.properties.Src) d.unstrippedOutputFile = in libName := d.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix() tocFile := android.PathForModuleOut(ctx, libName+".toc") d.tocFile = android.OptionalPathForPath(tocFile) TransformSharedObjectToToc(ctx, in, tocFile) ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ SharedLibrary: in, Target: ctx.Target(), TableOfContents: d.tocFile, }) return in } func (d *apiLibraryDecorator) availableFor(what string) bool { // Stub from API surface should be available for any APEX. return true } func (d *apiLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { d.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), multitree.GetApiImportSuffix()) return d.libraryDecorator.linkerFlags(ctx, flags) } func CcApiStubLibraryFactory() android.Module { module, decorator := NewLibrary(android.DeviceSupported) apiStubDecorator := &apiStubDecorator{ Loading
cc/library_stub_test.go +110 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import ( "android/soong/android" "android/soong/multitree" "github.com/google/blueprint" ) func TestCcApiStubLibraryOutputFiles(t *testing.T) { Loading Loading @@ -106,3 +108,111 @@ func TestApiSurfaceOutputs(t *testing.T) { android.AssertStringEquals(t, "name", "foo.mysdk", api_surface_gen_rule_args["name"]) android.AssertStringEquals(t, "symbol_file", "foo.map.txt", api_surface_gen_rule_args["symbol_file"])*/ } func hasDirectDependency(t *testing.T, ctx *android.TestResult, from android.Module, to android.Module) bool { t.Helper() var found bool ctx.VisitDirectDeps(from, func(dep blueprint.Module) { if dep == to { found = true } }) return found } func TestApiLibraryReplacesExistingModule(t *testing.T) { bp := ` cc_library { name: "libfoo", shared_libs: ["libbar"], } cc_library { name: "libbar", } cc_api_library { name: "libbar", src: "libbar.so", } api_imports { name: "api_imports", shared_libs: [ "libbar", ], header_libs: [], } ` ctx := prepareForCcTest.RunTestWithBp(t, bp) libfoo := ctx.ModuleForTests("libfoo", "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() android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbar)) android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport)) } func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) { bp := ` cc_library { name: "libfoo", shared_libs: ["libbar"], } cc_api_library { name: "libbar", src: "libbar.so", } api_imports { name: "api_imports", shared_libs: [ "libbar", ], header_libs: [], } ` ctx := prepareForCcTest.RunTestWithBp(t, bp) libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module() android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport)) } func TestApiLibraryShouldNotReplaceWithoutApiImport(t *testing.T) { bp := ` cc_library { name: "libfoo", shared_libs: ["libbar"], } cc_library { name: "libbar", } cc_api_library { name: "libbar", src: "libbar.so", } api_imports { name: "api_imports", shared_libs: [], header_libs: [], } ` ctx := prepareForCcTest.RunTestWithBp(t, bp) libfoo := ctx.ModuleForTests("libfoo", "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() 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)) }
cc/testing.go +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import ( "android/soong/android" "android/soong/genrule" "android/soong/multitree" "android/soong/snapshot" ) Loading @@ -31,6 +32,8 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterLibraryHeadersBuildComponents(ctx) RegisterLibraryStubBuildComponents(ctx) multitree.RegisterApiImportsModule(ctx) ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory) ctx.RegisterModuleType("cc_object", ObjectFactory) ctx.RegisterModuleType("cc_genrule", GenRuleFactory) Loading