Introduce cc_api_library

Introduce cc_api_library, which reflects imported API from other
inner-tree. This cc_api_library module type will later refer from
the other ninja module which generates stub library from the interface
description.

Tested environment :
* original libc definition has been removed temporarily, to ensure that
  imported api stub library is being used from build
* Added new definition of libc as below
 cc_api_library {
  name: "libc",
  arch: {
    x86: {
      src: "libs/x86/libc.so",
    },
    x86_64: {
      src: "libs/x86_64/libc.so",
    },
  },
  header_libs: [
    "libc_headers",
  ],
  export_header_lib_headers: ["libc_headers"],
  min_sdk_version: "9",
  vendor_available: true,
 }

Bug: 236087698
Test: `ALLOW_MISSING_DEPENDENCIES=true m vendorimage` succeeded
Change-Id: I67070b0f3561aa2afd73b6c1c0fdf4255218baac
This commit is contained in:
Kiyoung Kim 2022-07-26 09:48:22 +09:00
parent b7873a8b0f
commit 487689eaee
8 changed files with 447 additions and 32 deletions

View file

@ -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())
}

113
cc/cc.go
View file

@ -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

View file

@ -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{

View file

@ -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))
}

View file

@ -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)

View file

@ -10,6 +10,7 @@ bootstrap_go_package {
"soong-android",
],
srcs: [
"api_imports.go",
"api_surface.go",
"export.go",
"metadata.go",

88
multitree/api_imports.go Normal file
View file

@ -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
}

View file

@ -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)
}