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
This commit is contained in:
@@ -166,6 +166,7 @@ bootstrap_go_package {
|
|||||||
"cc/library.go",
|
"cc/library.go",
|
||||||
"cc/object.go",
|
"cc/object.go",
|
||||||
"cc/test.go",
|
"cc/test.go",
|
||||||
|
"cc/toolchain_library.go",
|
||||||
|
|
||||||
"cc/ndk_prebuilt.go",
|
"cc/ndk_prebuilt.go",
|
||||||
"cc/ndk_headers.go",
|
"cc/ndk_headers.go",
|
||||||
|
@@ -26,6 +26,23 @@ import (
|
|||||||
|
|
||||||
type AndroidMkContext interface {
|
type AndroidMkContext interface {
|
||||||
Target() android.Target
|
Target() android.Target
|
||||||
|
subAndroidMk(*android.AndroidMkData, interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type subAndroidMkProvider interface {
|
||||||
|
AndroidMk(AndroidMkContext, *android.AndroidMkData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Module) subAndroidMk(data *android.AndroidMkData, obj interface{}) {
|
||||||
|
if c.subAndroidMkOnce == nil {
|
||||||
|
c.subAndroidMkOnce = make(map[subAndroidMkProvider]bool)
|
||||||
|
}
|
||||||
|
if androidmk, ok := obj.(subAndroidMkProvider); ok {
|
||||||
|
if !c.subAndroidMkOnce[androidmk] {
|
||||||
|
c.subAndroidMkOnce[androidmk] = true
|
||||||
|
androidmk.AndroidMk(c, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) AndroidMk() (ret android.AndroidMkData, err error) {
|
func (c *Module) AndroidMk() (ret android.AndroidMkData, err error) {
|
||||||
@@ -50,43 +67,27 @@ func (c *Module) AndroidMk() (ret android.AndroidMkData, err error) {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
callSubAndroidMk := func(obj interface{}) {
|
|
||||||
if obj != nil {
|
|
||||||
if androidmk, ok := obj.(interface {
|
|
||||||
AndroidMk(AndroidMkContext, *android.AndroidMkData)
|
|
||||||
}); ok {
|
|
||||||
androidmk.AndroidMk(c, &ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, feature := range c.features {
|
for _, feature := range c.features {
|
||||||
callSubAndroidMk(feature)
|
c.subAndroidMk(&ret, feature)
|
||||||
}
|
}
|
||||||
|
|
||||||
callSubAndroidMk(c.compiler)
|
c.subAndroidMk(&ret, c.compiler)
|
||||||
callSubAndroidMk(c.linker)
|
c.subAndroidMk(&ret, c.linker)
|
||||||
if c.linker.installable() {
|
c.subAndroidMk(&ret, c.installer)
|
||||||
callSubAndroidMk(c.installer)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *baseLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
|
if !library.static() {
|
||||||
|
ctx.subAndroidMk(ret, &library.stripper)
|
||||||
|
}
|
||||||
|
|
||||||
if library.static() {
|
if library.static() {
|
||||||
ret.Class = "STATIC_LIBRARIES"
|
ret.Class = "STATIC_LIBRARIES"
|
||||||
} else {
|
} else {
|
||||||
ret.Class = "SHARED_LIBRARIES"
|
ret.Class = "SHARED_LIBRARIES"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (library *libraryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
|
||||||
library.baseLinker.AndroidMk(ctx, ret)
|
|
||||||
|
|
||||||
if !library.static() {
|
|
||||||
library.stripper.AndroidMk(ctx, ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
||||||
var exportedIncludes []string
|
var exportedIncludes []string
|
||||||
@@ -106,6 +107,10 @@ func (library *libraryLinker) AndroidMk(ctx AndroidMkContext, ret *android.Andro
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if !library.static() {
|
||||||
|
ctx.subAndroidMk(ret, library.baseInstaller)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
@@ -119,30 +124,39 @@ func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.Android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
binary.stripper.AndroidMk(ctx, ret)
|
ctx.subAndroidMk(ret, &binary.stripper)
|
||||||
|
|
||||||
ret.Class = "EXECUTABLES"
|
ret.Class = "EXECUTABLES"
|
||||||
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
||||||
fmt.Fprintln(w, "LOCAL_CXX_STL := none")
|
fmt.Fprintln(w, "LOCAL_CXX_STL := none")
|
||||||
fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
|
fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
|
||||||
if binary.static() {
|
if Bool(binary.Properties.Static_executable) {
|
||||||
fmt.Fprintln(w, "LOCAL_FORCE_STATIC_EXECUTABLE := true")
|
fmt.Fprintln(w, "LOCAL_FORCE_STATIC_EXECUTABLE := true")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testBinaryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
func (benchmark *benchmarkDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
test.binaryLinker.AndroidMk(ctx, ret)
|
ctx.subAndroidMk(ret, benchmark.binaryDecorator)
|
||||||
if Bool(test.testLinker.Properties.Test_per_src) {
|
ctx.subAndroidMk(ret, benchmark.baseInstaller)
|
||||||
ret.SubName = "_" + test.binaryLinker.Properties.Stem
|
}
|
||||||
|
|
||||||
|
func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
|
ctx.subAndroidMk(ret, test.binaryDecorator)
|
||||||
|
ctx.subAndroidMk(ret, test.baseInstaller)
|
||||||
|
if Bool(test.Properties.Test_per_src) {
|
||||||
|
ret.SubName = "_" + test.binaryDecorator.Properties.Stem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *toolchainLibraryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
func (test *testLibrary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
library.baseLinker.AndroidMk(ctx, ret)
|
ctx.subAndroidMk(ret, test.libraryDecorator)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (library *toolchainLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
|
ret.Class = "STATIC_LIBRARIES"
|
||||||
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
||||||
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())
|
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())
|
||||||
fmt.Fprintln(w, "LOCAL_CXX_STL := none")
|
fmt.Fprintln(w, "LOCAL_CXX_STL := none")
|
||||||
@@ -185,13 +199,11 @@ func (installer *baseInstaller) AndroidMk(ctx AndroidMkContext, ret *android.And
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *stubCompiler) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
||||||
ret.SubName = "." + strconv.Itoa(c.properties.ApiLevel)
|
ret.SubName = "." + strconv.Itoa(c.properties.ApiLevel)
|
||||||
}
|
|
||||||
|
|
||||||
func (installer *stubInstaller) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
|
|
||||||
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
|
||||||
path, file := filepath.Split(installer.installPath)
|
path, file := filepath.Split(c.installPath)
|
||||||
stem := strings.TrimSuffix(file, filepath.Ext(file))
|
stem := strings.TrimSuffix(file, filepath.Ext(file))
|
||||||
fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
|
fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
|
||||||
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
|
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
|
||||||
|
85
cc/binary.go
85
cc/binary.go
@@ -16,6 +16,7 @@ package cc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
|
"github.com/google/blueprint/proptools"
|
||||||
|
|
||||||
"android/soong"
|
"android/soong"
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
@@ -42,13 +43,13 @@ func init() {
|
|||||||
|
|
||||||
// Module factory for binaries
|
// Module factory for binaries
|
||||||
func binaryFactory() (blueprint.Module, []interface{}) {
|
func binaryFactory() (blueprint.Module, []interface{}) {
|
||||||
module := NewBinary(android.HostAndDeviceSupported)
|
module, _ := NewBinary(android.HostAndDeviceSupported)
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module factory for host binaries
|
// Module factory for host binaries
|
||||||
func binaryHostFactory() (blueprint.Module, []interface{}) {
|
func binaryHostFactory() (blueprint.Module, []interface{}) {
|
||||||
module := NewBinary(android.HostSupported)
|
module, _ := NewBinary(android.HostSupported)
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,8 +57,8 @@ func binaryHostFactory() (blueprint.Module, []interface{}) {
|
|||||||
// Executables
|
// Executables
|
||||||
//
|
//
|
||||||
|
|
||||||
type binaryLinker struct {
|
type binaryDecorator struct {
|
||||||
baseLinker
|
*baseLinker
|
||||||
stripper
|
stripper
|
||||||
|
|
||||||
Properties BinaryLinkerProperties
|
Properties BinaryLinkerProperties
|
||||||
@@ -65,24 +66,16 @@ type binaryLinker struct {
|
|||||||
hostToolPath android.OptionalPath
|
hostToolPath android.OptionalPath
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ linker = (*binaryLinker)(nil)
|
var _ linker = (*binaryDecorator)(nil)
|
||||||
|
|
||||||
func (binary *binaryLinker) linkerProps() []interface{} {
|
func (binary *binaryDecorator) linkerProps() []interface{} {
|
||||||
return append(binary.baseLinker.linkerProps(),
|
return append(binary.baseLinker.linkerProps(),
|
||||||
&binary.Properties,
|
&binary.Properties,
|
||||||
&binary.stripper.StripProperties)
|
&binary.stripper.StripProperties)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) buildStatic() bool {
|
func (binary *binaryDecorator) getStem(ctx BaseModuleContext) string {
|
||||||
return binary.baseLinker.staticBinary()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (binary *binaryLinker) buildShared() bool {
|
|
||||||
return !binary.baseLinker.staticBinary()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
|
|
||||||
stem := ctx.ModuleName()
|
stem := ctx.ModuleName()
|
||||||
if binary.Properties.Stem != "" {
|
if binary.Properties.Stem != "" {
|
||||||
stem = binary.Properties.Stem
|
stem = binary.Properties.Stem
|
||||||
@@ -91,22 +84,22 @@ func (binary *binaryLinker) getStem(ctx BaseModuleContext) string {
|
|||||||
return stem + binary.Properties.Suffix
|
return stem + binary.Properties.Suffix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
func (binary *binaryDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
deps = binary.baseLinker.linkerDeps(ctx, deps)
|
deps = binary.baseLinker.linkerDeps(ctx, deps)
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
if !Bool(binary.baseLinker.Properties.Nocrt) {
|
if !Bool(binary.baseLinker.Properties.Nocrt) {
|
||||||
if !ctx.sdk() {
|
if !ctx.sdk() {
|
||||||
if binary.buildStatic() {
|
if binary.static() {
|
||||||
deps.CrtBegin = "crtbegin_static"
|
deps.CrtBegin = "crtbegin_static"
|
||||||
} else {
|
} else {
|
||||||
deps.CrtBegin = "crtbegin_dynamic"
|
deps.CrtBegin = "crtbegin_dynamic"
|
||||||
}
|
}
|
||||||
deps.CrtEnd = "crtend_android"
|
deps.CrtEnd = "crtend_android"
|
||||||
} else {
|
} else {
|
||||||
if binary.buildStatic() {
|
if binary.static() {
|
||||||
deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
|
deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
|
||||||
} else {
|
} else {
|
||||||
if Bool(binary.Properties.Static_executable) {
|
if binary.static() {
|
||||||
deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
|
deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion()
|
||||||
} else {
|
} else {
|
||||||
deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
|
deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion()
|
||||||
@@ -116,7 +109,7 @@ func (binary *binaryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary.buildStatic() {
|
if binary.static() {
|
||||||
if inList("libc++_static", deps.StaticLibs) {
|
if inList("libc++_static", deps.StaticLibs) {
|
||||||
deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
|
deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl")
|
||||||
}
|
}
|
||||||
@@ -130,55 +123,55 @@ func (binary *binaryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary.buildShared() && inList("libc", deps.StaticLibs) {
|
if !binary.static() && inList("libc", deps.StaticLibs) {
|
||||||
ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
|
ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
|
||||||
"from static libs or set static_executable: true")
|
"from static libs or set static_executable: true")
|
||||||
}
|
}
|
||||||
return deps
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*binaryLinker) installable() bool {
|
func (binary *binaryDecorator) isDependencyRoot() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) isDependencyRoot() bool {
|
func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBinary(hod android.HostOrDeviceSupported) *Module {
|
|
||||||
module := newModule(hod, android.MultilibFirst)
|
module := newModule(hod, android.MultilibFirst)
|
||||||
module.compiler = &baseCompiler{}
|
binary := &binaryDecorator{
|
||||||
module.linker = &binaryLinker{}
|
baseLinker: NewBaseLinker(),
|
||||||
module.installer = &baseInstaller{
|
|
||||||
dir: "bin",
|
|
||||||
}
|
}
|
||||||
return module
|
module.compiler = NewBaseCompiler()
|
||||||
|
module.linker = binary
|
||||||
|
module.installer = NewBaseInstaller("bin", "", InstallInSystem)
|
||||||
|
return module, binary
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) linkerInit(ctx BaseModuleContext) {
|
func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) {
|
||||||
binary.baseLinker.linkerInit(ctx)
|
binary.baseLinker.linkerInit(ctx)
|
||||||
|
|
||||||
static := Bool(binary.Properties.Static_executable)
|
|
||||||
if ctx.Host() {
|
if ctx.Host() {
|
||||||
if ctx.Os() == android.Linux {
|
if ctx.Os() == android.Linux {
|
||||||
if binary.Properties.Static_executable == nil && Bool(ctx.AConfig().ProductVariables.HostStaticBinaries) {
|
if binary.Properties.Static_executable == nil && Bool(ctx.AConfig().ProductVariables.HostStaticBinaries) {
|
||||||
static = true
|
binary.Properties.Static_executable = proptools.BoolPtr(true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Static executables are not supported on Darwin or Windows
|
// Static executables are not supported on Darwin or Windows
|
||||||
static = false
|
binary.Properties.Static_executable = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if static {
|
|
||||||
binary.dynamicProperties.VariantIsStatic = true
|
|
||||||
binary.dynamicProperties.VariantIsStaticBinary = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
func (binary *binaryDecorator) static() bool {
|
||||||
|
return Bool(binary.Properties.Static_executable)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (binary *binaryDecorator) staticBinary() bool {
|
||||||
|
return binary.static()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
flags = binary.baseLinker.linkerFlags(ctx, flags)
|
flags = binary.baseLinker.linkerFlags(ctx, flags)
|
||||||
|
|
||||||
if ctx.Host() && !binary.staticBinary() {
|
if ctx.Host() && !binary.static() {
|
||||||
flags.LdFlags = append(flags.LdFlags, "-pie")
|
flags.LdFlags = append(flags.LdFlags, "-pie")
|
||||||
if ctx.Os() == android.Windows {
|
if ctx.Os() == android.Windows {
|
||||||
flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
|
flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
|
||||||
@@ -193,7 +186,7 @@ func (binary *binaryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
if binary.buildStatic() {
|
if binary.static() {
|
||||||
// Clang driver needs -static to create static executable.
|
// Clang driver needs -static to create static executable.
|
||||||
// However, bionic/linker uses -shared to overwrite.
|
// However, bionic/linker uses -shared to overwrite.
|
||||||
// Linker for x86 targets does not allow coexistance of -static and -shared,
|
// Linker for x86 targets does not allow coexistance of -static and -shared,
|
||||||
@@ -225,7 +218,7 @@ func (binary *binaryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if binary.staticBinary() {
|
if binary.static() {
|
||||||
flags.LdFlags = append(flags.LdFlags, "-static")
|
flags.LdFlags = append(flags.LdFlags, "-static")
|
||||||
}
|
}
|
||||||
if ctx.Darwin() {
|
if ctx.Darwin() {
|
||||||
@@ -236,7 +229,7 @@ func (binary *binaryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) link(ctx ModuleContext,
|
func (binary *binaryDecorator) link(ctx ModuleContext,
|
||||||
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
||||||
|
|
||||||
fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
|
fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
|
||||||
@@ -277,6 +270,6 @@ func (binary *binaryLinker) link(ctx ModuleContext,
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryLinker) HostToolPath() android.OptionalPath {
|
func (binary *binaryDecorator) HostToolPath() android.OptionalPath {
|
||||||
return binary.hostToolPath
|
return binary.hostToolPath
|
||||||
}
|
}
|
||||||
|
110
cc/cc.go
110
cc/cc.go
@@ -35,8 +35,6 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
soong.RegisterModuleType("cc_defaults", defaultsFactory)
|
soong.RegisterModuleType("cc_defaults", defaultsFactory)
|
||||||
|
|
||||||
soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
|
|
||||||
|
|
||||||
// LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
|
// 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
|
// the Go initialization order because this package depends on common, so common's init
|
||||||
// functions will run first.
|
// functions will run first.
|
||||||
@@ -189,7 +187,6 @@ type linker interface {
|
|||||||
|
|
||||||
link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles android.Paths) android.Path
|
link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles android.Paths) android.Path
|
||||||
appendLdflags([]string)
|
appendLdflags([]string)
|
||||||
installable() bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type installer interface {
|
type installer interface {
|
||||||
@@ -252,6 +249,8 @@ type Module struct {
|
|||||||
outputFile android.OptionalPath
|
outputFile android.OptionalPath
|
||||||
|
|
||||||
cachedToolchain config.Toolchain
|
cachedToolchain config.Toolchain
|
||||||
|
|
||||||
|
subAndroidMkOnce map[subAndroidMkProvider]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) Init() (blueprint.Module, []interface{}) {
|
func (c *Module) Init() (blueprint.Module, []interface{}) {
|
||||||
@@ -283,6 +282,17 @@ func (c *Module) Init() (blueprint.Module, []interface{}) {
|
|||||||
return android.InitDefaultableModule(c, c, props...)
|
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 {
|
type baseModuleContext struct {
|
||||||
android.BaseContext
|
android.BaseContext
|
||||||
moduleContextImpl
|
moduleContextImpl
|
||||||
@@ -322,25 +332,21 @@ func (ctx *moduleContextImpl) toolchain() config.Toolchain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *moduleContextImpl) static() bool {
|
func (ctx *moduleContextImpl) static() bool {
|
||||||
if ctx.mod.linker == nil {
|
if static, ok := ctx.mod.linker.(interface {
|
||||||
panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName()))
|
static() bool
|
||||||
}
|
}); ok {
|
||||||
if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
|
return static.static()
|
||||||
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 {
|
func (ctx *moduleContextImpl) staticBinary() bool {
|
||||||
if ctx.mod.linker == nil {
|
if static, ok := ctx.mod.linker.(interface {
|
||||||
panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName()))
|
staticBinary() bool
|
||||||
}
|
}); ok {
|
||||||
if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok {
|
return static.staticBinary()
|
||||||
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 {
|
func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool {
|
||||||
@@ -453,7 +459,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
c.outputFile = android.OptionalPathForPath(outputFile)
|
c.outputFile = android.OptionalPathForPath(outputFile)
|
||||||
|
|
||||||
if c.installer != nil && c.linker.installable() {
|
if c.installer != nil {
|
||||||
c.installer.install(ctx, outputFile)
|
c.installer.install(ctx, outputFile)
|
||||||
if ctx.Failed() {
|
if ctx.Failed() {
|
||||||
return
|
return
|
||||||
@@ -680,7 +686,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
// Platform code can link to anything
|
// Platform code can link to anything
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, ok := to.linker.(*toolchainLibraryLinker); ok {
|
if _, ok := to.linker.(*toolchainLibraryDecorator); ok {
|
||||||
// These are always allowed
|
// These are always allowed
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -692,7 +698,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
// These are allowed, but don't set sdk_version
|
// These are allowed, but don't set sdk_version
|
||||||
return
|
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
|
// These aren't real libraries, but are the stub shared libraries that are included in
|
||||||
// the NDK.
|
// the NDK.
|
||||||
return
|
return
|
||||||
@@ -794,7 +800,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
|
|
||||||
if tag == reuseObjTag {
|
if tag == reuseObjTag {
|
||||||
depPaths.ObjFiles = append(depPaths.ObjFiles,
|
depPaths.ObjFiles = append(depPaths.ObjFiles,
|
||||||
cc.compiler.(*libraryCompiler).reuseObjFiles...)
|
cc.compiler.(libraryInterface).reuseObjs()...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,8 +830,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
depPtr = &depPaths.LateStaticLibs
|
depPtr = &depPaths.LateStaticLibs
|
||||||
case wholeStaticDepTag:
|
case wholeStaticDepTag:
|
||||||
depPtr = &depPaths.WholeStaticLibs
|
depPtr = &depPaths.WholeStaticLibs
|
||||||
staticLib, _ := cc.linker.(libraryInterface)
|
staticLib, ok := cc.linker.(libraryInterface)
|
||||||
if staticLib == nil || !staticLib.static() {
|
if !ok || !staticLib.static() {
|
||||||
ctx.ModuleErrorf("module %q not a static library", name)
|
ctx.ModuleErrorf("module %q not a static library", name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -882,11 +888,11 @@ func defaultsFactory() (blueprint.Module, []interface{}) {
|
|||||||
&BaseProperties{},
|
&BaseProperties{},
|
||||||
&BaseCompilerProperties{},
|
&BaseCompilerProperties{},
|
||||||
&BaseLinkerProperties{},
|
&BaseLinkerProperties{},
|
||||||
&LibraryCompilerProperties{},
|
&LibraryProperties{},
|
||||||
&FlagExporterProperties{},
|
&FlagExporterProperties{},
|
||||||
&LibraryLinkerProperties{},
|
|
||||||
&BinaryLinkerProperties{},
|
&BinaryLinkerProperties{},
|
||||||
&TestLinkerProperties{},
|
&TestProperties{},
|
||||||
|
&TestBinaryProperties{},
|
||||||
&UnusedProperties{},
|
&UnusedProperties{},
|
||||||
&StlProperties{},
|
&StlProperties{},
|
||||||
&SanitizeProperties{},
|
&SanitizeProperties{},
|
||||||
@@ -899,58 +905,6 @@ func defaultsFactory() (blueprint.Module, []interface{}) {
|
|||||||
return android.InitDefaultsModule(module, module, propertyStructs...)
|
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
|
// 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
|
// modifies the slice contents in place, and returns a subslice of the original slice
|
||||||
func lastUniqueElements(list []string) []string {
|
func lastUniqueElements(list []string) []string {
|
||||||
|
@@ -89,6 +89,10 @@ type BaseCompilerProperties struct {
|
|||||||
} `android:"arch_variant"`
|
} `android:"arch_variant"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewBaseCompiler() *baseCompiler {
|
||||||
|
return &baseCompiler{}
|
||||||
|
}
|
||||||
|
|
||||||
type baseCompiler struct {
|
type baseCompiler struct {
|
||||||
Properties BaseCompilerProperties
|
Properties BaseCompilerProperties
|
||||||
}
|
}
|
||||||
@@ -311,7 +315,7 @@ func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathD
|
|||||||
pathDeps := deps.GeneratedHeaders
|
pathDeps := deps.GeneratedHeaders
|
||||||
pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
|
pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
|
||||||
// Compile files listed in c.Properties.Srcs into objects
|
// Compile files listed in c.Properties.Srcs into objects
|
||||||
objFiles := compiler.compileObjs(ctx, flags, "",
|
objFiles := compileObjs(ctx, flags, "",
|
||||||
compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
|
compiler.Properties.Srcs, compiler.Properties.Exclude_srcs,
|
||||||
deps.GeneratedSources, pathDeps)
|
deps.GeneratedSources, pathDeps)
|
||||||
|
|
||||||
@@ -323,7 +327,7 @@ func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathD
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compile a list of source files into objects a specified subdirectory
|
// Compile a list of source files into objects a specified subdirectory
|
||||||
func (compiler *baseCompiler) compileObjs(ctx android.ModuleContext, flags Flags,
|
func compileObjs(ctx android.ModuleContext, flags Flags,
|
||||||
subdir string, srcFiles, excludes []string, extraSrcs, deps android.Paths) android.Paths {
|
subdir string, srcFiles, excludes []string, extraSrcs, deps android.Paths) android.Paths {
|
||||||
|
|
||||||
buildFlags := flagsToBuilderFlags(flags)
|
buildFlags := flagsToBuilderFlags(flags)
|
||||||
|
@@ -30,12 +30,27 @@ type InstallerProperties struct {
|
|||||||
Symlinks []string `android:"arch_variant"`
|
Symlinks []string `android:"arch_variant"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type installLocation int
|
||||||
|
|
||||||
|
const (
|
||||||
|
InstallInSystem installLocation = 0
|
||||||
|
InstallInData = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewBaseInstaller(dir, dir64 string, location installLocation) *baseInstaller {
|
||||||
|
return &baseInstaller{
|
||||||
|
dir: dir,
|
||||||
|
dir64: dir64,
|
||||||
|
location: location,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type baseInstaller struct {
|
type baseInstaller struct {
|
||||||
Properties InstallerProperties
|
Properties InstallerProperties
|
||||||
|
|
||||||
dir string
|
dir string
|
||||||
dir64 string
|
dir64 string
|
||||||
data bool
|
location installLocation
|
||||||
|
|
||||||
path android.OutputPath
|
path android.OutputPath
|
||||||
}
|
}
|
||||||
@@ -62,5 +77,5 @@ func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (installer *baseInstaller) inData() bool {
|
func (installer *baseInstaller) inData() bool {
|
||||||
return installer.data
|
return installer.location == InstallInData
|
||||||
}
|
}
|
||||||
|
337
cc/library.go
337
cc/library.go
@@ -23,33 +23,22 @@ import (
|
|||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LibraryCompilerProperties struct {
|
type LibraryProperties struct {
|
||||||
Static struct {
|
Static struct {
|
||||||
Srcs []string `android:"arch_variant"`
|
Srcs []string `android:"arch_variant"`
|
||||||
Exclude_srcs []string `android:"arch_variant"`
|
Exclude_srcs []string `android:"arch_variant"`
|
||||||
Cflags []string `android:"arch_variant"`
|
Cflags []string `android:"arch_variant"`
|
||||||
} `android:"arch_variant"`
|
|
||||||
Shared struct {
|
|
||||||
Srcs []string `android:"arch_variant"`
|
|
||||||
Exclude_srcs []string `android:"arch_variant"`
|
|
||||||
Cflags []string `android:"arch_variant"`
|
|
||||||
} `android:"arch_variant"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type FlagExporterProperties struct {
|
|
||||||
// list of directories relative to the Blueprints file that will
|
|
||||||
// be added to the include path using -I for any module that links against this module
|
|
||||||
Export_include_dirs []string `android:"arch_variant"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type LibraryLinkerProperties struct {
|
|
||||||
Static struct {
|
|
||||||
Enabled *bool `android:"arch_variant"`
|
Enabled *bool `android:"arch_variant"`
|
||||||
Whole_static_libs []string `android:"arch_variant"`
|
Whole_static_libs []string `android:"arch_variant"`
|
||||||
Static_libs []string `android:"arch_variant"`
|
Static_libs []string `android:"arch_variant"`
|
||||||
Shared_libs []string `android:"arch_variant"`
|
Shared_libs []string `android:"arch_variant"`
|
||||||
} `android:"arch_variant"`
|
} `android:"arch_variant"`
|
||||||
Shared struct {
|
Shared struct {
|
||||||
|
Srcs []string `android:"arch_variant"`
|
||||||
|
Exclude_srcs []string `android:"arch_variant"`
|
||||||
|
Cflags []string `android:"arch_variant"`
|
||||||
|
|
||||||
Enabled *bool `android:"arch_variant"`
|
Enabled *bool `android:"arch_variant"`
|
||||||
Whole_static_libs []string `android:"arch_variant"`
|
Whole_static_libs []string `android:"arch_variant"`
|
||||||
Static_libs []string `android:"arch_variant"`
|
Static_libs []string `android:"arch_variant"`
|
||||||
@@ -69,6 +58,21 @@ type LibraryLinkerProperties struct {
|
|||||||
Unique_host_soname *bool
|
Unique_host_soname *bool
|
||||||
|
|
||||||
VariantName string `blueprint:"mutated"`
|
VariantName string `blueprint:"mutated"`
|
||||||
|
|
||||||
|
// Build a static variant
|
||||||
|
BuildStatic bool `blueprint:"mutated"`
|
||||||
|
// Build a shared variant
|
||||||
|
BuildShared bool `blueprint:"mutated"`
|
||||||
|
// This variant is shared
|
||||||
|
VariantIsShared bool `blueprint:"mutated"`
|
||||||
|
// This variant is static
|
||||||
|
VariantIsStatic bool `blueprint:"mutated"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FlagExporterProperties struct {
|
||||||
|
// list of directories relative to the Blueprints file that will
|
||||||
|
// be added to the include path using -I for any module that links against this module
|
||||||
|
Export_include_dirs []string `android:"arch_variant"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -82,31 +86,31 @@ func init() {
|
|||||||
// Module factory for combined static + shared libraries, device by default but with possible host
|
// Module factory for combined static + shared libraries, device by default but with possible host
|
||||||
// support
|
// support
|
||||||
func libraryFactory() (blueprint.Module, []interface{}) {
|
func libraryFactory() (blueprint.Module, []interface{}) {
|
||||||
module := NewLibrary(android.HostAndDeviceSupported, true, true)
|
module, _ := NewLibrary(android.HostAndDeviceSupported, true, true)
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module factory for static libraries
|
// Module factory for static libraries
|
||||||
func libraryStaticFactory() (blueprint.Module, []interface{}) {
|
func libraryStaticFactory() (blueprint.Module, []interface{}) {
|
||||||
module := NewLibrary(android.HostAndDeviceSupported, false, true)
|
module, _ := NewLibrary(android.HostAndDeviceSupported, false, true)
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module factory for shared libraries
|
// Module factory for shared libraries
|
||||||
func librarySharedFactory() (blueprint.Module, []interface{}) {
|
func librarySharedFactory() (blueprint.Module, []interface{}) {
|
||||||
module := NewLibrary(android.HostAndDeviceSupported, true, false)
|
module, _ := NewLibrary(android.HostAndDeviceSupported, true, false)
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module factory for host static libraries
|
// Module factory for host static libraries
|
||||||
func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
|
func libraryHostStaticFactory() (blueprint.Module, []interface{}) {
|
||||||
module := NewLibrary(android.HostSupported, false, true)
|
module, _ := NewLibrary(android.HostSupported, false, true)
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module factory for host shared libraries
|
// Module factory for host shared libraries
|
||||||
func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
|
func libraryHostSharedFactory() (blueprint.Module, []interface{}) {
|
||||||
module := NewLibrary(android.HostSupported, true, false)
|
module, _ := NewLibrary(android.HostSupported, true, false)
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,76 +141,17 @@ type exportedFlagsProducer interface {
|
|||||||
|
|
||||||
var _ exportedFlagsProducer = (*flagExporter)(nil)
|
var _ exportedFlagsProducer = (*flagExporter)(nil)
|
||||||
|
|
||||||
type libraryCompiler struct {
|
// libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific
|
||||||
baseCompiler
|
// functionality: static vs. shared linkage, reusing object files for shared libraries
|
||||||
|
type libraryDecorator struct {
|
||||||
linker *libraryLinker
|
Properties LibraryProperties
|
||||||
Properties LibraryCompilerProperties
|
|
||||||
|
|
||||||
// For reusing static library objects for shared library
|
// For reusing static library objects for shared library
|
||||||
reuseObjFiles android.Paths
|
reuseObjFiles android.Paths
|
||||||
}
|
|
||||||
|
|
||||||
var _ compiler = (*libraryCompiler)(nil)
|
|
||||||
|
|
||||||
func (library *libraryCompiler) compilerProps() []interface{} {
|
|
||||||
props := library.baseCompiler.compilerProps()
|
|
||||||
return append(props, &library.Properties)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (library *libraryCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
|
||||||
flags = library.baseCompiler.compilerFlags(ctx, flags)
|
|
||||||
|
|
||||||
// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
|
|
||||||
// all code is position independent, and then those warnings get promoted to
|
|
||||||
// errors.
|
|
||||||
if ctx.Os() != android.Windows {
|
|
||||||
flags.CFlags = append(flags.CFlags, "-fPIC")
|
|
||||||
}
|
|
||||||
|
|
||||||
if library.linker.static() {
|
|
||||||
flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
|
|
||||||
} else {
|
|
||||||
flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags
|
|
||||||
}
|
|
||||||
|
|
||||||
func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
|
|
||||||
var objFiles android.Paths
|
|
||||||
|
|
||||||
objFiles = library.baseCompiler.compile(ctx, flags, deps)
|
|
||||||
library.reuseObjFiles = objFiles
|
|
||||||
|
|
||||||
pathDeps := deps.GeneratedHeaders
|
|
||||||
pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
|
|
||||||
|
|
||||||
if library.linker.static() {
|
|
||||||
objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceStaticLibrary,
|
|
||||||
library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
|
|
||||||
nil, pathDeps)...)
|
|
||||||
} else {
|
|
||||||
objFiles = append(objFiles, library.compileObjs(ctx, flags, android.DeviceSharedLibrary,
|
|
||||||
library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
|
|
||||||
nil, pathDeps)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return objFiles
|
|
||||||
}
|
|
||||||
|
|
||||||
type libraryLinker struct {
|
|
||||||
baseLinker
|
|
||||||
flagExporter
|
flagExporter
|
||||||
stripper
|
stripper
|
||||||
|
|
||||||
Properties LibraryLinkerProperties
|
|
||||||
|
|
||||||
dynamicProperties struct {
|
|
||||||
BuildStatic bool `blueprint:"mutated"`
|
|
||||||
BuildShared bool `blueprint:"mutated"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're used as a whole_static_lib, our missing dependencies need
|
// If we're used as a whole_static_lib, our missing dependencies need
|
||||||
// to be given
|
// to be given
|
||||||
wholeStaticMissingDeps []string
|
wholeStaticMissingDeps []string
|
||||||
@@ -217,43 +162,40 @@ type libraryLinker struct {
|
|||||||
// Uses the module's name if empty, but can be overridden. Does not include
|
// Uses the module's name if empty, but can be overridden. Does not include
|
||||||
// shlib suffix.
|
// shlib suffix.
|
||||||
libName string
|
libName string
|
||||||
|
|
||||||
|
sanitize *sanitize
|
||||||
|
|
||||||
|
// Decorated interafaces
|
||||||
|
*baseCompiler
|
||||||
|
*baseLinker
|
||||||
|
*baseInstaller
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ linker = (*libraryLinker)(nil)
|
func (library *libraryDecorator) linkerProps() []interface{} {
|
||||||
|
var props []interface{}
|
||||||
type libraryInterface interface {
|
props = append(props, library.baseLinker.linkerProps()...)
|
||||||
getWholeStaticMissingDeps() []string
|
|
||||||
static() bool
|
|
||||||
objs() android.Paths
|
|
||||||
}
|
|
||||||
|
|
||||||
func (library *libraryLinker) linkerProps() []interface{} {
|
|
||||||
props := library.baseLinker.linkerProps()
|
|
||||||
return append(props,
|
return append(props,
|
||||||
&library.Properties,
|
&library.Properties,
|
||||||
&library.dynamicProperties,
|
|
||||||
&library.flagExporter.Properties,
|
&library.flagExporter.Properties,
|
||||||
&library.stripper.StripProperties)
|
&library.stripper.StripProperties)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) getLibName(ctx ModuleContext) string {
|
func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
name := library.libName
|
|
||||||
if name == "" {
|
|
||||||
name = ctx.ModuleName()
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
|
|
||||||
if !strings.HasSuffix(name, "-host") {
|
|
||||||
name = name + "-host"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return name + library.Properties.VariantName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (library *libraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|
||||||
flags = library.baseLinker.linkerFlags(ctx, flags)
|
flags = library.baseLinker.linkerFlags(ctx, flags)
|
||||||
|
|
||||||
|
// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
|
||||||
|
// all code is position independent, and then those warnings get promoted to
|
||||||
|
// errors.
|
||||||
|
if ctx.Os() != android.Windows {
|
||||||
|
flags.CFlags = append(flags.CFlags, "-fPIC")
|
||||||
|
}
|
||||||
|
|
||||||
|
if library.static() {
|
||||||
|
flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
|
||||||
|
} else {
|
||||||
|
flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
|
||||||
|
}
|
||||||
|
|
||||||
if !library.static() {
|
if !library.static() {
|
||||||
libName := library.getLibName(ctx)
|
libName := library.getLibName(ctx)
|
||||||
// GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
|
// GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
|
||||||
@@ -288,10 +230,73 @@ func (library *libraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags
|
|||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
|
||||||
deps = library.baseLinker.linkerDeps(ctx, deps)
|
var objFiles android.Paths
|
||||||
|
|
||||||
|
objFiles = library.baseCompiler.compile(ctx, flags, deps)
|
||||||
|
library.reuseObjFiles = objFiles
|
||||||
|
|
||||||
|
pathDeps := deps.GeneratedHeaders
|
||||||
|
pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
|
||||||
|
|
||||||
if library.static() {
|
if library.static() {
|
||||||
deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...)
|
objFiles = append(objFiles, compileObjs(ctx, flags, android.DeviceStaticLibrary,
|
||||||
|
library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs,
|
||||||
|
nil, pathDeps)...)
|
||||||
|
} else {
|
||||||
|
objFiles = append(objFiles, compileObjs(ctx, flags, android.DeviceSharedLibrary,
|
||||||
|
library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs,
|
||||||
|
nil, pathDeps)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return objFiles
|
||||||
|
}
|
||||||
|
|
||||||
|
type libraryInterface interface {
|
||||||
|
getWholeStaticMissingDeps() []string
|
||||||
|
static() bool
|
||||||
|
objs() android.Paths
|
||||||
|
reuseObjs() android.Paths
|
||||||
|
|
||||||
|
// Returns true if the build options for the module have selected a static or shared build
|
||||||
|
buildStatic() bool
|
||||||
|
buildShared() bool
|
||||||
|
|
||||||
|
// Sets whether a specific variant is static or shared
|
||||||
|
setStatic(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (library *libraryDecorator) getLibName(ctx ModuleContext) string {
|
||||||
|
name := library.libName
|
||||||
|
if name == "" {
|
||||||
|
name = ctx.ModuleName()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
|
||||||
|
if !strings.HasSuffix(name, "-host") {
|
||||||
|
name = name + "-host"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name + library.Properties.VariantName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
|
||||||
|
location := InstallInSystem
|
||||||
|
if library.sanitize.inData() {
|
||||||
|
location = InstallInData
|
||||||
|
}
|
||||||
|
library.baseInstaller.location = location
|
||||||
|
|
||||||
|
library.baseLinker.linkerInit(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (library *libraryDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
|
deps = library.baseLinker.linkerDeps(ctx, deps)
|
||||||
|
|
||||||
|
if library.static() {
|
||||||
|
deps.WholeStaticLibs = append(deps.WholeStaticLibs,
|
||||||
|
library.Properties.Static.Whole_static_libs...)
|
||||||
deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
|
deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
|
||||||
deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
|
deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
|
||||||
} else {
|
} else {
|
||||||
@@ -312,7 +317,7 @@ func (library *libraryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps
|
|||||||
return deps
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) linkStatic(ctx ModuleContext,
|
func (library *libraryDecorator) linkStatic(ctx ModuleContext,
|
||||||
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
||||||
|
|
||||||
library.objFiles = append(android.Paths{}, deps.WholeStaticLibObjFiles...)
|
library.objFiles = append(android.Paths{}, deps.WholeStaticLibObjFiles...)
|
||||||
@@ -334,7 +339,7 @@ func (library *libraryLinker) linkStatic(ctx ModuleContext,
|
|||||||
return outputFile
|
return outputFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) linkShared(ctx ModuleContext,
|
func (library *libraryDecorator) linkShared(ctx ModuleContext,
|
||||||
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
||||||
|
|
||||||
var linkerDeps android.Paths
|
var linkerDeps android.Paths
|
||||||
@@ -397,7 +402,7 @@ func (library *libraryLinker) linkShared(ctx ModuleContext,
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) link(ctx ModuleContext,
|
func (library *libraryDecorator) link(ctx ModuleContext,
|
||||||
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
||||||
|
|
||||||
objFiles = append(objFiles, deps.ObjFiles...)
|
objFiles = append(objFiles, deps.ObjFiles...)
|
||||||
@@ -415,64 +420,92 @@ func (library *libraryLinker) link(ctx ModuleContext,
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) buildStatic() bool {
|
func (library *libraryDecorator) buildStatic() bool {
|
||||||
return library.dynamicProperties.BuildStatic &&
|
return library.Properties.BuildStatic &&
|
||||||
(library.Properties.Static.Enabled == nil || *library.Properties.Static.Enabled)
|
(library.Properties.Static.Enabled == nil || *library.Properties.Static.Enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) buildShared() bool {
|
func (library *libraryDecorator) buildShared() bool {
|
||||||
return library.dynamicProperties.BuildShared &&
|
return library.Properties.BuildShared &&
|
||||||
(library.Properties.Shared.Enabled == nil || *library.Properties.Shared.Enabled)
|
(library.Properties.Shared.Enabled == nil || *library.Properties.Shared.Enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) getWholeStaticMissingDeps() []string {
|
func (library *libraryDecorator) getWholeStaticMissingDeps() []string {
|
||||||
return library.wholeStaticMissingDeps
|
return library.wholeStaticMissingDeps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryLinker) installable() bool {
|
func (library *libraryDecorator) objs() android.Paths {
|
||||||
return !library.static()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (library *libraryLinker) objs() android.Paths {
|
|
||||||
return library.objFiles
|
return library.objFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
type libraryInstaller struct {
|
func (library *libraryDecorator) reuseObjs() android.Paths {
|
||||||
baseInstaller
|
return library.reuseObjFiles
|
||||||
|
|
||||||
linker *libraryLinker
|
|
||||||
sanitize *sanitize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryInstaller) install(ctx ModuleContext, file android.Path) {
|
func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
|
||||||
if !library.linker.static() {
|
if !ctx.static() {
|
||||||
library.baseInstaller.install(ctx, file)
|
library.baseInstaller.install(ctx, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryInstaller) inData() bool {
|
func (library *libraryDecorator) static() bool {
|
||||||
return library.baseInstaller.inData() || library.sanitize.inData()
|
return library.Properties.VariantIsStatic
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLibrary(hod android.HostOrDeviceSupported, shared, static bool) *Module {
|
func (library *libraryDecorator) setStatic(static bool) {
|
||||||
|
library.Properties.VariantIsStatic = static
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLibrary(hod android.HostOrDeviceSupported, shared, static bool) (*Module, *libraryDecorator) {
|
||||||
module := newModule(hod, android.MultilibBoth)
|
module := newModule(hod, android.MultilibBoth)
|
||||||
|
|
||||||
linker := &libraryLinker{}
|
library := &libraryDecorator{
|
||||||
linker.dynamicProperties.BuildShared = shared
|
Properties: LibraryProperties{
|
||||||
linker.dynamicProperties.BuildStatic = static
|
BuildShared: shared,
|
||||||
module.linker = linker
|
BuildStatic: static,
|
||||||
|
|
||||||
module.compiler = &libraryCompiler{
|
|
||||||
linker: linker,
|
|
||||||
}
|
|
||||||
module.installer = &libraryInstaller{
|
|
||||||
baseInstaller: baseInstaller{
|
|
||||||
dir: "lib",
|
|
||||||
dir64: "lib64",
|
|
||||||
},
|
},
|
||||||
linker: linker,
|
baseCompiler: NewBaseCompiler(),
|
||||||
sanitize: module.sanitize,
|
baseLinker: NewBaseLinker(),
|
||||||
|
baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem),
|
||||||
|
sanitize: module.sanitize,
|
||||||
}
|
}
|
||||||
|
|
||||||
return module
|
module.compiler = library
|
||||||
|
module.linker = library
|
||||||
|
module.installer = library
|
||||||
|
|
||||||
|
return module, library
|
||||||
|
}
|
||||||
|
|
||||||
|
func linkageMutator(mctx android.BottomUpMutatorContext) {
|
||||||
|
if m, ok := mctx.Module().(*Module); ok && m.linker != nil {
|
||||||
|
if library, ok := m.linker.(libraryInterface); ok {
|
||||||
|
var modules []blueprint.Module
|
||||||
|
if library.buildStatic() && library.buildShared() {
|
||||||
|
modules = mctx.CreateLocalVariations("static", "shared")
|
||||||
|
static := modules[0].(*Module)
|
||||||
|
shared := modules[1].(*Module)
|
||||||
|
|
||||||
|
static.linker.(libraryInterface).setStatic(true)
|
||||||
|
shared.linker.(libraryInterface).setStatic(false)
|
||||||
|
|
||||||
|
if staticCompiler, ok := static.compiler.(*libraryDecorator); ok {
|
||||||
|
sharedCompiler := shared.compiler.(*libraryDecorator)
|
||||||
|
if len(staticCompiler.Properties.Static.Cflags) == 0 &&
|
||||||
|
len(sharedCompiler.Properties.Shared.Cflags) == 0 {
|
||||||
|
// Optimize out compiling common .o files twice for static+shared libraries
|
||||||
|
mctx.AddInterVariantDependency(reuseObjTag, shared, static)
|
||||||
|
sharedCompiler.baseCompiler.Properties.Srcs = nil
|
||||||
|
sharedCompiler.baseCompiler.Properties.Generated_sources = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if library.buildStatic() {
|
||||||
|
modules = mctx.CreateLocalVariations("static")
|
||||||
|
modules[0].(*Module).linker.(libraryInterface).setStatic(true)
|
||||||
|
} else if library.buildShared() {
|
||||||
|
modules = mctx.CreateLocalVariations("shared")
|
||||||
|
modules[0].(*Module).linker.(libraryInterface).setStatic(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
58
cc/linker.go
58
cc/linker.go
@@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
package cc
|
package cc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"android/soong/android"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
// This file contains the basic functionality for linking against static libraries and shared
|
// This file contains the basic functionality for linking against static libraries and shared
|
||||||
// libraries. Final linking into libraries or executables is handled in library.go, binary.go, etc.
|
// libraries. Final linking into libraries or executables is handled in library.go, binary.go, etc.
|
||||||
|
|
||||||
@@ -67,14 +72,15 @@ type BaseLinkerProperties struct {
|
|||||||
Nocrt *bool `android:"arch_variant"`
|
Nocrt *bool `android:"arch_variant"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewBaseLinker() *baseLinker {
|
||||||
|
return &baseLinker{}
|
||||||
|
}
|
||||||
|
|
||||||
// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
|
// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
|
||||||
type baseLinker struct {
|
type baseLinker struct {
|
||||||
Properties BaseLinkerProperties
|
Properties BaseLinkerProperties
|
||||||
dynamicProperties struct {
|
dynamicProperties struct {
|
||||||
VariantIsShared bool `blueprint:"mutated"`
|
RunPaths []string `blueprint:"mutated"`
|
||||||
VariantIsStatic bool `blueprint:"mutated"`
|
|
||||||
VariantIsStaticBinary bool `blueprint:"mutated"`
|
|
||||||
RunPaths []string `blueprint:"mutated"`
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,9 +90,9 @@ func (linker *baseLinker) appendLdflags(flags []string) {
|
|||||||
|
|
||||||
func (linker *baseLinker) linkerInit(ctx BaseModuleContext) {
|
func (linker *baseLinker) linkerInit(ctx BaseModuleContext) {
|
||||||
if ctx.toolchain().Is64Bit() {
|
if ctx.toolchain().Is64Bit() {
|
||||||
linker.dynamicProperties.RunPaths = []string{"../lib64", "lib64"}
|
linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib64", "lib64")
|
||||||
} else {
|
} else {
|
||||||
linker.dynamicProperties.RunPaths = []string{"../lib", "lib"}
|
linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib", "lib")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +119,7 @@ func (linker *baseLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||||||
deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
|
deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !linker.static() {
|
if !ctx.static() {
|
||||||
if linker.Properties.System_shared_libs != nil {
|
if linker.Properties.System_shared_libs != nil {
|
||||||
deps.LateSharedLibs = append(deps.LateSharedLibs,
|
deps.LateSharedLibs = append(deps.LateSharedLibs,
|
||||||
linker.Properties.System_shared_libs...)
|
linker.Properties.System_shared_libs...)
|
||||||
@@ -158,7 +164,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
|
|
||||||
flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
|
flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...)
|
||||||
|
|
||||||
if ctx.Host() && !linker.static() {
|
if ctx.Host() {
|
||||||
rpath_prefix := `\$$ORIGIN/`
|
rpath_prefix := `\$$ORIGIN/`
|
||||||
if ctx.Darwin() {
|
if ctx.Darwin() {
|
||||||
rpath_prefix = "@loader_path/"
|
rpath_prefix = "@loader_path/"
|
||||||
@@ -178,37 +184,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (linker *baseLinker) static() bool {
|
func (linker *baseLinker) link(ctx ModuleContext,
|
||||||
return linker.dynamicProperties.VariantIsStatic
|
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
||||||
}
|
panic(fmt.Errorf("baseLinker doesn't know how to link"))
|
||||||
|
|
||||||
func (linker *baseLinker) staticBinary() bool {
|
|
||||||
return linker.dynamicProperties.VariantIsStaticBinary
|
|
||||||
}
|
|
||||||
|
|
||||||
func (linker *baseLinker) setStatic(static bool) {
|
|
||||||
linker.dynamicProperties.VariantIsStatic = static
|
|
||||||
}
|
|
||||||
|
|
||||||
func (linker *baseLinker) isDependencyRoot() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type baseLinkerInterface interface {
|
|
||||||
// Returns true if the build options for the module have selected a static or shared build
|
|
||||||
buildStatic() bool
|
|
||||||
buildShared() bool
|
|
||||||
|
|
||||||
// Sets whether a specific variant is static or shared
|
|
||||||
setStatic(bool)
|
|
||||||
|
|
||||||
// Returns whether a specific variant is a static library or binary
|
|
||||||
static() bool
|
|
||||||
|
|
||||||
// Returns whether a module is a static binary
|
|
||||||
staticBinary() bool
|
|
||||||
|
|
||||||
// Returns true for dependency roots (binaries)
|
|
||||||
// TODO(ccross): also handle dlopenable libraries
|
|
||||||
isDependencyRoot() bool
|
|
||||||
}
|
}
|
||||||
|
@@ -89,12 +89,13 @@ type libraryProperties struct {
|
|||||||
ApiLevel int `blueprint:"mutated"`
|
ApiLevel int `blueprint:"mutated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubCompiler struct {
|
type stubDecorator struct {
|
||||||
baseCompiler
|
*libraryDecorator
|
||||||
|
|
||||||
properties libraryProperties
|
properties libraryProperties
|
||||||
|
|
||||||
linker *stubLinker
|
versionScriptPath android.ModuleGenPath
|
||||||
|
installPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// OMG GO
|
// OMG GO
|
||||||
@@ -106,7 +107,7 @@ func intMin(a int, b int) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateStubApiVariants(mctx android.BottomUpMutatorContext, c *stubCompiler) {
|
func generateStubApiVariants(mctx android.BottomUpMutatorContext, c *stubDecorator) {
|
||||||
minVersion := 9 // Minimum version supported by the NDK.
|
minVersion := 9 // Minimum version supported by the NDK.
|
||||||
// TODO(danalbert): Use PlatformSdkVersion when possible.
|
// TODO(danalbert): Use PlatformSdkVersion when possible.
|
||||||
// This is an interesting case because for the moment we actually need 24
|
// This is an interesting case because for the moment we actually need 24
|
||||||
@@ -152,19 +153,19 @@ func generateStubApiVariants(mctx android.BottomUpMutatorContext, c *stubCompile
|
|||||||
|
|
||||||
modules := mctx.CreateVariations(versionStrs...)
|
modules := mctx.CreateVariations(versionStrs...)
|
||||||
for i, module := range modules {
|
for i, module := range modules {
|
||||||
module.(*Module).compiler.(*stubCompiler).properties.ApiLevel = firstGenVersion + i
|
module.(*Module).compiler.(*stubDecorator).properties.ApiLevel = firstGenVersion + i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ndkApiMutator(mctx android.BottomUpMutatorContext) {
|
func ndkApiMutator(mctx android.BottomUpMutatorContext) {
|
||||||
if m, ok := mctx.Module().(*Module); ok {
|
if m, ok := mctx.Module().(*Module); ok {
|
||||||
if compiler, ok := m.compiler.(*stubCompiler); ok {
|
if compiler, ok := m.compiler.(*stubDecorator); ok {
|
||||||
generateStubApiVariants(mctx, compiler)
|
generateStubApiVariants(mctx, compiler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *stubCompiler) compilerInit(ctx BaseModuleContext) {
|
func (c *stubDecorator) compilerInit(ctx BaseModuleContext) {
|
||||||
c.baseCompiler.compilerInit(ctx)
|
c.baseCompiler.compilerInit(ctx)
|
||||||
|
|
||||||
name := strings.TrimSuffix(ctx.ModuleName(), ".ndk")
|
name := strings.TrimSuffix(ctx.ModuleName(), ".ndk")
|
||||||
@@ -176,7 +177,7 @@ func (c *stubCompiler) compilerInit(ctx BaseModuleContext) {
|
|||||||
ndkMigratedLibs = append(ndkMigratedLibs, name)
|
ndkMigratedLibs = append(ndkMigratedLibs, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *stubCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
|
func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths {
|
||||||
arch := ctx.Arch().ArchType.String()
|
arch := ctx.Arch().ArchType.String()
|
||||||
|
|
||||||
if !strings.HasSuffix(ctx.ModuleName(), ndkLibrarySuffix) {
|
if !strings.HasSuffix(ctx.ModuleName(), ndkLibrarySuffix) {
|
||||||
@@ -189,7 +190,7 @@ func (c *stubCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) an
|
|||||||
stubSrcPath := android.PathForModuleGen(ctx, stubSrcName)
|
stubSrcPath := android.PathForModuleGen(ctx, stubSrcName)
|
||||||
versionScriptName := fileBase + ".map"
|
versionScriptName := fileBase + ".map"
|
||||||
versionScriptPath := android.PathForModuleGen(ctx, versionScriptName)
|
versionScriptPath := android.PathForModuleGen(ctx, versionScriptName)
|
||||||
c.linker.versionScriptPath = versionScriptPath
|
c.versionScriptPath = versionScriptPath
|
||||||
symbolFilePath := android.PathForModuleSrc(ctx, c.properties.Symbol_file)
|
symbolFilePath := android.PathForModuleSrc(ctx, c.properties.Symbol_file)
|
||||||
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
|
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
|
||||||
Rule: genStubSrc,
|
Rule: genStubSrc,
|
||||||
@@ -218,47 +219,31 @@ func (c *stubCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) an
|
|||||||
excludeSrcs := []string{}
|
excludeSrcs := []string{}
|
||||||
extraSrcs := []android.Path{stubSrcPath}
|
extraSrcs := []android.Path{stubSrcPath}
|
||||||
extraDeps := []android.Path{}
|
extraDeps := []android.Path{}
|
||||||
return c.baseCompiler.compileObjs(ctx, flags, subdir, srcs, excludeSrcs,
|
return compileObjs(ctx, flags, subdir, srcs, excludeSrcs,
|
||||||
extraSrcs, extraDeps)
|
extraSrcs, extraDeps)
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubLinker struct {
|
func (linker *stubDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
libraryLinker
|
|
||||||
|
|
||||||
versionScriptPath android.ModuleGenPath
|
|
||||||
}
|
|
||||||
|
|
||||||
func (linker *stubLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|
||||||
return Deps{}
|
return Deps{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (linker *stubLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
func (stub *stubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
linker.libraryLinker.libName = strings.TrimSuffix(ctx.ModuleName(),
|
stub.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(),
|
||||||
ndkLibrarySuffix)
|
ndkLibrarySuffix)
|
||||||
return linker.libraryLinker.linkerFlags(ctx, flags)
|
return stub.libraryDecorator.linkerFlags(ctx, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (linker *stubLinker) link(ctx ModuleContext, flags Flags, deps PathDeps,
|
func (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
|
||||||
objFiles android.Paths) android.Path {
|
objFiles android.Paths) android.Path {
|
||||||
|
|
||||||
linkerScriptFlag := "-Wl,--version-script," + linker.versionScriptPath.String()
|
linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
|
||||||
flags.LdFlags = append(flags.LdFlags, linkerScriptFlag)
|
flags.LdFlags = append(flags.LdFlags, linkerScriptFlag)
|
||||||
return linker.libraryLinker.link(ctx, flags, deps, objFiles)
|
return stub.libraryDecorator.link(ctx, flags, deps, objFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubInstaller struct {
|
func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) {
|
||||||
baseInstaller
|
|
||||||
|
|
||||||
compiler *stubCompiler
|
|
||||||
|
|
||||||
installPath string
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ installer = (*stubInstaller)(nil)
|
|
||||||
|
|
||||||
func (installer *stubInstaller) install(ctx ModuleContext, path android.Path) {
|
|
||||||
arch := ctx.Target().Arch.ArchType.Name
|
arch := ctx.Target().Arch.ArchType.Name
|
||||||
apiLevel := installer.compiler.properties.ApiLevel
|
apiLevel := stub.properties.ApiLevel
|
||||||
|
|
||||||
// arm64 isn't actually a multilib toolchain, so unlike the other LP64
|
// arm64 isn't actually a multilib toolchain, so unlike the other LP64
|
||||||
// architectures it's just installed to lib.
|
// architectures it's just installed to lib.
|
||||||
@@ -269,32 +254,26 @@ func (installer *stubInstaller) install(ctx ModuleContext, path android.Path) {
|
|||||||
|
|
||||||
installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf(
|
installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf(
|
||||||
"platforms/android-%d/arch-%s/usr/%s", apiLevel, arch, libDir))
|
"platforms/android-%d/arch-%s/usr/%s", apiLevel, arch, libDir))
|
||||||
installer.installPath = ctx.InstallFile(installDir, path).String()
|
stub.installPath = ctx.InstallFile(installDir, path).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStubLibrary() *Module {
|
func newStubLibrary() *Module {
|
||||||
module := newModule(android.DeviceSupported, android.MultilibBoth)
|
module, library := NewLibrary(android.DeviceSupported, true, false)
|
||||||
module.stl = nil
|
module.stl = nil
|
||||||
|
module.sanitize = nil
|
||||||
|
library.StripProperties.Strip.None = true
|
||||||
|
|
||||||
linker := &stubLinker{}
|
stub := &stubDecorator{
|
||||||
linker.dynamicProperties.BuildShared = true
|
libraryDecorator: library,
|
||||||
linker.dynamicProperties.BuildStatic = false
|
}
|
||||||
linker.stripper.StripProperties.Strip.None = true
|
module.compiler = stub
|
||||||
module.linker = linker
|
module.linker = stub
|
||||||
|
module.installer = stub
|
||||||
compiler := &stubCompiler{}
|
|
||||||
compiler.linker = linker
|
|
||||||
module.compiler = compiler
|
|
||||||
module.installer = &stubInstaller{baseInstaller{
|
|
||||||
dir: "lib",
|
|
||||||
dir64: "lib64",
|
|
||||||
}, compiler, ""}
|
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
func ndkLibraryFactory() (blueprint.Module, []interface{}) {
|
func ndkLibraryFactory() (blueprint.Module, []interface{}) {
|
||||||
module := newStubLibrary()
|
module := newStubLibrary()
|
||||||
return android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth,
|
return module.Init()
|
||||||
&module.compiler.(*stubCompiler).properties)
|
|
||||||
}
|
}
|
||||||
|
@@ -70,7 +70,11 @@ func (*ndkPrebuiltObjectLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Dep
|
|||||||
|
|
||||||
func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
|
func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
|
||||||
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
|
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
|
||||||
module.linker = &ndkPrebuiltObjectLinker{}
|
module.linker = &ndkPrebuiltObjectLinker{
|
||||||
|
objectLinker: objectLinker{
|
||||||
|
baseLinker: NewBaseLinker(),
|
||||||
|
},
|
||||||
|
}
|
||||||
module.Properties.HideFromMake = true
|
module.Properties.HideFromMake = true
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
@@ -86,14 +90,11 @@ func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ndkPrebuiltLibraryLinker struct {
|
type ndkPrebuiltLibraryLinker struct {
|
||||||
libraryLinker
|
*libraryDecorator
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil)
|
|
||||||
var _ exportedFlagsProducer = (*libraryLinker)(nil)
|
|
||||||
|
|
||||||
func (ndk *ndkPrebuiltLibraryLinker) linkerProps() []interface{} {
|
func (ndk *ndkPrebuiltLibraryLinker) linkerProps() []interface{} {
|
||||||
return append(ndk.libraryLinker.linkerProps(), &ndk.Properties, &ndk.flagExporter.Properties)
|
return append(ndk.libraryDecorator.linkerProps(), &ndk.Properties, &ndk.flagExporter.Properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ndkPrebuiltLibraryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
func (*ndkPrebuiltLibraryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
@@ -102,10 +103,14 @@ func (*ndkPrebuiltLibraryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) De
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
|
func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
|
||||||
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
|
module, library := NewLibrary(android.DeviceSupported, true, false)
|
||||||
linker := &ndkPrebuiltLibraryLinker{}
|
linker := &ndkPrebuiltLibraryLinker{
|
||||||
linker.dynamicProperties.BuildShared = true
|
libraryDecorator: library,
|
||||||
|
}
|
||||||
|
module.compiler = nil
|
||||||
module.linker = linker
|
module.linker = linker
|
||||||
|
module.installer = nil
|
||||||
|
module.stl = nil
|
||||||
module.Properties.HideFromMake = true
|
module.Properties.HideFromMake = true
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
@@ -128,19 +133,29 @@ type ndkPrebuiltStlLinker struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
|
func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
|
||||||
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
|
module, library := NewLibrary(android.DeviceSupported, true, false)
|
||||||
linker := &ndkPrebuiltStlLinker{}
|
linker := &ndkPrebuiltStlLinker{
|
||||||
linker.dynamicProperties.BuildShared = true
|
ndkPrebuiltLibraryLinker: ndkPrebuiltLibraryLinker{
|
||||||
|
libraryDecorator: library,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
module.compiler = nil
|
||||||
module.linker = linker
|
module.linker = linker
|
||||||
|
module.installer = nil
|
||||||
module.Properties.HideFromMake = true
|
module.Properties.HideFromMake = true
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
|
func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
|
||||||
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
|
module, library := NewLibrary(android.DeviceSupported, false, true)
|
||||||
linker := &ndkPrebuiltStlLinker{}
|
linker := &ndkPrebuiltStlLinker{
|
||||||
linker.dynamicProperties.BuildStatic = true
|
ndkPrebuiltLibraryLinker: ndkPrebuiltLibraryLinker{
|
||||||
|
libraryDecorator: library,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
module.compiler = nil
|
||||||
module.linker = linker
|
module.linker = linker
|
||||||
|
module.installer = nil
|
||||||
module.Properties.HideFromMake = true
|
module.Properties.HideFromMake = true
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
@@ -177,7 +192,7 @@ func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
|
|||||||
|
|
||||||
libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
|
libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
|
||||||
libExt := flags.Toolchain.ShlibSuffix()
|
libExt := flags.Toolchain.ShlibSuffix()
|
||||||
if ndk.dynamicProperties.BuildStatic {
|
if ndk.Properties.BuildStatic {
|
||||||
libExt = staticLibraryExtension
|
libExt = staticLibraryExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,40 +201,3 @@ func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
|
|||||||
libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
|
libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
|
||||||
return libDir.Join(ctx, libName+libExt)
|
return libDir.Join(ctx, libName+libExt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func linkageMutator(mctx android.BottomUpMutatorContext) {
|
|
||||||
if m, ok := mctx.Module().(*Module); ok {
|
|
||||||
if m.linker != nil {
|
|
||||||
if linker, ok := m.linker.(baseLinkerInterface); ok {
|
|
||||||
var modules []blueprint.Module
|
|
||||||
if linker.buildStatic() && linker.buildShared() {
|
|
||||||
modules = mctx.CreateLocalVariations("static", "shared")
|
|
||||||
static := modules[0].(*Module)
|
|
||||||
shared := modules[1].(*Module)
|
|
||||||
|
|
||||||
static.linker.(baseLinkerInterface).setStatic(true)
|
|
||||||
shared.linker.(baseLinkerInterface).setStatic(false)
|
|
||||||
|
|
||||||
if staticCompiler, ok := static.compiler.(*libraryCompiler); ok {
|
|
||||||
sharedCompiler := shared.compiler.(*libraryCompiler)
|
|
||||||
if len(staticCompiler.Properties.Static.Cflags) == 0 &&
|
|
||||||
len(sharedCompiler.Properties.Shared.Cflags) == 0 {
|
|
||||||
// Optimize out compiling common .o files twice for static+shared libraries
|
|
||||||
mctx.AddInterVariantDependency(reuseObjTag, shared, static)
|
|
||||||
sharedCompiler.baseCompiler.Properties.Srcs = nil
|
|
||||||
sharedCompiler.baseCompiler.Properties.Generated_sources = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if linker.buildStatic() {
|
|
||||||
modules = mctx.CreateLocalVariations("static")
|
|
||||||
modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true)
|
|
||||||
} else if linker.buildShared() {
|
|
||||||
modules = mctx.CreateLocalVariations("shared")
|
|
||||||
modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false)
|
|
||||||
} else {
|
|
||||||
panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -96,7 +96,7 @@ func (n *ndkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
|
|||||||
|
|
||||||
ctx.VisitAllModules(func(module blueprint.Module) {
|
ctx.VisitAllModules(func(module blueprint.Module) {
|
||||||
if m, ok := module.(*Module); ok {
|
if m, ok := module.(*Module); ok {
|
||||||
if installer, ok := m.installer.(*stubInstaller); ok {
|
if installer, ok := m.installer.(*stubDecorator); ok {
|
||||||
installPaths = append(installPaths, installer.installPath)
|
installPaths = append(installPaths, installer.installPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
cc/object.go
11
cc/object.go
@@ -32,13 +32,16 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type objectLinker struct {
|
type objectLinker struct {
|
||||||
|
*baseLinker
|
||||||
Properties ObjectLinkerProperties
|
Properties ObjectLinkerProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
func objectFactory() (blueprint.Module, []interface{}) {
|
func objectFactory() (blueprint.Module, []interface{}) {
|
||||||
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
|
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
|
||||||
module.compiler = &baseCompiler{}
|
module.linker = &objectLinker{
|
||||||
module.linker = &objectLinker{}
|
baseLinker: NewBaseLinker(),
|
||||||
|
}
|
||||||
|
module.compiler = NewBaseCompiler()
|
||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +87,3 @@ func (object *objectLinker) link(ctx ModuleContext,
|
|||||||
ctx.CheckbuildFile(outputFile)
|
ctx.CheckbuildFile(outputFile)
|
||||||
return outputFile
|
return outputFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*objectLinker) installable() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
@@ -345,7 +345,7 @@ func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
|
|||||||
func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
|
func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
|
||||||
return func(mctx android.BottomUpMutatorContext) {
|
return func(mctx android.BottomUpMutatorContext) {
|
||||||
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
|
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
|
||||||
if d, ok := c.linker.(baseLinkerInterface); ok && d.isDependencyRoot() && c.sanitize.Sanitizer(t) {
|
if c.isDependencyRoot() && c.sanitize.Sanitizer(t) {
|
||||||
modules := mctx.CreateVariations(t.String())
|
modules := mctx.CreateVariations(t.String())
|
||||||
modules[0].(*Module).sanitize.SetSanitizer(t, true)
|
modules[0].(*Module).sanitize.SetSanitizer(t, true)
|
||||||
if mctx.AConfig().EmbeddedInMake() && !c.Host() {
|
if mctx.AConfig().EmbeddedInMake() && !c.Host() {
|
||||||
|
234
cc/test.go
234
cc/test.go
@@ -24,10 +24,12 @@ import (
|
|||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestLinkerProperties struct {
|
type TestProperties struct {
|
||||||
// if set, build against the gtest library. Defaults to true.
|
// if set, build against the gtest library. Defaults to true.
|
||||||
Gtest bool
|
Gtest bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestBinaryProperties struct {
|
||||||
// Create a separate binary for each source file. Useful when there is
|
// Create a separate binary for each source file. Useful when there is
|
||||||
// global state that can not be torn down and reset between each test suite.
|
// global state that can not be torn down and reset between each test suite.
|
||||||
Test_per_src *bool
|
Test_per_src *bool
|
||||||
@@ -71,29 +73,50 @@ func benchmarkHostFactory() (blueprint.Module, []interface{}) {
|
|||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testPerSrc interface {
|
||||||
|
testPerSrc() bool
|
||||||
|
srcs() []string
|
||||||
|
setSrc(string, string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testBinary) testPerSrc() bool {
|
||||||
|
return Bool(test.Properties.Test_per_src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testBinary) srcs() []string {
|
||||||
|
return test.baseCompiler.Properties.Srcs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testBinary) setSrc(name, src string) {
|
||||||
|
test.baseCompiler.Properties.Srcs = []string{src}
|
||||||
|
test.binaryDecorator.Properties.Stem = name
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ testPerSrc = (*testBinary)(nil)
|
||||||
|
|
||||||
func testPerSrcMutator(mctx android.BottomUpMutatorContext) {
|
func testPerSrcMutator(mctx android.BottomUpMutatorContext) {
|
||||||
if m, ok := mctx.Module().(*Module); ok {
|
if m, ok := mctx.Module().(*Module); ok {
|
||||||
if test, ok := m.linker.(*testBinaryLinker); ok {
|
if test, ok := m.linker.(testPerSrc); ok {
|
||||||
if Bool(test.testLinker.Properties.Test_per_src) {
|
if test.testPerSrc() && len(test.srcs()) > 0 {
|
||||||
testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs))
|
testNames := make([]string, len(test.srcs()))
|
||||||
for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
|
for i, src := range test.srcs() {
|
||||||
testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
|
testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
|
||||||
}
|
}
|
||||||
tests := mctx.CreateLocalVariations(testNames...)
|
tests := mctx.CreateLocalVariations(testNames...)
|
||||||
for i, src := range m.compiler.(*baseCompiler).Properties.Srcs {
|
for i, src := range test.srcs() {
|
||||||
tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src}
|
tests[i].(*Module).linker.(testPerSrc).setSrc(testNames[i], src)
|
||||||
tests[i].(*Module).linker.(*testBinaryLinker).binaryLinker.Properties.Stem = testNames[i]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type testLinker struct {
|
type testDecorator struct {
|
||||||
Properties TestLinkerProperties
|
Properties TestProperties
|
||||||
|
linker *baseLinker
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
func (test *testDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
if !test.Properties.Gtest {
|
if !test.Properties.Gtest {
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
@@ -119,7 +142,7 @@ func (test *testLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
func (test *testDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
if test.Properties.Gtest {
|
if test.Properties.Gtest {
|
||||||
if ctx.sdk() && ctx.Device() {
|
if ctx.sdk() && ctx.Device() {
|
||||||
switch ctx.selectedStl() {
|
switch ctx.selectedStl() {
|
||||||
@@ -134,123 +157,156 @@ func (test *testLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||||||
deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
|
deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return deps
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
type testBinaryLinker struct {
|
func (test *testDecorator) linkerInit(ctx BaseModuleContext, linker *baseLinker) {
|
||||||
testLinker
|
|
||||||
binaryLinker
|
|
||||||
}
|
|
||||||
|
|
||||||
func (test *testBinaryLinker) linkerInit(ctx BaseModuleContext) {
|
|
||||||
test.binaryLinker.linkerInit(ctx)
|
|
||||||
runpath := "../../lib"
|
runpath := "../../lib"
|
||||||
if ctx.toolchain().Is64Bit() {
|
if ctx.toolchain().Is64Bit() {
|
||||||
runpath += "64"
|
runpath += "64"
|
||||||
}
|
}
|
||||||
test.dynamicProperties.RunPaths = append([]string{runpath}, test.dynamicProperties.RunPaths...)
|
linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, runpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testBinaryLinker) linkerProps() []interface{} {
|
func (test *testDecorator) linkerProps() []interface{} {
|
||||||
return append(test.binaryLinker.linkerProps(), &test.testLinker.Properties)
|
return []interface{}{&test.Properties}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testBinaryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
func NewTestInstaller() *baseInstaller {
|
||||||
flags = test.binaryLinker.linkerFlags(ctx, flags)
|
return NewBaseInstaller("nativetest", "nativetest64", InstallInData)
|
||||||
flags = test.testLinker.linkerFlags(ctx, flags)
|
|
||||||
return flags
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testBinaryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
type testBinary struct {
|
||||||
deps = test.testLinker.linkerDeps(ctx, deps)
|
testDecorator
|
||||||
deps = test.binaryLinker.linkerDeps(ctx, deps)
|
*binaryDecorator
|
||||||
|
*baseCompiler
|
||||||
|
*baseInstaller
|
||||||
|
Properties TestBinaryProperties
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testBinary) linkerProps() []interface{} {
|
||||||
|
props := append(test.testDecorator.linkerProps(), test.binaryDecorator.linkerProps()...)
|
||||||
|
props = append(props, &test.Properties)
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testBinary) linkerInit(ctx BaseModuleContext) {
|
||||||
|
test.testDecorator.linkerInit(ctx, test.binaryDecorator.baseLinker)
|
||||||
|
test.binaryDecorator.linkerInit(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testBinary) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
|
deps = test.testDecorator.linkerDeps(ctx, deps)
|
||||||
|
deps = test.binaryDecorator.linkerDeps(ctx, deps)
|
||||||
return deps
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
type testLibraryLinker struct {
|
func (test *testBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
testLinker
|
flags = test.binaryDecorator.linkerFlags(ctx, flags)
|
||||||
*libraryLinker
|
flags = test.testDecorator.linkerFlags(ctx, flags)
|
||||||
}
|
|
||||||
|
|
||||||
func (test *testLibraryLinker) linkerProps() []interface{} {
|
|
||||||
return append(test.libraryLinker.linkerProps(), &test.testLinker.Properties)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (test *testLibraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|
||||||
flags = test.libraryLinker.linkerFlags(ctx, flags)
|
|
||||||
flags = test.testLinker.linkerFlags(ctx, flags)
|
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testLibraryLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
func (test *testBinary) install(ctx ModuleContext, file android.Path) {
|
||||||
deps = test.testLinker.linkerDeps(ctx, deps)
|
test.baseInstaller.dir = filepath.Join("nativetest", ctx.ModuleName())
|
||||||
deps = test.libraryLinker.linkerDeps(ctx, deps)
|
test.baseInstaller.dir64 = filepath.Join("nativetest64", ctx.ModuleName())
|
||||||
return deps
|
test.baseInstaller.install(ctx, file)
|
||||||
}
|
|
||||||
|
|
||||||
type testInstaller struct {
|
|
||||||
baseInstaller
|
|
||||||
}
|
|
||||||
|
|
||||||
func (installer *testInstaller) install(ctx ModuleContext, file android.Path) {
|
|
||||||
installer.dir = filepath.Join(installer.dir, ctx.ModuleName())
|
|
||||||
installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName())
|
|
||||||
installer.baseInstaller.install(ctx, file)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTest(hod android.HostOrDeviceSupported) *Module {
|
func NewTest(hod android.HostOrDeviceSupported) *Module {
|
||||||
module := newModule(hod, android.MultilibBoth)
|
module, binary := NewBinary(hod)
|
||||||
module.compiler = &baseCompiler{}
|
module.multilib = android.MultilibBoth
|
||||||
linker := &testBinaryLinker{}
|
|
||||||
linker.testLinker.Properties.Gtest = true
|
test := &testBinary{
|
||||||
module.linker = linker
|
testDecorator: testDecorator{
|
||||||
module.installer = &testInstaller{
|
linker: binary.baseLinker,
|
||||||
baseInstaller: baseInstaller{
|
|
||||||
dir: "nativetest",
|
|
||||||
dir64: "nativetest64",
|
|
||||||
data: true,
|
|
||||||
},
|
},
|
||||||
|
binaryDecorator: binary,
|
||||||
|
baseCompiler: NewBaseCompiler(),
|
||||||
|
baseInstaller: NewTestInstaller(),
|
||||||
}
|
}
|
||||||
|
test.testDecorator.Properties.Gtest = true
|
||||||
|
module.compiler = test
|
||||||
|
module.linker = test
|
||||||
|
module.installer = test
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testLibrary struct {
|
||||||
|
testDecorator
|
||||||
|
*libraryDecorator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testLibrary) linkerProps() []interface{} {
|
||||||
|
return append(test.testDecorator.linkerProps(), test.libraryDecorator.linkerProps()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testLibrary) linkerInit(ctx BaseModuleContext) {
|
||||||
|
test.testDecorator.linkerInit(ctx, test.libraryDecorator.baseLinker)
|
||||||
|
test.libraryDecorator.linkerInit(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testLibrary) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
|
deps = test.testDecorator.linkerDeps(ctx, deps)
|
||||||
|
deps = test.libraryDecorator.linkerDeps(ctx, deps)
|
||||||
|
return deps
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testLibrary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
|
flags = test.libraryDecorator.linkerFlags(ctx, flags)
|
||||||
|
flags = test.testDecorator.linkerFlags(ctx, flags)
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
func NewTestLibrary(hod android.HostOrDeviceSupported) *Module {
|
func NewTestLibrary(hod android.HostOrDeviceSupported) *Module {
|
||||||
module := NewLibrary(android.HostAndDeviceSupported, false, true)
|
module, library := NewLibrary(android.HostAndDeviceSupported, false, true)
|
||||||
linker := &testLibraryLinker{
|
test := &testLibrary{
|
||||||
libraryLinker: module.linker.(*libraryLinker),
|
testDecorator: testDecorator{
|
||||||
}
|
linker: library.baseLinker,
|
||||||
linker.testLinker.Properties.Gtest = true
|
|
||||||
module.linker = linker
|
|
||||||
module.installer = &testInstaller{
|
|
||||||
baseInstaller: baseInstaller{
|
|
||||||
dir: "nativetest",
|
|
||||||
dir64: "nativetest64",
|
|
||||||
data: true,
|
|
||||||
},
|
},
|
||||||
|
libraryDecorator: library,
|
||||||
}
|
}
|
||||||
|
test.testDecorator.Properties.Gtest = true
|
||||||
|
module.linker = test
|
||||||
|
module.installer = nil
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
type benchmarkLinker struct {
|
type benchmarkDecorator struct {
|
||||||
testBinaryLinker
|
*binaryDecorator
|
||||||
|
*baseInstaller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (benchmark *benchmarkLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
func (benchmark *benchmarkDecorator) linkerInit(ctx BaseModuleContext) {
|
||||||
deps = benchmark.testBinaryLinker.linkerDeps(ctx, deps)
|
runpath := "../../lib"
|
||||||
|
if ctx.toolchain().Is64Bit() {
|
||||||
|
runpath += "64"
|
||||||
|
}
|
||||||
|
benchmark.baseLinker.dynamicProperties.RunPaths = append(benchmark.baseLinker.dynamicProperties.RunPaths, runpath)
|
||||||
|
benchmark.binaryDecorator.linkerInit(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (benchmark *benchmarkDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
|
deps = benchmark.binaryDecorator.linkerDeps(ctx, deps)
|
||||||
deps.StaticLibs = append(deps.StaticLibs, "libgoogle-benchmark")
|
deps.StaticLibs = append(deps.StaticLibs, "libgoogle-benchmark")
|
||||||
return deps
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) {
|
||||||
|
benchmark.baseInstaller.dir = filepath.Join("nativetest", ctx.ModuleName())
|
||||||
|
benchmark.baseInstaller.dir64 = filepath.Join("nativetest64", ctx.ModuleName())
|
||||||
|
}
|
||||||
|
|
||||||
func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
|
func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
|
||||||
module := newModule(hod, android.MultilibFirst)
|
module, binary := NewBinary(hod)
|
||||||
module.compiler = &baseCompiler{}
|
module.multilib = android.MultilibBoth
|
||||||
module.linker = &benchmarkLinker{}
|
|
||||||
module.installer = &testInstaller{
|
benchmark := &benchmarkDecorator{
|
||||||
baseInstaller: baseInstaller{
|
binaryDecorator: binary,
|
||||||
dir: "nativetest",
|
baseInstaller: NewTestInstaller(),
|
||||||
dir64: "nativetest64",
|
|
||||||
data: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
module.linker = benchmark
|
||||||
|
module.installer = benchmark
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
76
cc/toolchain_library.go
Normal file
76
cc/toolchain_library.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/blueprint"
|
||||||
|
"github.com/google/blueprint/proptools"
|
||||||
|
|
||||||
|
"android/soong"
|
||||||
|
"android/soong/android"
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Device libraries shipped with gcc
|
||||||
|
//
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
|
||||||
|
}
|
||||||
|
|
||||||
|
type toolchainLibraryDecorator struct {
|
||||||
|
*libraryDecorator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*toolchainLibraryDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
||||||
|
// toolchain libraries can't have any dependencies
|
||||||
|
return deps
|
||||||
|
}
|
||||||
|
|
||||||
|
func toolchainLibraryFactory() (blueprint.Module, []interface{}) {
|
||||||
|
module, library := NewLibrary(android.DeviceSupported, false, true)
|
||||||
|
toolchainLibrary := &toolchainLibraryDecorator{
|
||||||
|
libraryDecorator: library,
|
||||||
|
}
|
||||||
|
module.compiler = toolchainLibrary
|
||||||
|
module.linker = toolchainLibrary
|
||||||
|
module.Properties.Clang = proptools.BoolPtr(false)
|
||||||
|
module.stl = nil
|
||||||
|
module.sanitize = nil
|
||||||
|
module.installer = nil
|
||||||
|
return module.Init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (library *toolchainLibraryDecorator) compile(ctx ModuleContext, flags Flags,
|
||||||
|
deps PathDeps) android.Paths {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (library *toolchainLibraryDecorator) 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
|
||||||
|
}
|
Reference in New Issue
Block a user