Start using Providers instead of direct module access
Export information about static libraries, shared libraries and exported flags through Providers instead of accessing the module directly. Much more is left to be converted, but this significantly simplifies the dependencies on libraries with stubs by making it easy for a module to masquerade as another by simply exporting the providers from the other module. Instead of depending on all the versions of a library and then picking which one to use later, it can depend only on the implementation variant and then select the right SharedLibraryInfo from the variant. Test: m checkbuild Test: only expected changes to build.ninja Change-Id: I1fd9eb4d251cf96ed8398d586efc3e0817663c76
This commit is contained in:
parent
ff8838cb86
commit
0de8a1e17b
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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" ],
|
||||
|
|
|
@ -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
502
cc/cc.go
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
114
cc/library.go
114
cc/library.go
|
@ -291,36 +291,16 @@ func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
|
|||
f.headers = append(f.headers, headers...)
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportedDirs() android.Paths {
|
||||
return f.dirs
|
||||
func (f *flagExporter) setProvider(ctx android.ModuleContext) {
|
||||
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
|
||||
IncludeDirs: f.dirs,
|
||||
SystemIncludeDirs: f.systemDirs,
|
||||
Flags: f.flags,
|
||||
Deps: f.deps,
|
||||
GeneratedHeaders: f.headers,
|
||||
})
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportedSystemDirs() android.Paths {
|
||||
return f.systemDirs
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportedFlags() []string {
|
||||
return f.flags
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportedDeps() android.Paths {
|
||||
return f.deps
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportedGeneratedHeaders() android.Paths {
|
||||
return f.headers
|
||||
}
|
||||
|
||||
type exportedFlagsProducer interface {
|
||||
exportedDirs() android.Paths
|
||||
exportedSystemDirs() android.Paths
|
||||
exportedFlags() []string
|
||||
exportedDeps() android.Paths
|
||||
exportedGeneratedHeaders() android.Paths
|
||||
}
|
||||
|
||||
var _ exportedFlagsProducer = (*flagExporter)(nil)
|
||||
|
||||
// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific
|
||||
// functionality: static vs. shared linkage, reusing object files for shared libraries
|
||||
type libraryDecorator struct {
|
||||
|
@ -396,7 +376,7 @@ func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext)
|
|||
// can't be globbed, and they should be manually collected.
|
||||
// So, we first filter out intermediate directories (which contains generated headers)
|
||||
// from exported directories, and then glob headers under remaining directories.
|
||||
for _, path := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
|
||||
for _, path := range append(android.CopyOfPaths(l.flagExporter.dirs), l.flagExporter.systemDirs...) {
|
||||
dir := path.String()
|
||||
// Skip if dir is for generated headers
|
||||
if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
|
||||
|
@ -448,7 +428,7 @@ func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext)
|
|||
}
|
||||
|
||||
// Collect generated headers
|
||||
for _, header := range append(l.exportedGeneratedHeaders(), l.exportedDeps()...) {
|
||||
for _, header := range append(android.CopyOfPaths(l.flagExporter.headers), l.flagExporter.deps...) {
|
||||
// TODO(b/148123511): remove exportedDeps after cleaning up genrule
|
||||
if strings.HasSuffix(header.Base(), "-phony") {
|
||||
continue
|
||||
|
@ -681,7 +661,7 @@ type libraryInterface interface {
|
|||
static() bool
|
||||
shared() bool
|
||||
objs() Objects
|
||||
reuseObjs() (Objects, exportedFlagsProducer)
|
||||
reuseObjs() Objects
|
||||
toc() android.OptionalPath
|
||||
|
||||
// Returns true if the build options for the module have selected a static or shared build
|
||||
|
@ -886,6 +866,17 @@ func (library *libraryDecorator) linkStatic(ctx ModuleContext,
|
|||
|
||||
ctx.CheckbuildFile(outputFile)
|
||||
|
||||
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
|
||||
StaticLibrary: outputFile,
|
||||
ReuseObjects: library.reuseObjects,
|
||||
Objects: library.objects,
|
||||
|
||||
TransitiveStaticLibrariesForOrdering: android.NewDepSetBuilder(android.TOPOLOGICAL).
|
||||
Direct(outputFile).
|
||||
Transitive(deps.TranstiveStaticLibrariesForOrdering).
|
||||
Build(),
|
||||
})
|
||||
|
||||
return outputFile
|
||||
}
|
||||
|
||||
|
@ -930,7 +921,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
|
|||
|
||||
fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
|
||||
outputFile := android.PathForModuleOut(ctx, fileName)
|
||||
ret := outputFile
|
||||
unstrippedOutputFile := outputFile
|
||||
|
||||
var implicitOutputs android.WritablePaths
|
||||
if ctx.Windows() {
|
||||
|
@ -1012,9 +1003,42 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
|
|||
objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
|
||||
|
||||
library.coverageOutputFile = TransformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
|
||||
library.linkSAbiDumpFiles(ctx, objs, fileName, ret)
|
||||
library.linkSAbiDumpFiles(ctx, objs, fileName, unstrippedOutputFile)
|
||||
|
||||
return ret
|
||||
var staticAnalogue *StaticLibraryInfo
|
||||
if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
|
||||
s := ctx.OtherModuleProvider(static[0], StaticLibraryInfoProvider).(StaticLibraryInfo)
|
||||
staticAnalogue = &s
|
||||
}
|
||||
|
||||
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
|
||||
TableOfContents: android.OptionalPathForPath(tocFile),
|
||||
SharedLibrary: unstrippedOutputFile,
|
||||
UnstrippedSharedLibrary: library.unstrippedOutputFile,
|
||||
CoverageSharedLibrary: library.coverageOutputFile,
|
||||
StaticAnalogue: staticAnalogue,
|
||||
})
|
||||
|
||||
stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
|
||||
if len(stubs) > 0 {
|
||||
var stubsInfo []SharedLibraryStubsInfo
|
||||
for _, stub := range stubs {
|
||||
stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo)
|
||||
flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo)
|
||||
stubsInfo = append(stubsInfo, SharedLibraryStubsInfo{
|
||||
Version: stub.(*Module).StubsVersion(),
|
||||
SharedLibraryInfo: stubInfo,
|
||||
FlagExporterInfo: flagInfo,
|
||||
})
|
||||
}
|
||||
ctx.SetProvider(SharedLibraryImplementationStubsInfoProvider, SharedLibraryImplementationStubsInfo{
|
||||
SharedLibraryStubsInfos: stubsInfo,
|
||||
|
||||
IsLLNDK: ctx.isLlndk(ctx.Config()),
|
||||
})
|
||||
}
|
||||
|
||||
return unstrippedOutputFile
|
||||
}
|
||||
|
||||
func (library *libraryDecorator) unstrippedOutputFilePath() android.Path {
|
||||
|
@ -1162,6 +1186,8 @@ func (library *libraryDecorator) link(ctx ModuleContext,
|
|||
library.reexportFlags("-D" + versioningMacroName(ctx.ModuleName()) + "=" + library.stubsVersion())
|
||||
}
|
||||
|
||||
library.flagExporter.setProvider(ctx)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
|
@ -1179,8 +1205,8 @@ func (library *libraryDecorator) objs() Objects {
|
|||
return library.objects
|
||||
}
|
||||
|
||||
func (library *libraryDecorator) reuseObjs() (Objects, exportedFlagsProducer) {
|
||||
return library.reuseObjects, &library.flagExporter
|
||||
func (library *libraryDecorator) reuseObjs() Objects {
|
||||
return library.reuseObjects
|
||||
}
|
||||
|
||||
func (library *libraryDecorator) toc() android.OptionalPath {
|
||||
|
@ -1423,10 +1449,10 @@ func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Mod
|
|||
sharedCompiler.baseCompiler.Properties.Srcs
|
||||
sharedCompiler.baseCompiler.Properties.Srcs = nil
|
||||
sharedCompiler.baseCompiler.Properties.Generated_sources = nil
|
||||
} else {
|
||||
// This dep is just to reference static variant from shared variant
|
||||
mctx.AddInterVariantDependency(staticVariantTag, shared, static)
|
||||
}
|
||||
|
||||
// This dep is just to reference static variant from shared variant
|
||||
mctx.AddInterVariantDependency(staticVariantTag, shared, static)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1525,15 +1551,15 @@ func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
|
|||
|
||||
func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
|
||||
// "" is for the non-stubs (implementation) variant.
|
||||
variants := append([]string{""}, versions...)
|
||||
variants := append(android.CopyOf(versions), "")
|
||||
|
||||
modules := mctx.CreateLocalVariations(variants...)
|
||||
for i, m := range modules {
|
||||
if variants[i] != "" {
|
||||
m.(LinkableInterface).SetBuildStubs()
|
||||
m.(LinkableInterface).SetStubsVersion(variants[i])
|
||||
// The stubs depend on the implementation
|
||||
mctx.AddInterVariantDependency(stubImplDepTag, modules[i], modules[0])
|
||||
// The implementation depends on the stubs
|
||||
mctx.AddInterVariantDependency(stubImplDepTag, modules[len(modules)-1], modules[i])
|
||||
}
|
||||
}
|
||||
mctx.AliasVariation("")
|
||||
|
@ -1570,9 +1596,7 @@ func CanBeVersionVariant(module interface {
|
|||
// and propagates the value from implementation libraries to llndk libraries with the same name.
|
||||
func versionSelectorMutator(mctx android.BottomUpMutatorContext) {
|
||||
if library, ok := mctx.Module().(LinkableInterface); ok && CanBeVersionVariant(library) {
|
||||
|
||||
if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 &&
|
||||
!library.IsSdkVariant() {
|
||||
if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 {
|
||||
|
||||
versions := library.StubsVersions()
|
||||
normalizeVersions(mctx, versions)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{})
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -97,12 +97,14 @@ func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
|
|||
func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
|
||||
flags Flags, deps PathDeps, objs Objects) android.Path {
|
||||
|
||||
p.libraryDecorator.exportIncludes(ctx)
|
||||
p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
|
||||
p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
|
||||
p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
|
||||
p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
|
||||
p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
|
||||
p.libraryDecorator.flagExporter.exportIncludes(ctx)
|
||||
p.libraryDecorator.flagExporter.reexportDirs(deps.ReexportedDirs...)
|
||||
p.libraryDecorator.flagExporter.reexportSystemDirs(deps.ReexportedSystemDirs...)
|
||||
p.libraryDecorator.flagExporter.reexportFlags(deps.ReexportedFlags...)
|
||||
p.libraryDecorator.flagExporter.reexportDeps(deps.ReexportedDeps...)
|
||||
p.libraryDecorator.flagExporter.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
|
||||
|
||||
p.libraryDecorator.flagExporter.setProvider(ctx)
|
||||
|
||||
// TODO(ccross): verify shared library dependencies
|
||||
srcs := p.prebuiltSrcs()
|
||||
|
@ -117,6 +119,12 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
|
|||
in := android.PathForModuleSrc(ctx, srcs[0])
|
||||
|
||||
if p.static() {
|
||||
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
|
||||
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
|
||||
StaticLibrary: in,
|
||||
|
||||
TransitiveStaticLibrariesForOrdering: depSet,
|
||||
})
|
||||
return in
|
||||
}
|
||||
|
||||
|
@ -170,6 +178,13 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
|
|||
},
|
||||
})
|
||||
|
||||
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
|
||||
SharedLibrary: outputFile,
|
||||
UnstrippedSharedLibrary: p.unstrippedOutputFile,
|
||||
|
||||
TableOfContents: p.tocFile,
|
||||
})
|
||||
|
||||
return outputFile
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ var (
|
|||
)
|
||||
|
||||
type snapshotLibraryInterface interface {
|
||||
exportedFlagsProducer
|
||||
libraryInterface
|
||||
collectHeadersForSnapshot(ctx android.ModuleContext)
|
||||
snapshotHeaders() android.Paths
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
11
cc/vndk.go
11
cc/vndk.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
90
rust/rust.go
90
rust/rust.go
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue