diff --git a/apex/apex_test.go b/apex/apex_test.go index 6abd8ffa6..e5f77fc23 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -26,6 +26,7 @@ import ( "strings" "testing" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" @@ -9546,6 +9547,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()) } diff --git a/cc/cc.go b/cc/cc.go index bc958134f..471267a1c 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -31,6 +31,7 @@ import ( "android/soong/cc/config" "android/soong/fuzz" "android/soong/genrule" + "android/soong/multitree" "android/soong/snapshot" ) @@ -2184,6 +2185,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. @@ -2209,8 +2228,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 } @@ -2221,13 +2240,18 @@ 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. +// +// 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. +// +// 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. +// +// It adds these to the nonvariantLibs list. // // The caller can then know to add the variantLibs dependencies differently from the // nonvariantLibs @@ -2239,11 +2263,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) @@ -2252,6 +2276,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 @@ -2267,6 +2310,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 @@ -2279,7 +2325,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) } } @@ -2289,7 +2335,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()), @@ -2302,10 +2348,20 @@ 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. - actx.AddFarVariationDependencies(append(ctx.Target().Variations(), - c.ImageVariation(), - blueprint.Variation{Mutator: "link", Variation: "shared"}, - ), stubImplementation, c.BaseModuleName()) + 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 @@ -2321,7 +2377,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"}, @@ -2341,7 +2397,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"}, @@ -2355,7 +2411,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 @@ -2387,14 +2443,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 { @@ -2435,11 +2491,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) @@ -2464,7 +2520,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)) } } } @@ -3186,6 +3242,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() && @@ -3521,6 +3582,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 @@ -3638,9 +3703,7 @@ func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } } -// // Defaults -// type Defaults struct { android.ModuleBase android.DefaultsModuleBase diff --git a/cc/library_stub.go b/cc/library_stub.go index 4d0148df4..14d1b963a 100644 --- a/cc/library_stub.go +++ b/cc/library_stub.go @@ -17,6 +17,7 @@ package cc import ( "android/soong/android" "android/soong/multitree" + "strings" ) func init() { @@ -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{ diff --git a/cc/library_stub_test.go b/cc/library_stub_test.go index 15b56d227..c2ac941dd 100644 --- a/cc/library_stub_test.go +++ b/cc/library_stub_test.go @@ -22,6 +22,8 @@ import ( "android/soong/android" "android/soong/multitree" + + "github.com/google/blueprint" ) func TestCcApiStubLibraryOutputFiles(t *testing.T) { @@ -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)) +} diff --git a/cc/testing.go b/cc/testing.go index 6b858d593..40edd28f2 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -20,6 +20,7 @@ import ( "android/soong/android" "android/soong/genrule" + "android/soong/multitree" "android/soong/snapshot" ) @@ -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) diff --git a/multitree/Android.bp b/multitree/Android.bp index 9b16d2021..78c49627b 100644 --- a/multitree/Android.bp +++ b/multitree/Android.bp @@ -10,6 +10,7 @@ bootstrap_go_package { "soong-android", ], srcs: [ + "api_imports.go", "api_surface.go", "export.go", "metadata.go", diff --git a/multitree/api_imports.go b/multitree/api_imports.go new file mode 100644 index 000000000..2c4cf80ca --- /dev/null +++ b/multitree/api_imports.go @@ -0,0 +1,88 @@ +// 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" +) + +var ( + apiImportNameSuffix = ".apiimport" +) + +func init() { + RegisterApiImportsModule(android.InitRegistrationContext) +} + +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 +} + +// '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 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) + + ctx.SetProvider(ApiImportsProvider, ApiImportInfo{ + SharedLibs: sharedLibs, + HeaderLibs: headerLibs, + }) +} + +func GetApiImportSuffix() string { + return apiImportNameSuffix +} diff --git a/rust/rust.go b/rust/rust.go index d5d492971..4c3d25aba 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -1380,6 +1380,11 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { var commonDepVariations []blueprint.Variation var snapshotInfo *cc.SnapshotInfo + apiImportInfo := cc.GetApiImports(mod, actx) + for idx, lib := range deps.SharedLibs { + deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs) + } + if ctx.Os() == android.Android { deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs) } @@ -1400,7 +1405,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation}) for _, lib := range deps.Rlibs { depTag := rlibDepTag - lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) + lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) actx.AddVariationDependencies(rlibDepVariations, depTag, lib) } @@ -1438,7 +1443,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { if mod.compiler.stdLinkage(ctx) == RlibLinkage { for _, lib := range deps.Stdlibs { depTag := rlibDepTag - lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) + lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...), depTag, lib) @@ -1462,7 +1467,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { for _, lib := range deps.WholeStaticLibs { depTag := cc.StaticDepTag(true) - lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs) + lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, @@ -1471,7 +1476,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { for _, lib := range deps.StaticLibs { depTag := cc.StaticDepTag(false) - lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs) + lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, @@ -1483,11 +1488,11 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { crtVariations := cc.GetCrtVariations(ctx, mod) for _, crt := range deps.CrtBegin { actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, - cc.RewriteSnapshotLib(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) + cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) } for _, crt := range deps.CrtEnd { actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, - cc.RewriteSnapshotLib(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) + cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) } if mod.sourceProvider != nil { @@ -1510,7 +1515,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { // addRlibDependency will add an rlib dependency, rewriting to the snapshot library if available. func addRlibDependency(actx android.BottomUpMutatorContext, lib string, mod *Module, snapshotInfo *cc.SnapshotInfo, variations []blueprint.Variation) { - lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) + lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) actx.AddVariationDependencies(variations, rlibDepTag, lib) }