From 0de8a1e17bc2c4e74b94458c8f60af4ac99955e4 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 18 Sep 2020 14:15:30 -0700 Subject: [PATCH] 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 --- android/apex.go | 19 -- android/depset.go | 36 +-- apex/apex_test.go | 1 + cc/androidmk.go | 8 +- cc/cc.go | 502 +++++++++++++++------------------------ cc/cc_test.go | 72 +----- cc/kernel_headers.go | 1 + cc/library.go | 114 +++++---- cc/library_sdk_member.go | 10 +- cc/linkable.go | 58 ++++- cc/ndk_prebuilt.go | 22 +- cc/prebuilt.go | 27 ++- cc/snapshot_utils.go | 1 - cc/toolchain_library.go | 33 ++- cc/vendor_snapshot.go | 23 +- cc/vndk.go | 11 +- cc/vndk_prebuilt.go | 7 + rust/library.go | 31 ++- rust/prebuilt.go | 3 +- rust/rust.go | 90 +++---- 20 files changed, 509 insertions(+), 560 deletions(-) diff --git a/android/apex.go b/android/apex.go index c01b71692..3039e7944 100644 --- a/android/apex.go +++ b/android/apex.go @@ -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 { diff --git a/android/depset.go b/android/depset.go index f70709423..60ebcacc8 100644 --- a/android/depset.go +++ b/android/depset.go @@ -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 + } diff --git a/apex/apex_test.go b/apex/apex_test.go index cf2c9533b..96a7a575a 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -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" ], diff --git a/cc/androidmk.go b/cc/androidmk.go index a2549b8e7..899d3398a 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -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()...) } diff --git a/cc/cc.go b/cc/cc.go index 81885509b..8560042ca 100644 --- a/cc/cc.go +++ b/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 diff --git a/cc/cc_test.go b/cc/cc_test.go index e0d464093..d1780cd70 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -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) { diff --git a/cc/kernel_headers.go b/cc/kernel_headers.go index 796de6269..9ea988a42 100644 --- a/cc/kernel_headers.go +++ b/cc/kernel_headers.go @@ -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) } diff --git a/cc/library.go b/cc/library.go index 35828aa71..3a46b1137 100644 --- a/cc/library.go +++ b/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) diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 765fe710f..fcf6069c8 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -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 diff --git a/cc/linkable.go b/cc/linkable.go index a67cd4e4c..21e6f9b4e 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -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{}) diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go index acdc581a2..793ab37fb 100644 --- a/cc/ndk_prebuilt.go +++ b/cc/ndk_prebuilt.go @@ -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 } diff --git a/cc/prebuilt.go b/cc/prebuilt.go index 9d1b01608..f21e4a943 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -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 } } diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go index b72af4405..238508dc9 100644 --- a/cc/snapshot_utils.go +++ b/cc/snapshot_utils.go @@ -22,7 +22,6 @@ var ( ) 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 19f5ea4f7..8c546c51f 100644 --- a/cc/toolchain_library.go +++ b/cc/toolchain_library.go @@ -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 { diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index 529ed600e..4c206e6d2 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -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 diff --git a/cc/vndk.go b/cc/vndk.go index 4169e2129..981e039ec 100644 --- a/cc/vndk.go +++ b/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 } diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go index 94847601e..7c47ef42a 100644 --- a/cc/vndk_prebuilt.go +++ b/cc/vndk_prebuilt.go @@ -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 } diff --git a/rust/library.go b/rust/library.go index 3bba089e6..ae33f0fdd 100644 --- a/rust/library.go +++ b/rust/library.go @@ -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 } diff --git a/rust/prebuilt.go b/rust/prebuilt.go index f9c8934d6..94fe1e546 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -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 { diff --git a/rust/rust.go b/rust/rust.go index ba8673c94..29606fafa 100644 --- a/rust/rust.go +++ b/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