Refactor cc modules to use decorators instead of inheritance
For example , instead of trying to have libraryLinker inherit from
baseLinker and libraryCompiler inherit from baseCompiler, create a
single decorator object that wraps both baseLinker and baseCompiler.
Test: Builds, no unexpected changes to build.ninja
Change-Id: I2468adaea8466c203a240259ba5694b8b1df7a52
diff --git a/cc/cc.go b/cc/cc.go
index 8af2b8c..b381897 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -35,8 +35,6 @@
func init() {
soong.RegisterModuleType("cc_defaults", defaultsFactory)
- soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
-
// LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
// the Go initialization order because this package depends on common, so common's init
// functions will run first.
@@ -189,7 +187,6 @@
link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles android.Paths) android.Path
appendLdflags([]string)
- installable() bool
}
type installer interface {
@@ -252,6 +249,8 @@
outputFile android.OptionalPath
cachedToolchain config.Toolchain
+
+ subAndroidMkOnce map[subAndroidMkProvider]bool
}
func (c *Module) Init() (blueprint.Module, []interface{}) {
@@ -283,6 +282,17 @@
return android.InitDefaultableModule(c, c, props...)
}
+// Returns true for dependency roots (binaries)
+// TODO(ccross): also handle dlopenable libraries
+func (c *Module) isDependencyRoot() bool {
+ if root, ok := c.linker.(interface {
+ isDependencyRoot() bool
+ }); ok {
+ return root.isDependencyRoot()
+ }
+ return false
+}
+
type baseModuleContext struct {
android.BaseContext
moduleContextImpl
@@ -322,25 +332,21 @@
}
func (ctx *moduleContextImpl) static() bool {
- if ctx.mod.linker == nil {
- panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
+ if static, ok := ctx.mod.linker.(interface {
+ static() bool
+ }); ok {
+ return static.static()
}
- if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
- return linker.static()
- } else {
- panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
- }
+ return false
}
func (ctx *moduleContextImpl) staticBinary() bool {
- if ctx.mod.linker == nil {
- panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
+ if static, ok := ctx.mod.linker.(interface {
+ staticBinary() bool
+ }); ok {
+ return static.staticBinary()
}
- if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
- return linker.staticBinary()
- } else {
- panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName()))
- }
+ return false
}
func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
@@ -453,7 +459,7 @@
}
c.outputFile = android.OptionalPathForPath(outputFile)
- if c.installer != nil && c.linker.installable() {
+ if c.installer != nil {
c.installer.install(ctx, outputFile)
if ctx.Failed() {
return
@@ -680,7 +686,7 @@
// Platform code can link to anything
return
}
- if _, ok := to.linker.(*toolchainLibraryLinker); ok {
+ if _, ok := to.linker.(*toolchainLibraryDecorator); ok {
// These are always allowed
return
}
@@ -692,7 +698,7 @@
// These are allowed, but don't set sdk_version
return
}
- if _, ok := to.linker.(*stubLinker); ok {
+ if _, ok := to.linker.(*stubDecorator); ok {
// These aren't real libraries, but are the stub shared libraries that are included in
// the NDK.
return
@@ -794,7 +800,7 @@
if tag == reuseObjTag {
depPaths.ObjFiles = append(depPaths.ObjFiles,
- cc.compiler.(*libraryCompiler).reuseObjFiles...)
+ cc.compiler.(libraryInterface).reuseObjs()...)
return
}
@@ -824,8 +830,8 @@
depPtr = &depPaths.LateStaticLibs
case wholeStaticDepTag:
depPtr = &depPaths.WholeStaticLibs
- staticLib, _ := cc.linker.(libraryInterface)
- if staticLib == nil || !staticLib.static() {
+ staticLib, ok := cc.linker.(libraryInterface)
+ if !ok || !staticLib.static() {
ctx.ModuleErrorf("module %q not a static library", name)
return
}
@@ -882,11 +888,11 @@
&BaseProperties{},
&BaseCompilerProperties{},
&BaseLinkerProperties{},
- &LibraryCompilerProperties{},
+ &LibraryProperties{},
&FlagExporterProperties{},
- &LibraryLinkerProperties{},
&BinaryLinkerProperties{},
- &TestLinkerProperties{},
+ &TestProperties{},
+ &TestBinaryProperties{},
&UnusedProperties{},
&StlProperties{},
&SanitizeProperties{},
@@ -899,58 +905,6 @@
return android.InitDefaultsModule(module, module, propertyStructs...)
}
-//
-// Device libraries shipped with gcc
-//
-
-type toolchainLibraryLinker struct {
- baseLinker
-}
-
-var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil)
-
-func (*toolchainLibraryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
- // toolchain libraries can't have any dependencies
- return deps
-}
-
-func (*toolchainLibraryLinker) buildStatic() bool {
- return true
-}
-
-func (*toolchainLibraryLinker) buildShared() bool {
- return false
-}
-
-func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
- module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
- module.compiler = &baseCompiler{}
- module.linker = &toolchainLibraryLinker{}
- module.Properties.Clang = proptools.BoolPtr(false)
- return module.Init()
-}
-
-func (library *toolchainLibraryLinker) link(ctx ModuleContext,
- flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
-
- libName := ctx.ModuleName() + staticLibraryExtension
- outputFile := android.PathForModuleOut(ctx, libName)
-
- if flags.Clang {
- ctx.ModuleErrorf("toolchain_library must use GCC, not Clang")
- }
-
- CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile)
-
- ctx.CheckbuildFile(outputFile)
-
- return outputFile
-}
-
-func (*toolchainLibraryLinker) installable() bool {
- return false
-}
-
// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
// modifies the slice contents in place, and returns a subslice of the original slice
func lastUniqueElements(list []string) []string {