Start using Providers instead of direct module access

Export information about static libraries, shared libraries and
exported flags through Providers instead of accessing the module
directly.  Much more is left to be converted, but this significantly
simplifies the dependencies on libraries with stubs by making it easy
for a module to masquerade as another by simply exporting the
providers from the other module.  Instead of depending on all the
versions of a library and then picking which one to use later, it
can depend only on the implementation variant and then select the
right SharedLibraryInfo from the variant.

Test: m checkbuild
Test: only expected changes to build.ninja
Change-Id: I1fd9eb4d251cf96ed8398d586efc3e0817663c76
This commit is contained in:
Colin Cross 2020-09-18 14:15:30 -07:00
parent ff8838cb86
commit 0de8a1e17b
20 changed files with 509 additions and 560 deletions

View file

@ -145,11 +145,6 @@ type ApexModule interface {
// check-platform-availability mutator in the apex package.
SetNotAvailableForPlatform()
// Returns the highest version which is <= maxSdkVersion.
// For example, with maxSdkVersion is 10 and versionList is [9,11]
// it returns 9 as string
ChooseSdkVersion(ctx BaseModuleContext, versionList []string, maxSdkVersion ApiLevel) (string, error)
// List of APEXes that this module tests. The module has access to
// the private part of the listed APEXes even when it is not included in the
// APEXes.
@ -310,20 +305,6 @@ func (m *ApexModuleBase) DepIsInSameApex(ctx BaseModuleContext, dep Module) bool
return true
}
func (m *ApexModuleBase) ChooseSdkVersion(ctx BaseModuleContext, versionList []string, maxSdkVersion ApiLevel) (string, error) {
for i := range versionList {
version := versionList[len(versionList)-i-1]
ver, err := ApiLevelFromUser(ctx, version)
if err != nil {
return "", err
}
if ver.LessThanOrEqualTo(maxSdkVersion) {
return version, nil
}
}
return "", fmt.Errorf("not found a version(<=%s) in versionList: %v", maxSdkVersion, versionList)
}
func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
for _, n := range m.ApexProperties.Apex_available {
if n == AvailableToPlatform || n == AvailableToAnyApex || n == AvailableToGkiApex {

View file

@ -71,24 +71,26 @@ func (o DepSetOrder) String() string {
// NewDepSet returns an immutable DepSet with the given order, direct and transitive contents.
func NewDepSet(order DepSetOrder, direct Paths, transitive []*DepSet) *DepSet {
var directCopy Paths
var transitiveCopy []*DepSet
transitiveCopy := make([]*DepSet, 0, len(transitive))
for _, dep := range transitive {
if dep != nil {
if dep.order != order {
panic(fmt.Errorf("incompatible order, new DepSet is %s but transitive DepSet is %s",
order, dep.order))
}
transitiveCopy = append(transitiveCopy, dep)
}
}
if order == TOPOLOGICAL {
directCopy = ReversePaths(direct)
transitiveCopy = reverseDepSets(transitive)
reverseDepSetsInPlace(transitiveCopy)
} else {
// Use copy instead of append(nil, ...) to make a slice that is exactly the size of the input
// slice. The DepSet is immutable, there is no need for additional capacity.
directCopy = make(Paths, len(direct))
copy(directCopy, direct)
transitiveCopy = make([]*DepSet, len(transitive))
copy(transitiveCopy, transitive)
}
for _, dep := range transitive {
if dep.order != order {
panic(fmt.Errorf("incompatible order, new DepSet is %s but transitive DepSet is %s",
order, dep.order))
}
}
return &DepSet{
@ -157,6 +159,9 @@ func (d *DepSet) walk(visit func(Paths)) {
// its transitive dependencies, in which case the ordering of the duplicated element is not
// guaranteed).
func (d *DepSet) ToList() Paths {
if d == nil {
return nil
}
var list Paths
d.walk(func(paths Paths) {
list = append(list, paths...)
@ -181,10 +186,9 @@ func reversePathsInPlace(list Paths) {
}
}
func reverseDepSets(list []*DepSet) []*DepSet {
ret := make([]*DepSet, len(list))
for i := range list {
ret[i] = list[len(list)-1-i]
func reverseDepSetsInPlace(list []*DepSet) {
for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 {
list[i], list[j] = list[j], list[i]
}
return ret
}

View file

@ -1319,6 +1319,7 @@ func TestApexWithSystemLibsStubs(t *testing.T) {
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
system_shared_libs: ["libc", "libm"],
shared_libs: ["libdl#27"],
stl: "none",
apex_available: [ "myapex" ],

View file

@ -186,17 +186,17 @@ func makeOverrideModuleNames(ctx AndroidMkContext, overrides []string) []string
}
func (library *libraryDecorator) androidMkWriteExportedFlags(entries *android.AndroidMkEntries) {
exportedFlags := library.exportedFlags()
for _, dir := range library.exportedDirs() {
exportedFlags := library.flagExporter.flags
for _, dir := range library.flagExporter.dirs {
exportedFlags = append(exportedFlags, "-I"+dir.String())
}
for _, dir := range library.exportedSystemDirs() {
for _, dir := range library.flagExporter.systemDirs {
exportedFlags = append(exportedFlags, "-isystem "+dir.String())
}
if len(exportedFlags) > 0 {
entries.AddStrings("LOCAL_EXPORT_CFLAGS", exportedFlags...)
}
exportedDeps := library.exportedDeps()
exportedDeps := library.flagExporter.deps
if len(exportedDeps) > 0 {
entries.AddStrings("LOCAL_EXPORT_C_INCLUDE_DEPS", exportedDeps.Strings()...)
}

502
cc/cc.go
View file

@ -130,6 +130,9 @@ type PathDeps struct {
// Paths to .a files
StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
// Transitive static library dependencies of static libraries for use in ordering.
TranstiveStaticLibrariesForOrdering *android.DepSet
// Paths to .o files
Objs Objects
// Paths to .o files in dependencies that provide them. Note that these lists
@ -546,9 +549,7 @@ var (
dataLibDepTag = dependencyTag{name: "data lib"}
runtimeDepTag = dependencyTag{name: "runtime lib"}
testPerSrcDepTag = dependencyTag{name: "test_per_src"}
testForDepTag = dependencyTag{name: "test for apex"}
stubImplDepTag = copyDirectlyInAnyApexDependencyTag{name: "stub_impl"}
stubImplDepTag = dependencyTag{name: "stub_impl"}
)
type copyDirectlyInAnyApexDependencyTag dependencyTag
@ -618,13 +619,8 @@ type Module struct {
// Flags used to compile this module
flags Flags
// When calling a linker, if module A depends on module B, then A must precede B in its command
// line invocation. depsInLinkOrder stores the proper ordering of all of the transitive
// deps of this module
depsInLinkOrder android.Paths
// only non-nil when this is a shared library that reuses the objects of a static library
staticVariant LinkableInterface
staticAnalogue *StaticLibraryInfo
makeLinkType string
// Kythe (source file indexer) paths for this compilation module
@ -722,34 +718,6 @@ func (c *Module) AlwaysSdk() bool {
return c.Properties.AlwaysSdk || Bool(c.Properties.Sdk_variant_only)
}
func (c *Module) IncludeDirs() android.Paths {
if c.linker != nil {
if library, ok := c.linker.(exportedFlagsProducer); ok {
return library.exportedDirs()
}
}
panic(fmt.Errorf("IncludeDirs called on non-exportedFlagsProducer module: %q", c.BaseModuleName()))
}
func (c *Module) HasStaticVariant() bool {
if c.staticVariant != nil {
return true
}
return false
}
func (c *Module) GetStaticVariant() LinkableInterface {
return c.staticVariant
}
func (c *Module) SetDepsInLinkOrder(depsInLinkOrder []android.Path) {
c.depsInLinkOrder = depsInLinkOrder
}
func (c *Module) GetDepsInLinkOrder() []android.Path {
return c.depsInLinkOrder
}
func (c *Module) StubsVersions() []string {
if c.linker != nil {
if library, ok := c.linker.(*libraryDecorator); ok {
@ -1156,41 +1124,6 @@ func (c *Module) isSnapshotPrebuilt() bool {
return false
}
func (c *Module) ExportedIncludeDirs() android.Paths {
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
return flagsProducer.exportedDirs()
}
return nil
}
func (c *Module) ExportedSystemIncludeDirs() android.Paths {
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
return flagsProducer.exportedSystemDirs()
}
return nil
}
func (c *Module) ExportedFlags() []string {
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
return flagsProducer.exportedFlags()
}
return nil
}
func (c *Module) ExportedDeps() android.Paths {
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
return flagsProducer.exportedDeps()
}
return nil
}
func (c *Module) ExportedGeneratedHeaders() android.Paths {
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
return flagsProducer.exportedGeneratedHeaders()
}
return nil
}
func (c *Module) ExcludeFromVendorSnapshot() bool {
return Bool(c.Properties.Exclude_from_vendor_snapshot)
}
@ -1454,65 +1387,6 @@ func (c *Module) Symlinks() []string {
return nil
}
// orderDeps reorders dependencies into a list such that if module A depends on B, then
// A will precede B in the resultant list.
// This is convenient for passing into a linker.
// Note that directSharedDeps should be the analogous static library for each shared lib dep
func orderDeps(directStaticDeps []android.Path, directSharedDeps []android.Path, allTransitiveDeps map[android.Path][]android.Path) (orderedAllDeps []android.Path, orderedDeclaredDeps []android.Path) {
// If A depends on B, then
// Every list containing A will also contain B later in the list
// So, after concatenating all lists, the final instance of B will have come from the same
// original list as the final instance of A
// So, the final instance of B will be later in the concatenation than the final A
// So, keeping only the final instance of A and of B ensures that A is earlier in the output
// list than B
for _, dep := range directStaticDeps {
orderedAllDeps = append(orderedAllDeps, dep)
orderedAllDeps = append(orderedAllDeps, allTransitiveDeps[dep]...)
}
for _, dep := range directSharedDeps {
orderedAllDeps = append(orderedAllDeps, dep)
orderedAllDeps = append(orderedAllDeps, allTransitiveDeps[dep]...)
}
orderedAllDeps = android.LastUniquePaths(orderedAllDeps)
// We don't want to add any new dependencies into directStaticDeps (to allow the caller to
// intentionally exclude or replace any unwanted transitive dependencies), so we limit the
// resultant list to only what the caller has chosen to include in directStaticDeps
_, orderedDeclaredDeps = android.FilterPathList(orderedAllDeps, directStaticDeps)
return orderedAllDeps, orderedDeclaredDeps
}
func orderStaticModuleDeps(module LinkableInterface, staticDeps []LinkableInterface, sharedDeps []LinkableInterface) (results []android.Path) {
// convert Module to Path
var depsInLinkOrder []android.Path
allTransitiveDeps := make(map[android.Path][]android.Path, len(staticDeps))
staticDepFiles := []android.Path{}
for _, dep := range staticDeps {
// The OutputFile may not be valid for a variant not present, and the AllowMissingDependencies flag is set.
if dep.OutputFile().Valid() {
allTransitiveDeps[dep.OutputFile().Path()] = dep.GetDepsInLinkOrder()
staticDepFiles = append(staticDepFiles, dep.OutputFile().Path())
}
}
sharedDepFiles := []android.Path{}
for _, sharedDep := range sharedDeps {
if sharedDep.HasStaticVariant() {
staticAnalogue := sharedDep.GetStaticVariant()
allTransitiveDeps[staticAnalogue.OutputFile().Path()] = staticAnalogue.GetDepsInLinkOrder()
sharedDepFiles = append(sharedDepFiles, staticAnalogue.OutputFile().Path())
}
}
// reorder the dependencies based on transitive dependencies
depsInLinkOrder, results = orderDeps(staticDepFiles, sharedDepFiles, allTransitiveDeps)
module.SetDepsInLinkOrder(depsInLinkOrder)
return results
}
func (c *Module) IsTestPerSrcAllTestsVariation() bool {
test, ok := c.linker.(testPerSrc)
return ok && test.isAllTestsVariation()
@ -1896,29 +1770,11 @@ func (c *Module) addSharedLibDependenciesWithVersions(ctx android.BottomUpMutato
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
depTag.explicitlyVersioned = true
}
var deps []blueprint.Module
if far {
deps = ctx.AddFarVariationDependencies(variations, depTag, name)
} else {
deps = ctx.AddVariationDependencies(variations, depTag, name)
}
// If the version is not specified, add dependency to all stubs libraries.
// The stubs library will be used when the depending module is built for APEX and
// the dependent module is not in the same APEX.
if version == "" && CanBeOrLinkAgainstVersionVariants(c) {
if dep, ok := deps[0].(*Module); ok {
for _, ver := range dep.AllStubsVersions() {
// Note that depTag.ExplicitlyVersioned is false in this case.
versionVariations := append(variations,
blueprint.Variation{Mutator: "version", Variation: ver})
if far {
ctx.AddFarVariationDependencies(versionVariations, depTag, name)
} else {
ctx.AddVariationDependencies(versionVariations, depTag, name)
}
}
}
if far {
ctx.AddFarVariationDependencies(variations, depTag, name)
} else {
ctx.AddVariationDependencies(variations, depTag, name)
}
}
@ -2384,19 +2240,49 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
}
}
// Returns the highest version which is <= maxSdkVersion.
// For example, with maxSdkVersion is 10 and versionList is [9,11]
// it returns 9 as string. The list of stubs must be in order from
// oldest to newest.
func (c *Module) chooseSdkVersion(ctx android.PathContext, stubsInfo []SharedLibraryStubsInfo,
maxSdkVersion android.ApiLevel) (SharedLibraryStubsInfo, error) {
for i := range stubsInfo {
stubInfo := stubsInfo[len(stubsInfo)-i-1]
var ver android.ApiLevel
if stubInfo.Version == "" {
ver = android.FutureApiLevel
} else {
var err error
ver, err = android.ApiLevelFromUser(ctx, stubInfo.Version)
if err != nil {
return SharedLibraryStubsInfo{}, err
}
}
if ver.LessThanOrEqualTo(maxSdkVersion) {
return stubInfo, nil
}
}
var versionList []string
for _, stubInfo := range stubsInfo {
versionList = append(versionList, stubInfo.Version)
}
return SharedLibraryStubsInfo{}, fmt.Errorf("not found a version(<=%s) in versionList: %v", maxSdkVersion.String(), versionList)
}
// Convert dependencies to paths. Returns a PathDeps containing paths
func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
directStaticDeps := []LinkableInterface{}
directSharedDeps := []LinkableInterface{}
var directStaticDeps []StaticLibraryInfo
var directSharedDeps []SharedLibraryInfo
reexportExporter := func(exporter exportedFlagsProducer) {
depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, exporter.exportedDirs()...)
depPaths.ReexportedSystemDirs = append(depPaths.ReexportedSystemDirs, exporter.exportedSystemDirs()...)
depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, exporter.exportedFlags()...)
depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, exporter.exportedDeps()...)
depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, exporter.exportedGeneratedHeaders()...)
reexportExporter := func(exporter FlagExporterInfo) {
depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, exporter.IncludeDirs...)
depPaths.ReexportedSystemDirs = append(depPaths.ReexportedSystemDirs, exporter.SystemIncludeDirs...)
depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, exporter.Flags...)
depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, exporter.Deps...)
depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, exporter.GeneratedHeaders...)
}
// For the dependency from platform to apex, use the latest stubs
@ -2481,24 +2367,14 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return
}
// re-exporting flags
if depTag == reuseObjTag {
// reusing objects only make sense for cc.Modules.
if ccReuseDep, ok := ccDep.(*Module); ok && ccDep.CcLibraryInterface() {
c.staticVariant = ccDep
objs, exporter := ccReuseDep.compiler.(libraryInterface).reuseObjs()
depPaths.Objs = depPaths.Objs.Append(objs)
reexportExporter(exporter)
return
}
}
if depTag == staticVariantTag {
// staticVariants are a cc.Module specific concept.
if _, ok := ccDep.(*Module); ok && ccDep.CcLibraryInterface() {
c.staticVariant = ccDep
return
}
staticAnalogue := ctx.OtherModuleProvider(dep, StaticLibraryInfoProvider).(StaticLibraryInfo)
objs := staticAnalogue.ReuseObjects
depPaths.Objs = depPaths.Objs.Append(objs)
depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
reexportExporter(depExporterInfo)
return
}
checkLinkType(ctx, c, ccDep, depTag)
@ -2511,103 +2387,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return
}
if ccDep.CcLibrary() && !libDepTag.static() {
depIsStubs := ccDep.BuildStubs()
depHasStubs := CanBeOrLinkAgainstVersionVariants(c) && ccDep.HasStubsVariants()
depInSameApexes := android.DirectlyInAllApexes(apexInfo, depName)
depInPlatform := !dep.(android.ApexModule).AnyVariantDirectlyInAnyApex()
var useThisDep bool
if depIsStubs && libDepTag.explicitlyVersioned {
// Always respect dependency to the versioned stubs (i.e. libX#10)
useThisDep = true
} else if !depHasStubs {
// Use non-stub variant if that is the only choice
// (i.e. depending on a lib without stubs.version property)
useThisDep = true
} else if apexInfo.IsForPlatform() {
// If not building for APEX, use stubs only when it is from
// an APEX (and not from platform)
useThisDep = (depInPlatform != depIsStubs)
if c.bootstrap() {
// However, for host, ramdisk, recovery or bootstrap modules,
// always link to non-stub variant
useThisDep = !depIsStubs
}
// Another exception: if this module is bundled with an APEX, then
// it is linked with the non-stub variant of a module in the APEX
// as if this is part of the APEX.
testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
for _, apexContents := range testFor.ApexContents {
if apexContents.DirectlyInApex(depName) {
useThisDep = !depIsStubs
break
}
}
} else {
// If building for APEX, use stubs when the parent is in any APEX that
// the child is not in.
useThisDep = (depInSameApexes != depIsStubs)
}
// when to use (unspecified) stubs, check min_sdk_version and choose the right one
if useThisDep && depIsStubs && !libDepTag.explicitlyVersioned {
versionToUse, err := c.ChooseSdkVersion(ctx, ccDep.StubsVersions(), c.apexSdkVersion)
if err != nil {
ctx.OtherModuleErrorf(dep, err.Error())
return
}
if versionToUse != ccDep.StubsVersion() {
useThisDep = false
}
}
if !useThisDep {
return // stop processing this dep
}
}
if c.UseVndk() {
if m, ok := ccDep.(*Module); ok && m.IsStubs() { // LLNDK
// by default, use current version of LLNDK
versionToUse := ""
versions := m.AllStubsVersions()
if apexInfo.ApexVariationName != "" && len(versions) > 0 {
// if this is for use_vendor apex && dep has stubsVersions
// apply the same rule of apex sdk enforcement to choose right version
var err error
versionToUse, err = c.ChooseSdkVersion(ctx, versions, c.apexSdkVersion)
if err != nil {
ctx.OtherModuleErrorf(dep, err.Error())
return
}
}
if versionToUse != ccDep.StubsVersion() {
return
}
}
}
depPaths.IncludeDirs = append(depPaths.IncludeDirs, ccDep.IncludeDirs()...)
// Exporting flags only makes sense for cc.Modules
if _, ok := ccDep.(*Module); ok {
if i, ok := ccDep.(*Module).linker.(exportedFlagsProducer); ok {
depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, i.exportedSystemDirs()...)
depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, i.exportedDeps()...)
depPaths.Flags = append(depPaths.Flags, i.exportedFlags()...)
if libDepTag.reexportFlags {
reexportExporter(i)
// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
// Re-exported shared library headers must be included as well since they can help us with type information
// about template instantiations (instantiated from their headers).
// -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version
// scripts.
c.sabi.Properties.ReexportedIncludes = append(
c.sabi.Properties.ReexportedIncludes, i.exportedDirs().Strings()...)
}
}
}
depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
var ptr *android.Paths
var depPtr *android.Paths
@ -2618,6 +2398,64 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
case libDepTag.header():
// nothing
case libDepTag.shared():
if !ctx.OtherModuleHasProvider(dep, SharedLibraryInfoProvider) {
if !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("module %q is not a shared library", depName)
} else {
ctx.AddMissingDependencies([]string{depName})
}
return
}
sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo)
sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryImplementationStubsInfoProvider).(SharedLibraryImplementationStubsInfo)
if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedLibraryStubsInfos) > 0 {
useStubs := false
if m, ok := ccDep.(*Module); ok && m.IsStubs() && c.UseVndk() { // LLNDK
if !apexInfo.IsForPlatform() {
// For platform libraries, use current version of LLNDK
// If this is for use_vendor apex we will apply the same rules
// of apex sdk enforcement below to choose right version.
useStubs = true
}
} else if apexInfo.IsForPlatform() {
// If not building for APEX, use stubs only when it is from
// an APEX (and not from platform)
// However, for host, ramdisk, recovery or bootstrap modules,
// always link to non-stub variant
useStubs = dep.(android.ApexModule).AnyVariantDirectlyInAnyApex() && !c.bootstrap()
// Another exception: if this module is bundled with an APEX, then
// it is linked with the non-stub variant of a module in the APEX
// as if this is part of the APEX.
testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
for _, apexContents := range testFor.ApexContents {
if apexContents.DirectlyInApex(depName) {
useStubs = false
break
}
}
} else {
// If building for APEX, use stubs when the parent is in any APEX that
// the child is not in.
useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
}
// when to use (unspecified) stubs, check min_sdk_version and choose the right one
if useStubs {
sharedLibraryStubsInfo, err :=
c.chooseSdkVersion(ctx, sharedLibraryStubsInfo.SharedLibraryStubsInfos, c.apexSdkVersion)
if err != nil {
ctx.OtherModuleErrorf(dep, err.Error())
return
}
sharedLibraryInfo = sharedLibraryStubsInfo.SharedLibraryInfo
depExporterInfo = sharedLibraryStubsInfo.FlagExporterInfo
}
}
linkFile = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary)
depFile = sharedLibraryInfo.TableOfContents
ptr = &depPaths.SharedLibs
switch libDepTag.Order {
case earlyLibraryDependency:
@ -2626,47 +2464,41 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
case normalLibraryDependency:
ptr = &depPaths.SharedLibs
depPtr = &depPaths.SharedLibsDeps
directSharedDeps = append(directSharedDeps, ccDep)
directSharedDeps = append(directSharedDeps, sharedLibraryInfo)
case lateLibraryDependency:
ptr = &depPaths.LateSharedLibs
depPtr = &depPaths.LateSharedLibsDeps
default:
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
}
depFile = ccDep.Toc()
case libDepTag.static():
if !ctx.OtherModuleHasProvider(dep, StaticLibraryInfoProvider) {
if !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("module %q is not a static library", depName)
} else {
ctx.AddMissingDependencies([]string{depName})
}
return
}
staticLibraryInfo := ctx.OtherModuleProvider(dep, StaticLibraryInfoProvider).(StaticLibraryInfo)
linkFile = android.OptionalPathForPath(staticLibraryInfo.StaticLibrary)
if libDepTag.wholeStatic {
ptr = &depPaths.WholeStaticLibs
if !ccDep.CcLibraryInterface() || !ccDep.Static() {
ctx.ModuleErrorf("module %q not a static library", depName)
return
}
// Because the static library objects are included, this only makes sense
// in the context of proper cc.Modules.
if ccWholeStaticLib, ok := ccDep.(*Module); ok {
staticLib := ccWholeStaticLib.linker.(libraryInterface)
if objs := staticLib.objs(); len(objs.objFiles) > 0 {
depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(objs)
} else {
// This case normally catches prebuilt static
// libraries, but it can also occur when
// AllowMissingDependencies is on and the
// dependencies has no sources of its own
// but has a whole_static_libs dependency
// on a missing library. We want to depend
// on the .a file so that there is something
// in the dependency tree that contains the
// error rule for the missing transitive
// dependency.
depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path())
}
if len(staticLibraryInfo.Objects.objFiles) > 0 {
depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLibraryInfo.Objects)
} else {
ctx.ModuleErrorf(
"non-cc.Modules cannot be included as whole static libraries.", depName)
return
// This case normally catches prebuilt static
// libraries, but it can also occur when
// AllowMissingDependencies is on and the
// dependencies has no sources of its own
// but has a whole_static_libs dependency
// on a missing library. We want to depend
// on the .a file so that there is something
// in the dependency tree that contains the
// error rule for the missing transitive
// dependency.
depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path())
}
} else {
switch libDepTag.Order {
case earlyLibraryDependency:
@ -2675,7 +2507,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// static dependencies will be handled separately so they can be ordered
// using transitive dependencies.
ptr = nil
directStaticDeps = append(directStaticDeps, ccDep)
directStaticDeps = append(directStaticDeps, staticLibraryInfo)
case lateLibraryDependency:
ptr = &depPaths.LateStaticLibs
default:
@ -2699,10 +2531,10 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
staticLib.objs().coverageFiles...)
depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
staticLib.objs().sAbiDumpFiles...)
} else if c, ok := ccDep.(LinkableInterface); ok {
} else {
// Handle non-CC modules here
depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
c.CoverageFiles()...)
ccDep.CoverageFiles()...)
}
}
@ -2726,6 +2558,22 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
*depPtr = append(*depPtr, dep.Path())
}
depPaths.IncludeDirs = append(depPaths.IncludeDirs, depExporterInfo.IncludeDirs...)
depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, depExporterInfo.SystemIncludeDirs...)
depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, depExporterInfo.Deps...)
depPaths.Flags = append(depPaths.Flags, depExporterInfo.Flags...)
if libDepTag.reexportFlags {
reexportExporter(depExporterInfo)
// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
// Re-exported shared library headers must be included as well since they can help us with type information
// about template instantiations (instantiated from their headers).
// -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version
// scripts.
c.sabi.Properties.ReexportedIncludes = append(
c.sabi.Properties.ReexportedIncludes, depExporterInfo.IncludeDirs.Strings()...)
}
makeLibName := c.makeLibName(ctx, ccDep, depName) + libDepTag.makeSuffix
switch {
case libDepTag.header():
@ -2779,7 +2627,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
})
// use the ordered dependencies as this module's dependencies
depPaths.StaticLibs = append(depPaths.StaticLibs, orderStaticModuleDeps(c, directStaticDeps, directSharedDeps)...)
orderedStaticPaths, transitiveStaticLibs := orderStaticModuleDeps(directStaticDeps, directSharedDeps)
depPaths.TranstiveStaticLibrariesForOrdering = transitiveStaticLibs
depPaths.StaticLibs = append(depPaths.StaticLibs, orderedStaticPaths...)
// Dedup exported flags from dependencies
depPaths.Flags = android.FirstUniqueStrings(depPaths.Flags)
@ -2799,6 +2649,38 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return depPaths
}
// orderStaticModuleDeps rearranges the order of the static library dependencies of the module
// to match the topological order of the dependency tree, including any static analogues of
// direct shared libraries. It returns the ordered static dependencies, and an android.DepSet
// of the transitive dependencies.
func orderStaticModuleDeps(staticDeps []StaticLibraryInfo, sharedDeps []SharedLibraryInfo) (ordered android.Paths, transitive *android.DepSet) {
transitiveStaticLibsBuilder := android.NewDepSetBuilder(android.TOPOLOGICAL)
var staticPaths android.Paths
for _, staticDep := range staticDeps {
staticPaths = append(staticPaths, staticDep.StaticLibrary)
transitiveStaticLibsBuilder.Transitive(staticDep.TransitiveStaticLibrariesForOrdering)
}
for _, sharedDep := range sharedDeps {
if sharedDep.StaticAnalogue != nil {
transitiveStaticLibsBuilder.Transitive(sharedDep.StaticAnalogue.TransitiveStaticLibrariesForOrdering)
}
}
transitiveStaticLibs := transitiveStaticLibsBuilder.Build()
orderedTransitiveStaticLibs := transitiveStaticLibs.ToList()
// reorder the dependencies based on transitive dependencies
staticPaths = android.FirstUniquePaths(staticPaths)
_, orderedStaticPaths := android.FilterPathList(orderedTransitiveStaticLibs, staticPaths)
if len(orderedStaticPaths) != len(staticPaths) {
missing, _ := android.FilterPathList(staticPaths, orderedStaticPaths)
panic(fmt.Errorf("expected %d ordered static paths , got %d, missing %q %q %q", len(staticPaths), len(orderedStaticPaths), missing, orderedStaticPaths, staticPaths))
}
return orderedStaticPaths, transitiveStaticLibs
}
// baseLibName trims known prefixes and suffixes
func baseLibName(depName string) string {
libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
@ -3096,8 +2978,8 @@ func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return false
}
}
if depTag == llndkImplDep {
// We don't track beyond LLNDK
if depTag == stubImplDepTag || depTag == llndkImplDep {
// We don't track beyond LLNDK or from an implementation library to its stubs.
return false
}
return true

View file

@ -20,7 +20,6 @@ import (
"os"
"path/filepath"
"reflect"
"sort"
"strings"
"testing"
@ -2890,59 +2889,6 @@ func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[an
return modulesInOrder, allDeps
}
func TestLinkReordering(t *testing.T) {
for _, testCase := range staticLinkDepOrderTestCases {
errs := []string{}
// parse testcase
_, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
if testCase.allOrdered == "" {
// allow the test case to skip specifying allOrdered
testCase.allOrdered = testCase.outOrdered
}
_, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
_, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
// For each module whose post-reordered dependencies were specified, validate that
// reordering the inputs produces the expected outputs.
for _, moduleName := range expectedModuleNames {
moduleDeps := givenTransitiveDeps[moduleName]
givenSharedDeps := givenAllSharedDeps[moduleName]
orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
correctAllOrdered := expectedAllDeps[moduleName]
if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
"\nin static:%q"+
"\nin shared:%q"+
"\nmodule: %v"+
"\nexpected: %s"+
"\nactual: %s",
testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
}
correctOutputDeps := expectedTransitiveDeps[moduleName]
if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
"\nin static:%q"+
"\nin shared:%q"+
"\nmodule: %v"+
"\nexpected: %s"+
"\nactual: %s",
testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
}
}
if len(errs) > 0 {
sort.Strings(errs)
for _, err := range errs {
t.Error(err)
}
}
}
}
func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
for _, moduleName := range moduleNames {
module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
@ -2977,8 +2923,8 @@ func TestStaticLibDepReordering(t *testing.T) {
variant := "android_arm64_armv8-a_static"
moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
actual := moduleA.depsInLinkOrder
expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).TransitiveStaticLibrariesForOrdering.ToList()
expected := getOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings were not propagated correctly"+
@ -3011,8 +2957,8 @@ func TestStaticLibDepReorderingWithShared(t *testing.T) {
variant := "android_arm64_armv8-a_static"
moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
actual := moduleA.depsInLinkOrder
expected := getOutputPaths(ctx, variant, []string{"c", "b"})
actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).TransitiveStaticLibrariesForOrdering.ToList()
expected := getOutputPaths(ctx, variant, []string{"a", "c", "b"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings did not account for shared libs"+
@ -3048,12 +2994,12 @@ func TestLlndkLibrary(t *testing.T) {
`)
actual := ctx.ModuleVariantsForTests("libllndk.llndk")
expected := []string{
"android_vendor.VER_arm64_armv8-a_shared",
"android_vendor.VER_arm64_armv8-a_shared_1",
"android_vendor.VER_arm64_armv8-a_shared_2",
"android_vendor.VER_arm_armv7-a-neon_shared",
"android_vendor.VER_arm64_armv8-a_shared",
"android_vendor.VER_arm_armv7-a-neon_shared_1",
"android_vendor.VER_arm_armv7-a-neon_shared_2",
"android_vendor.VER_arm_armv7-a-neon_shared",
}
checkEquals(t, "variants for llndk stubs", expected, actual)
@ -3582,7 +3528,7 @@ func TestStaticDepsOrderWithStubs(t *testing.T) {
cc_binary {
name: "mybin",
srcs: ["foo.c"],
static_libs: ["libfooB"],
static_libs: ["libfooC", "libfooB"],
static_executable: true,
stl: "none",
}
@ -3603,8 +3549,8 @@ func TestStaticDepsOrderWithStubs(t *testing.T) {
},
}`)
mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Module().(*Module)
actual := mybin.depsInLinkOrder
mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
actual := mybin.Implicits[:2]
expected := getOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
if !reflect.DeepEqual(actual, expected) {

View file

@ -26,6 +26,7 @@ func (stub *kernelHeadersDecorator) link(ctx ModuleContext, flags Flags, deps Pa
if ctx.Device() {
f := &stub.libraryDecorator.flagExporter
f.reexportSystemDirs(android.PathsForSource(ctx, ctx.DeviceConfig().DeviceKernelHeaderDirs())...)
f.setProvider(ctx)
}
return stub.libraryDecorator.linkStatic(ctx, flags, deps, objs)
}

View file

@ -291,36 +291,16 @@ func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
f.headers = append(f.headers, headers...)
}
func (f *flagExporter) exportedDirs() android.Paths {
return f.dirs
func (f *flagExporter) setProvider(ctx android.ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
IncludeDirs: f.dirs,
SystemIncludeDirs: f.systemDirs,
Flags: f.flags,
Deps: f.deps,
GeneratedHeaders: f.headers,
})
}
func (f *flagExporter) exportedSystemDirs() android.Paths {
return f.systemDirs
}
func (f *flagExporter) exportedFlags() []string {
return f.flags
}
func (f *flagExporter) exportedDeps() android.Paths {
return f.deps
}
func (f *flagExporter) exportedGeneratedHeaders() android.Paths {
return f.headers
}
type exportedFlagsProducer interface {
exportedDirs() android.Paths
exportedSystemDirs() android.Paths
exportedFlags() []string
exportedDeps() android.Paths
exportedGeneratedHeaders() android.Paths
}
var _ exportedFlagsProducer = (*flagExporter)(nil)
// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific
// functionality: static vs. shared linkage, reusing object files for shared libraries
type libraryDecorator struct {
@ -396,7 +376,7 @@ func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext)
// can't be globbed, and they should be manually collected.
// So, we first filter out intermediate directories (which contains generated headers)
// from exported directories, and then glob headers under remaining directories.
for _, path := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
for _, path := range append(android.CopyOfPaths(l.flagExporter.dirs), l.flagExporter.systemDirs...) {
dir := path.String()
// Skip if dir is for generated headers
if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
@ -448,7 +428,7 @@ func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext)
}
// Collect generated headers
for _, header := range append(l.exportedGeneratedHeaders(), l.exportedDeps()...) {
for _, header := range append(android.CopyOfPaths(l.flagExporter.headers), l.flagExporter.deps...) {
// TODO(b/148123511): remove exportedDeps after cleaning up genrule
if strings.HasSuffix(header.Base(), "-phony") {
continue
@ -681,7 +661,7 @@ type libraryInterface interface {
static() bool
shared() bool
objs() Objects
reuseObjs() (Objects, exportedFlagsProducer)
reuseObjs() Objects
toc() android.OptionalPath
// Returns true if the build options for the module have selected a static or shared build
@ -886,6 +866,17 @@ func (library *libraryDecorator) linkStatic(ctx ModuleContext,
ctx.CheckbuildFile(outputFile)
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
StaticLibrary: outputFile,
ReuseObjects: library.reuseObjects,
Objects: library.objects,
TransitiveStaticLibrariesForOrdering: android.NewDepSetBuilder(android.TOPOLOGICAL).
Direct(outputFile).
Transitive(deps.TranstiveStaticLibrariesForOrdering).
Build(),
})
return outputFile
}
@ -930,7 +921,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
outputFile := android.PathForModuleOut(ctx, fileName)
ret := outputFile
unstrippedOutputFile := outputFile
var implicitOutputs android.WritablePaths
if ctx.Windows() {
@ -1012,9 +1003,42 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
library.coverageOutputFile = TransformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
library.linkSAbiDumpFiles(ctx, objs, fileName, ret)
library.linkSAbiDumpFiles(ctx, objs, fileName, unstrippedOutputFile)
return ret
var staticAnalogue *StaticLibraryInfo
if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
s := ctx.OtherModuleProvider(static[0], StaticLibraryInfoProvider).(StaticLibraryInfo)
staticAnalogue = &s
}
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
TableOfContents: android.OptionalPathForPath(tocFile),
SharedLibrary: unstrippedOutputFile,
UnstrippedSharedLibrary: library.unstrippedOutputFile,
CoverageSharedLibrary: library.coverageOutputFile,
StaticAnalogue: staticAnalogue,
})
stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
if len(stubs) > 0 {
var stubsInfo []SharedLibraryStubsInfo
for _, stub := range stubs {
stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo)
flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo)
stubsInfo = append(stubsInfo, SharedLibraryStubsInfo{
Version: stub.(*Module).StubsVersion(),
SharedLibraryInfo: stubInfo,
FlagExporterInfo: flagInfo,
})
}
ctx.SetProvider(SharedLibraryImplementationStubsInfoProvider, SharedLibraryImplementationStubsInfo{
SharedLibraryStubsInfos: stubsInfo,
IsLLNDK: ctx.isLlndk(ctx.Config()),
})
}
return unstrippedOutputFile
}
func (library *libraryDecorator) unstrippedOutputFilePath() android.Path {
@ -1162,6 +1186,8 @@ func (library *libraryDecorator) link(ctx ModuleContext,
library.reexportFlags("-D" + versioningMacroName(ctx.ModuleName()) + "=" + library.stubsVersion())
}
library.flagExporter.setProvider(ctx)
return out
}
@ -1179,8 +1205,8 @@ func (library *libraryDecorator) objs() Objects {
return library.objects
}
func (library *libraryDecorator) reuseObjs() (Objects, exportedFlagsProducer) {
return library.reuseObjects, &library.flagExporter
func (library *libraryDecorator) reuseObjs() Objects {
return library.reuseObjects
}
func (library *libraryDecorator) toc() android.OptionalPath {
@ -1423,10 +1449,10 @@ func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Mod
sharedCompiler.baseCompiler.Properties.Srcs
sharedCompiler.baseCompiler.Properties.Srcs = nil
sharedCompiler.baseCompiler.Properties.Generated_sources = nil
} else {
// This dep is just to reference static variant from shared variant
mctx.AddInterVariantDependency(staticVariantTag, shared, static)
}
// This dep is just to reference static variant from shared variant
mctx.AddInterVariantDependency(staticVariantTag, shared, static)
}
}
@ -1525,15 +1551,15 @@ func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
// "" is for the non-stubs (implementation) variant.
variants := append([]string{""}, versions...)
variants := append(android.CopyOf(versions), "")
modules := mctx.CreateLocalVariations(variants...)
for i, m := range modules {
if variants[i] != "" {
m.(LinkableInterface).SetBuildStubs()
m.(LinkableInterface).SetStubsVersion(variants[i])
// The stubs depend on the implementation
mctx.AddInterVariantDependency(stubImplDepTag, modules[i], modules[0])
// The implementation depends on the stubs
mctx.AddInterVariantDependency(stubImplDepTag, modules[len(modules)-1], modules[i])
}
}
mctx.AliasVariation("")
@ -1570,9 +1596,7 @@ func CanBeVersionVariant(module interface {
// and propagates the value from implementation libraries to llndk libraries with the same name.
func versionSelectorMutator(mctx android.BottomUpMutatorContext) {
if library, ok := mctx.Module().(LinkableInterface); ok && CanBeVersionVariant(library) {
if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 &&
!library.IsSdkVariant() {
if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 {
versions := library.StubsVersions()
normalizeVersions(mctx, versions)

View file

@ -391,10 +391,12 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte
p.outputFile = getRequiredMemberOutputFile(ctx, ccModule)
}
exportedInfo := ctx.SdkModuleContext().OtherModuleProvider(variant, FlagExporterInfoProvider).(FlagExporterInfo)
// Separate out the generated include dirs (which are arch specific) from the
// include dirs (which may not be).
exportedIncludeDirs, exportedGeneratedIncludeDirs := android.FilterPathListPredicate(
ccModule.ExportedIncludeDirs(), isGeneratedHeaderDirectory)
exportedInfo.IncludeDirs, isGeneratedHeaderDirectory)
p.name = variant.Name()
p.archType = ccModule.Target().Arch.ArchType.String()
@ -405,10 +407,10 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte
// Take a copy before filtering out duplicates to avoid changing the slice owned by the
// ccModule.
dirs := append(android.Paths(nil), ccModule.ExportedSystemIncludeDirs()...)
dirs := append(android.Paths(nil), exportedInfo.SystemIncludeDirs...)
p.ExportedSystemIncludeDirs = android.FirstUniquePaths(dirs)
p.ExportedFlags = ccModule.ExportedFlags()
p.ExportedFlags = exportedInfo.Flags
if ccModule.linker != nil {
specifiedDeps := specifiedDeps{}
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps)
@ -419,7 +421,7 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte
}
p.SystemSharedLibs = specifiedDeps.systemSharedLibs
}
p.exportedGeneratedHeaders = ccModule.ExportedGeneratedHeaders()
p.exportedGeneratedHeaders = exportedInfo.GeneratedHeaders
if ccModule.HasStubsVariants() {
// TODO(b/169373910): 1. Only output the specific version (from

View file

@ -14,13 +14,6 @@ type LinkableInterface interface {
OutputFile() android.OptionalPath
CoverageFiles() android.Paths
IncludeDirs() android.Paths
SetDepsInLinkOrder([]android.Path)
GetDepsInLinkOrder() []android.Path
HasStaticVariant() bool
GetStaticVariant() LinkableInterface
NonCcVariants() bool
StubsVersions() []string
@ -80,3 +73,54 @@ func SharedDepTag() blueprint.DependencyTag {
func StaticDepTag() blueprint.DependencyTag {
return libraryDependencyTag{Kind: staticLibraryDependency}
}
type SharedLibraryInfo struct {
SharedLibrary android.Path
UnstrippedSharedLibrary android.Path
TableOfContents android.OptionalPath
CoverageSharedLibrary android.OptionalPath
StaticAnalogue *StaticLibraryInfo
}
var SharedLibraryInfoProvider = blueprint.NewProvider(SharedLibraryInfo{})
type SharedLibraryImplementationStubsInfo struct {
SharedLibraryStubsInfos []SharedLibraryStubsInfo
IsLLNDK bool
}
var SharedLibraryImplementationStubsInfoProvider = blueprint.NewProvider(SharedLibraryImplementationStubsInfo{})
type SharedLibraryStubsInfo struct {
Version string
SharedLibraryInfo SharedLibraryInfo
FlagExporterInfo FlagExporterInfo
}
var SharedLibraryStubsInfoProvider = blueprint.NewProvider(SharedLibraryStubsInfo{})
type StaticLibraryInfo struct {
StaticLibrary android.Path
Objects Objects
ReuseObjects Objects
// This isn't the actual transitive DepSet, shared library dependencies have been
// converted into static library analogues. It is only used to order the static
// library dependencies that were specified for the current module.
TransitiveStaticLibrariesForOrdering *android.DepSet
}
var StaticLibraryInfoProvider = blueprint.NewProvider(StaticLibraryInfo{})
type FlagExporterInfo struct {
IncludeDirs android.Paths
SystemIncludeDirs android.Paths
Flags []string
Deps android.Paths
GeneratedHeaders android.Paths
}
var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{})

View file

@ -166,7 +166,7 @@ func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
ctx.ModuleErrorf("NDK prebuilt libraries must have an ndk_lib prefixed name")
}
ndk.exportIncludesAsSystem(ctx)
ndk.libraryDecorator.flagExporter.exportIncludesAsSystem(ctx)
libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
libExt := flags.Toolchain.ShlibSuffix()
@ -175,5 +175,23 @@ func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
}
libDir := getNdkStlLibDir(ctx)
return libDir.Join(ctx, libName+libExt)
lib := libDir.Join(ctx, libName+libExt)
ndk.libraryDecorator.flagExporter.setProvider(ctx)
if ndk.static() {
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(lib).Build()
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
StaticLibrary: lib,
TransitiveStaticLibrariesForOrdering: depSet,
})
} else {
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: lib,
UnstrippedSharedLibrary: lib,
})
}
return lib
}

