Merge "Start using Providers instead of direct module access"

This commit is contained in:
Colin Cross
2020-10-13 21:48:26 +00:00
committed by Gerrit Code Review
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

@@ -294,36 +294,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 {
@@ -399,7 +379,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()) {
@@ -451,7 +431,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
@@ -684,7 +664,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
@@ -889,6 +869,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
}
@@ -933,7 +924,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() {
@@ -1015,9 +1006,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 {
@@ -1165,6 +1189,8 @@ func (library *libraryDecorator) link(ctx ModuleContext,
library.reexportFlags("-D" + versioningMacroName(ctx.ModuleName()) + "=" + library.stubsVersion())
}
library.flagExporter.setProvider(ctx)
return out
}
@@ -1182,8 +1208,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 {
@@ -1426,10 +1452,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)
}
}
@@ -1528,15 +1554,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("")
@@ -1573,9 +1599,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

@@ -98,12 +98,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(ctx)
@@ -118,6 +120,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
}
@@ -171,6 +179,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