Add a common interface for cc linkable libraries.
Adds an interface, CcLinkableInterface, for cc linkable dependencies
which come from other toolchains such as Rust.
Bug: 140726209
Test: Soong tests pass, rust modules still compile.
Change-Id: I7378a46fad94fd0b735746aaf4e265fd2c2c04d8
diff --git a/cc/cc.go b/cc/cc.go
index 67132e4..32bbffb 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -338,81 +338,50 @@
relativeInstallPath() string
}
-type dependencyTag struct {
- blueprint.BaseDependencyTag
- name string
- library bool
- shared bool
-
- reexportFlags bool
-
- explicitlyVersioned bool
-}
-
type xref interface {
XrefCcFiles() android.Paths
}
var (
- sharedDepTag = dependencyTag{name: "shared", library: true, shared: true}
- sharedExportDepTag = dependencyTag{name: "shared", library: true, shared: true, reexportFlags: true}
- earlySharedDepTag = dependencyTag{name: "early_shared", library: true, shared: true}
- lateSharedDepTag = dependencyTag{name: "late shared", library: true, shared: true}
- staticDepTag = dependencyTag{name: "static", library: true}
- staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
- lateStaticDepTag = dependencyTag{name: "late static", library: true}
- wholeStaticDepTag = dependencyTag{name: "whole static", library: true, reexportFlags: true}
- headerDepTag = dependencyTag{name: "header", library: true}
- headerExportDepTag = dependencyTag{name: "header", library: true, reexportFlags: true}
- genSourceDepTag = dependencyTag{name: "gen source"}
- genHeaderDepTag = dependencyTag{name: "gen header"}
- genHeaderExportDepTag = dependencyTag{name: "gen header", reexportFlags: true}
- objDepTag = dependencyTag{name: "obj"}
- crtBeginDepTag = dependencyTag{name: "crtbegin"}
- crtEndDepTag = dependencyTag{name: "crtend"}
- linkerFlagsDepTag = dependencyTag{name: "linker flags file"}
- dynamicLinkerDepTag = dependencyTag{name: "dynamic linker"}
- reuseObjTag = dependencyTag{name: "reuse objects"}
- staticVariantTag = dependencyTag{name: "static variant"}
- ndkStubDepTag = dependencyTag{name: "ndk stub", library: true}
- ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true}
- vndkExtDepTag = dependencyTag{name: "vndk extends", library: true}
- runtimeDepTag = dependencyTag{name: "runtime lib"}
- coverageDepTag = dependencyTag{name: "coverage"}
- testPerSrcDepTag = dependencyTag{name: "test_per_src"}
+ sharedExportDepTag = DependencyTag{Name: "shared", Library: true, Shared: true, ReexportFlags: true}
+ earlySharedDepTag = DependencyTag{Name: "early_shared", Library: true, Shared: true}
+ lateSharedDepTag = DependencyTag{Name: "late shared", Library: true, Shared: true}
+ staticExportDepTag = DependencyTag{Name: "static", Library: true, ReexportFlags: true}
+ lateStaticDepTag = DependencyTag{Name: "late static", Library: true}
+ wholeStaticDepTag = DependencyTag{Name: "whole static", Library: true, ReexportFlags: true}
+ headerDepTag = DependencyTag{Name: "header", Library: true}
+ headerExportDepTag = DependencyTag{Name: "header", Library: true, ReexportFlags: true}
+ genSourceDepTag = DependencyTag{Name: "gen source"}
+ genHeaderDepTag = DependencyTag{Name: "gen header"}
+ genHeaderExportDepTag = DependencyTag{Name: "gen header", ReexportFlags: true}
+ objDepTag = DependencyTag{Name: "obj"}
+ linkerFlagsDepTag = DependencyTag{Name: "linker flags file"}
+ dynamicLinkerDepTag = DependencyTag{Name: "dynamic linker"}
+ reuseObjTag = DependencyTag{Name: "reuse objects"}
+ staticVariantTag = DependencyTag{Name: "static variant"}
+ ndkStubDepTag = DependencyTag{Name: "ndk stub", Library: true}
+ ndkLateStubDepTag = DependencyTag{Name: "ndk late stub", Library: true}
+ vndkExtDepTag = DependencyTag{Name: "vndk extends", Library: true}
+ runtimeDepTag = DependencyTag{Name: "runtime lib"}
+ coverageDepTag = DependencyTag{Name: "coverage"}
+ testPerSrcDepTag = DependencyTag{Name: "test_per_src"}
)
func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
- return ok && ccDepTag.shared
+ ccDepTag, ok := depTag.(DependencyTag)
+ return ok && ccDepTag.Shared
}
func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
+ ccDepTag, ok := depTag.(DependencyTag)
return ok && ccDepTag == runtimeDepTag
}
func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
+ ccDepTag, ok := depTag.(DependencyTag)
return ok && ccDepTag == testPerSrcDepTag
}
-func SharedDepTag() dependencyTag {
- return sharedDepTag
-}
-
-func StaticDepTag() dependencyTag {
- return staticDepTag
-}
-
-func CrtBeginDepTag() dependencyTag {
- return crtBeginDepTag
-}
-
-func CrtEndDepTag() dependencyTag {
- return crtEndDepTag
-}
-
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer interface
@@ -467,10 +436,131 @@
kytheFiles android.Paths
}
+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 {
+ return library.Properties.Stubs.Versions
+ }
+ }
+ panic(fmt.Errorf("StubsVersions called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) CcLibrary() bool {
+ if c.linker != nil {
+ if _, ok := c.linker.(*libraryDecorator); ok {
+ return true
+ }
+ }
+ return false
+}
+
+func (c *Module) CcLibraryInterface() bool {
+ if _, ok := c.compiler.(libraryInterface); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) SetBuildStubs() {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ library.MutatedProperties.BuildStubs = true
+ return
+ }
+ }
+ panic(fmt.Errorf("SetBuildStubs called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) SetStubsVersions(version string) {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ library.MutatedProperties.StubsVersion = version
+ return
+ }
+ }
+ panic(fmt.Errorf("SetStubsVersions called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) SetStatic() {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ library.setStatic()
+ return
+ }
+ }
+ panic(fmt.Errorf("SetStatic called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) SetShared() {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ library.setShared()
+ return
+ }
+ }
+ panic(fmt.Errorf("SetShared called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) BuildStaticVariant() bool {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ return library.buildStatic()
+ }
+ }
+ panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) BuildSharedVariant() bool {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ return library.buildShared()
+ }
+ }
+ panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) Module() android.Module {
+ return c
+}
+
+func (c *Module) InRecovery() bool {
+ return c.inRecovery()
+}
+
func (c *Module) OutputFile() android.OptionalPath {
return c.outputFile
}
+var _ LinkableInterface = (*Module)(nil)
+
func (c *Module) UnstrippedOutputFile() android.Path {
if c.linker != nil {
return c.linker.unstrippedOutputFilePath()
@@ -971,25 +1061,27 @@
return orderedAllDeps, orderedDeclaredDeps
}
-func orderStaticModuleDeps(module *Module, staticDeps []*Module, sharedDeps []*Module) (results []android.Path) {
+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 {
- allTransitiveDeps[dep.outputFile.Path()] = dep.depsInLinkOrder
- staticDepFiles = append(staticDepFiles, dep.outputFile.Path())
+ allTransitiveDeps[dep.OutputFile().Path()] = dep.GetDepsInLinkOrder()
+ staticDepFiles = append(staticDepFiles, dep.OutputFile().Path())
}
sharedDepFiles := []android.Path{}
for _, sharedDep := range sharedDeps {
- staticAnalogue := sharedDep.staticVariant
- if staticAnalogue != nil {
- allTransitiveDeps[staticAnalogue.outputFile.Path()] = staticAnalogue.depsInLinkOrder
- sharedDepFiles = append(sharedDepFiles, staticAnalogue.outputFile.Path())
+ 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
- module.depsInLinkOrder, results = orderDeps(staticDepFiles, sharedDepFiles, allTransitiveDeps)
+ depsInLinkOrder, results = orderDeps(staticDepFiles, sharedDepFiles, allTransitiveDeps)
+ module.SetDepsInLinkOrder(depsInLinkOrder)
return results
}
@@ -1411,7 +1503,7 @@
}
for _, lib := range deps.StaticLibs {
- depTag := staticDepTag
+ depTag := StaticDepTag
if inList(lib, deps.ReexportStaticLibHeaders) {
depTag = staticExportDepTag
}
@@ -1429,14 +1521,14 @@
{Mutator: "link", Variation: "static"},
}, lateStaticDepTag, deps.LateStaticLibs...)
- addSharedLibDependencies := func(depTag dependencyTag, name string, version string) {
+ addSharedLibDependencies := func(depTag DependencyTag, name string, version string) {
var variations []blueprint.Variation
variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
versionVariantAvail := !ctx.useVndk() && !c.inRecovery()
if version != "" && versionVariantAvail {
// Version is explicitly specified. i.e. libFoo#30
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
- depTag.explicitlyVersioned = true
+ depTag.ExplicitlyVersioned = true
}
actx.AddVariationDependencies(variations, depTag, name)
@@ -1449,7 +1541,7 @@
{Mutator: "link", Variation: "shared"},
{Mutator: "version", Variation: latestVersion},
}, depTag, name)
- // Note that depTag.explicitlyVersioned is false in this case.
+ // Note that depTag.ExplicitlyVersioned is false in this case.
}
}
@@ -1457,7 +1549,7 @@
var sharedLibNames []string
for _, lib := range deps.SharedLibs {
- depTag := sharedDepTag
+ depTag := SharedDepTag
if inList(lib, deps.ReexportSharedLibHeaders) {
depTag = sharedExportDepTag
}
@@ -1499,10 +1591,10 @@
actx.AddVariationDependencies(nil, objDepTag, deps.ObjFiles...)
if deps.CrtBegin != "" {
- actx.AddVariationDependencies(nil, crtBeginDepTag, deps.CrtBegin)
+ actx.AddVariationDependencies(nil, CrtBeginDepTag, deps.CrtBegin)
}
if deps.CrtEnd != "" {
- actx.AddVariationDependencies(nil, crtEndDepTag, deps.CrtEnd)
+ actx.AddVariationDependencies(nil, CrtEndDepTag, deps.CrtEnd)
}
if deps.LinkerFlagsFile != "" {
actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
@@ -1545,7 +1637,7 @@
// Whether a module can link to another module, taking into
// account NDK linking.
-func checkLinkType(ctx android.ModuleContext, from *Module, to *Module, tag dependencyTag) {
+func checkLinkType(ctx android.ModuleContext, from *Module, to *Module, tag DependencyTag) {
if from.Target().Os != android.Android {
// Host code is not restricted
return
@@ -1691,8 +1783,8 @@
func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
- directStaticDeps := []*Module{}
- directSharedDeps := []*Module{}
+ directStaticDeps := []LinkableInterface{}
+ directSharedDeps := []LinkableInterface{}
llndkLibraries := llndkLibraries(ctx.Config())
vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
@@ -1783,20 +1875,20 @@
}
}
- // Extract explicitlyVersioned field from the depTag and reset it inside the struct.
- // Otherwise, sharedDepTag and lateSharedDepTag with explicitlyVersioned set to true
- // won't be matched to sharedDepTag and lateSharedDepTag.
+ // Extract ExplicitlyVersioned field from the depTag and reset it inside the struct.
+ // Otherwise, SharedDepTag and lateSharedDepTag with ExplicitlyVersioned set to true
+ // won't be matched to SharedDepTag and lateSharedDepTag.
explicitlyVersioned := false
- if t, ok := depTag.(dependencyTag); ok {
- explicitlyVersioned = t.explicitlyVersioned
- t.explicitlyVersioned = false
+ if t, ok := depTag.(DependencyTag); ok {
+ explicitlyVersioned = t.ExplicitlyVersioned
+ t.ExplicitlyVersioned = false
depTag = t
}
- if t, ok := depTag.(dependencyTag); ok && t.library {
+ if t, ok := depTag.(DependencyTag); ok && t.Library {
depIsStatic := false
switch depTag {
- case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
depIsStatic = true
}
if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok && !depIsStatic {
@@ -1839,7 +1931,7 @@
depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, i.exportedDeps()...)
depPaths.Flags = append(depPaths.Flags, i.exportedFlags()...)
- if t.reexportFlags {
+ if t.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
@@ -1861,11 +1953,12 @@
depFile := android.OptionalPath{}
switch depTag {
- case ndkStubDepTag, sharedDepTag, sharedExportDepTag:
+ case ndkStubDepTag, SharedDepTag, sharedExportDepTag:
ptr = &depPaths.SharedLibs
depPtr = &depPaths.SharedLibsDeps
depFile = ccDep.linker.(libraryInterface).toc()
directSharedDeps = append(directSharedDeps, ccDep)
+
case earlySharedDepTag:
ptr = &depPaths.EarlySharedLibs
depPtr = &depPaths.EarlySharedLibsDeps
@@ -1875,7 +1968,7 @@
ptr = &depPaths.LateSharedLibs
depPtr = &depPaths.LateSharedLibsDeps
depFile = ccDep.linker.(libraryInterface).toc()
- case staticDepTag, staticExportDepTag:
+ case StaticDepTag, staticExportDepTag:
ptr = nil
directStaticDeps = append(directStaticDeps, ccDep)
case lateStaticDepTag:
@@ -1900,16 +1993,16 @@
// Nothing
case objDepTag:
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
- case crtBeginDepTag:
+ case CrtBeginDepTag:
depPaths.CrtBegin = linkFile
- case crtEndDepTag:
+ case CrtEndDepTag:
depPaths.CrtEnd = linkFile
case dynamicLinkerDepTag:
depPaths.DynamicLinker = linkFile
}
switch depTag {
- case staticDepTag, staticExportDepTag, lateStaticDepTag:
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag:
staticLib, ok := ccDep.linker.(libraryInterface)
if !ok || !staticLib.static() {
ctx.ModuleErrorf("module %q not a static library", depName)
@@ -1983,7 +2076,7 @@
// Export the shared libs to Make.
switch depTag {
- case sharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
+ case SharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok {
if dependentLibrary.buildStubs() && android.InAnyApex(depName) {
// Add the dependency to the APEX(es) providing the library so that
@@ -2004,7 +2097,7 @@
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs,
depName+"."+ndkStub.properties.ApiLevel)
- case staticDepTag, staticExportDepTag, lateStaticDepTag:
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag:
c.Properties.AndroidMkStaticLibs = append(
c.Properties.AndroidMkStaticLibs, makeLibName(depName))
case runtimeDepTag:
@@ -2189,8 +2282,8 @@
}
func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- if depTag, ok := ctx.OtherModuleDependencyTag(dep).(dependencyTag); ok {
- if cc, ok := dep.(*Module); ok && cc.IsStubs() && depTag.shared {
+ if depTag, ok := ctx.OtherModuleDependencyTag(dep).(DependencyTag); ok {
+ if cc, ok := dep.(*Module); ok && cc.IsStubs() && depTag.Shared {
// dynamic dep to a stubs lib crosses APEX boundary
return false
}