View file

@ -97,12 +97,14 @@ func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
p.libraryDecorator.exportIncludes(ctx)
p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
p.libraryDecorator.flagExporter.exportIncludes(ctx)
p.libraryDecorator.flagExporter.reexportDirs(deps.ReexportedDirs...)
p.libraryDecorator.flagExporter.reexportSystemDirs(deps.ReexportedSystemDirs...)
p.libraryDecorator.flagExporter.reexportFlags(deps.ReexportedFlags...)
p.libraryDecorator.flagExporter.reexportDeps(deps.ReexportedDeps...)
p.libraryDecorator.flagExporter.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
p.libraryDecorator.flagExporter.setProvider(ctx)
// TODO(ccross): verify shared library dependencies
srcs := p.prebuiltSrcs()
@ -117,6 +119,12 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
in := android.PathForModuleSrc(ctx, srcs[0])
if p.static() {
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
StaticLibrary: in,
TransitiveStaticLibrariesForOrdering: depSet,
})
return in
}
@ -170,6 +178,13 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
},
})
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: outputFile,
UnstrippedSharedLibrary: p.unstrippedOutputFile,
TableOfContents: p.tocFile,
})
return outputFile
}
}

View file

@ -22,7 +22,6 @@ var (
)
type snapshotLibraryInterface interface {
exportedFlagsProducer
libraryInterface
collectHeadersForSnapshot(ctx android.ModuleContext)
snapshotHeaders() android.Paths

View file

@ -84,24 +84,31 @@ func (library *toolchainLibraryDecorator) link(ctx ModuleContext,
}
srcPath := android.PathForSource(ctx, *library.Properties.Src)
if library.stripper.StripProperties.Strip.Keep_symbols_list != nil {
fileName := ctx.ModuleName() + staticLibraryExtension
outputFile := android.PathForModuleOut(ctx, fileName)
stripFlags := flagsToStripFlags(flags)
library.stripper.StripStaticLib(ctx, srcPath, outputFile, stripFlags)
return outputFile
}
outputFile := android.Path(srcPath)
if library.Properties.Repack_objects_to_keep != nil {
fileName := ctx.ModuleName() + staticLibraryExtension
outputFile := android.PathForModuleOut(ctx, fileName)
TransformArchiveRepack(ctx, srcPath, outputFile, library.Properties.Repack_objects_to_keep)
return outputFile
repackedPath := android.PathForModuleOut(ctx, fileName)
TransformArchiveRepack(ctx, outputFile, repackedPath, library.Properties.Repack_objects_to_keep)
outputFile = repackedPath
}
return srcPath
if library.stripper.StripProperties.Strip.Keep_symbols_list != nil {
fileName := ctx.ModuleName() + staticLibraryExtension
strippedPath := android.PathForModuleOut(ctx, fileName)
stripFlags := flagsToStripFlags(flags)
library.stripper.StripStaticLib(ctx, outputFile, strippedPath, stripFlags)
outputFile = strippedPath
}
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputFile).Build()
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
StaticLibrary: outputFile,
TransitiveStaticLibrariesForOrdering: depSet,
})
return outputFile
}
func (library *toolchainLibraryDecorator) nativeCoverage() bool {

View file

@ -223,6 +223,22 @@ func (p *vendorSnapshotLibraryDecorator) link(ctx ModuleContext,
tocFile := android.PathForModuleOut(ctx, libName+".toc")
p.tocFile = android.OptionalPathForPath(tocFile)
TransformSharedObjectToToc(ctx, in, tocFile, builderFlags)
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: in,
UnstrippedSharedLibrary: p.unstrippedOutputFile,
TableOfContents: p.tocFile,
})
}
if p.static() {
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
StaticLibrary: in,
TransitiveStaticLibrariesForOrdering: depSet,
})
}
return in
@ -735,13 +751,14 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont
var propOut string
if l, ok := m.linker.(snapshotLibraryInterface); ok {
exporterInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
// library flags
prop.ExportedFlags = l.exportedFlags()
for _, dir := range l.exportedDirs() {
prop.ExportedFlags = exporterInfo.Flags
for _, dir := range exporterInfo.IncludeDirs {
prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
}
for _, dir := range l.exportedSystemDirs() {
for _, dir := range exporterInfo.SystemIncludeDirs {
prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
}
// shared libs dependencies aren't meaningful on static or header libs

View file

@ -620,7 +620,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
var headers android.Paths
installVndkSnapshotLib := func(m *Module, l snapshotLibraryInterface, vndkType string) (android.Paths, bool) {
installVndkSnapshotLib := func(m *Module, vndkType string) (android.Paths, bool) {
var ret android.Paths
targetArch := "arch-" + m.Target().Arch.ArchType.String()
@ -639,9 +639,10 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
ExportedFlags []string `json:",omitempty"`
RelativeInstallPath string `json:",omitempty"`
}{}
prop.ExportedFlags = l.exportedFlags()
prop.ExportedDirs = l.exportedDirs().Strings()
prop.ExportedSystemDirs = l.exportedSystemDirs().Strings()
exportedInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
prop.ExportedFlags = exportedInfo.Flags
prop.ExportedDirs = exportedInfo.IncludeDirs.Strings()
prop.ExportedSystemDirs = exportedInfo.SystemIncludeDirs.Strings()
prop.RelativeInstallPath = m.RelativeInstallPath()
propOut := snapshotLibOut + ".json"
@ -671,7 +672,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
// install .so files for appropriate modules.
// Also install .json files if VNDK_SNAPSHOT_BUILD_ARTIFACTS
libs, ok := installVndkSnapshotLib(m, l, vndkType)
libs, ok := installVndkSnapshotLib(m, vndkType)
if !ok {
return
}

View file

@ -162,6 +162,13 @@ func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
p.androidMkSuffix = ""
}
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: in,
UnstrippedSharedLibrary: p.unstrippedOutputFile,
TableOfContents: p.tocFile,
})
return in
}

