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
diff --git a/cc/androidmk.go b/cc/androidmk.go
index a2549b8..899d339 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -186,17 +186,17 @@
}
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()...)
}
diff --git a/cc/cc.go b/cc/cc.go
index 8188550..8560042 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -130,6 +130,9 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
}
}
+// 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
*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 @@
})
// 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 @@
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 @@
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
diff --git a/cc/cc_test.go b/cc/cc_test.go
index e0d4640..d1780cd 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -20,7 +20,6 @@
"os"
"path/filepath"
"reflect"
- "sort"
"strings"
"testing"
@@ -2890,59 +2889,6 @@
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 @@
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 @@
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 @@
`)
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 @@
cc_binary {
name: "mybin",
srcs: ["foo.c"],
- static_libs: ["libfooB"],
+ static_libs: ["libfooC", "libfooB"],
static_executable: true,
stl: "none",
}
@@ -3603,8 +3549,8 @@
},
}`)
- 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) {
diff --git a/cc/kernel_headers.go b/cc/kernel_headers.go
index 796de62..9ea988a 100644
--- a/cc/kernel_headers.go
+++ b/cc/kernel_headers.go
@@ -26,6 +26,7 @@
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)
}
diff --git a/cc/library.go b/cc/library.go
index 35828aa..3a46b11 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -291,36 +291,16 @@
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 @@
// 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 @@
}
// 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 @@
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 @@
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 @@
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 @@
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 @@
library.reexportFlags("-D" + versioningMacroName(ctx.ModuleName()) + "=" + library.stubsVersion())
}
+ library.flagExporter.setProvider(ctx)
+
return out
}
@@ -1179,8 +1205,8 @@
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 @@
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 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 @@
// 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)
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 765fe71..fcf6069 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -391,10 +391,12 @@
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 @@
// 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 @@
}
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
diff --git a/cc/linkable.go b/cc/linkable.go
index a67cd4e..21e6f9b 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -14,13 +14,6 @@
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 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{})
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index acdc581..793ab37 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -166,7 +166,7 @@
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 @@
}
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
}
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 9d1b016..f21e4a9 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -97,12 +97,14 @@
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 @@
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 @@
},
})
+ ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
+ SharedLibrary: outputFile,
+ UnstrippedSharedLibrary: p.unstrippedOutputFile,
+
+ TableOfContents: p.tocFile,
+ })
+
return outputFile
}
}
diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go
index b72af44..238508d 100644
--- a/cc/snapshot_utils.go
+++ b/cc/snapshot_utils.go
@@ -22,7 +22,6 @@
)
type snapshotLibraryInterface interface {
- exportedFlagsProducer
libraryInterface
collectHeadersForSnapshot(ctx android.ModuleContext)
snapshotHeaders() android.Paths
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index 19f5ea4..8c546c5 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -84,24 +84,31 @@
}
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 {
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 529ed60..4c206e6 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -223,6 +223,22 @@
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 @@
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
diff --git a/cc/vndk.go b/cc/vndk.go
index 4169e21..981e039 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -620,7 +620,7 @@
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 @@
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 @@
// 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
}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 9484760..7c47ef4 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -162,6 +162,13 @@
p.androidMkSuffix = ""
}
+ ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
+ SharedLibrary: in,
+ UnstrippedSharedLibrary: p.unstrippedOutputFile,
+
+ TableOfContents: p.tocFile,
+ })
+
return in
}