View file

@ -20,6 +20,7 @@ import (
"strings"
"android/soong/android"
"android/soong/cc"
)
var (
@ -484,11 +485,35 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
library.coverageOutputZipFile = TransformCoverageFilesToZip(ctx, coverageFiles, library.getStem(ctx))
if library.rlib() || library.dylib() {
library.exportLinkDirs(deps.linkDirs...)
library.exportDepFlags(deps.depFlags...)
library.exportLinkObjects(deps.linkObjects...)
library.flagExporter.exportLinkDirs(deps.linkDirs...)
library.flagExporter.exportDepFlags(deps.depFlags...)
library.flagExporter.exportLinkObjects(deps.linkObjects...)
}
if library.static() || library.shared() {
ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
IncludeDirs: library.includeDirs,
})
}
if library.shared() {
ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
SharedLibrary: outputFile,
UnstrippedSharedLibrary: outputFile,
})
}
if library.static() {
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputFile).Build()
ctx.SetProvider(cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
StaticLibrary: outputFile,
TransitiveStaticLibrariesForOrdering: depSet,
})
}
library.flagExporter.setProvider(ctx)
return outputFile
}

View file

@ -93,7 +93,8 @@ func (prebuilt *prebuiltLibraryDecorator) compilerProps() []interface{} {
}
func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
prebuilt.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
prebuilt.flagExporter.setProvider(ctx)
srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
if len(paths) > 0 {

View file

@ -302,9 +302,6 @@ type compiler interface {
}
type exportedFlagsProducer interface {
exportedLinkDirs() []string
exportedDepFlags() []string
exportedLinkObjects() []string
exportLinkDirs(...string)
exportDepFlags(...string)
exportLinkObjects(...string)
@ -316,18 +313,6 @@ type flagExporter struct {
linkObjects []string
}
func (flagExporter *flagExporter) exportedLinkDirs() []string {
return flagExporter.linkDirs
}
func (flagExporter *flagExporter) exportedDepFlags() []string {
return flagExporter.depFlags
}
func (flagExporter *flagExporter) exportedLinkObjects() []string {
return flagExporter.linkObjects
}
func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
}
@ -340,16 +325,28 @@ func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
}
func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
Flags: flagExporter.depFlags,
LinkDirs: flagExporter.linkDirs,
LinkObjects: flagExporter.linkObjects,
})
}
var _ exportedFlagsProducer = (*flagExporter)(nil)
func NewFlagExporter() *flagExporter {
return &flagExporter{
depFlags: []string{},
linkDirs: []string{},
linkObjects: []string{},
}
return &flagExporter{}
}
type FlagExporterInfo struct {
Flags []string
LinkDirs []string // TODO: this should be android.Paths
LinkObjects []string // TODO: this should be android.Paths
}
var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{})
func (mod *Module) isCoverageVariant() bool {
return mod.coverage.Properties.IsCoverageVariant
}
@ -499,17 +496,6 @@ func (mod *Module) BuildSharedVariant() bool {
panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName()))
}
// Rust module deps don't have a link order (?)
func (mod *Module) SetDepsInLinkOrder([]android.Path) {}
func (mod *Module) GetDepsInLinkOrder() []android.Path {
return []android.Path{}
}
func (mod *Module) GetStaticVariant() cc.LinkableInterface {
return nil
}
func (mod *Module) Module() android.Module {
return mod
}
@ -532,12 +518,6 @@ func (mod *Module) InRecovery() bool {
// For now, Rust has no notion of the recovery image
return false
}
func (mod *Module) HasStaticVariant() bool {
if mod.GetStaticVariant() != nil {
return true
}
return false
}
func (mod *Module) CoverageFiles() android.Paths {
if mod.compiler != nil {
@ -701,11 +681,6 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
if mod.compiler.(libraryInterface).source() {
mod.sourceProvider.GenerateSource(ctx, deps)
mod.sourceProvider.setSubName(ctx.ModuleSubDir())
if lib, ok := mod.compiler.(*libraryDecorator); ok {
lib.flagExporter.linkDirs = nil
lib.flagExporter.linkObjects = nil
lib.flagExporter.depFlags = nil
}
} else {
sourceMod := actx.GetDirectDepWithTag(mod.Name(), sourceDepTag)
sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator)
@ -846,10 +821,11 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
//Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS
if lib, ok := rustDep.compiler.(exportedFlagsProducer); ok && depTag != procMacroDepTag {
depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedLinkDirs()...)
depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...)
depPaths.linkObjects = append(depPaths.linkObjects, lib.exportedLinkObjects()...)
if depTag != procMacroDepTag {
exportedInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
}
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
@ -889,24 +865,22 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
case cc.IsStaticDepTag(depTag):
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
if mod, ok := ccDep.(*cc.Module); ok {
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, mod.ExportedGeneratedHeaders()...)
}
exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...)
directStaticLibDeps = append(directStaticLibDeps, ccDep)
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
case cc.IsSharedDepTag(depTag):
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
if mod, ok := ccDep.(*cc.Module); ok {
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, mod.ExportedGeneratedHeaders()...)
}
exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
directSharedLibDeps = append(directSharedLibDeps, ccDep)
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true