Squash vendor sources before linkageMutator runs
linkageMutator removes srcs property of the shared variant of a lib in order to reuse *.o files compiled for the static variant also to the shared variant. However, this causes problem when vendor-specific srcs are specified in target: {vendor: {srcs: ["..."]}}. For example, let's assume cc_library { name: "libfoo", srcs: ["foo.c"], target: { vendor: { srcs: ["bar.c"], }, }, } Then, static_vendor: inputs = foo.o, bar.o shared_vendor: inputs = foo.o (from static_vendor), bar.o (from static_vendor), bar.o So, bar.o is included twice and this causes multiple symbol definition error. In order to handle the problem, vendor mutator is applied before the linkage mutator and the vendor-specific srcs are squashed in the vendor mutator. Bug: 67731122 Test: build Test: cc_test.go Change-Id: I2a5390295dddfc41260e9b6f02746908cdf47228
This commit is contained in:
parent
432a2d4033
commit
6a43f04777
|
@ -193,8 +193,8 @@ func TestArchConfig(buildDir string, env map[string]string) Config {
|
||||||
|
|
||||||
config.Targets = map[OsClass][]Target{
|
config.Targets = map[OsClass][]Target{
|
||||||
Device: []Target{
|
Device: []Target{
|
||||||
{Android, Arch{ArchType: Arm64, Native: true}},
|
{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true}},
|
||||||
{Android, Arch{ArchType: Arm, Native: true}},
|
{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true}},
|
||||||
},
|
},
|
||||||
Host: []Target{
|
Host: []Target{
|
||||||
{BuildOs, Arch{ArchType: X86_64}},
|
{BuildOs, Arch{ArchType: X86_64}},
|
||||||
|
|
20
cc/cc.go
20
cc/cc.go
|
@ -34,9 +34,9 @@ func init() {
|
||||||
android.RegisterModuleType("cc_defaults", defaultsFactory)
|
android.RegisterModuleType("cc_defaults", defaultsFactory)
|
||||||
|
|
||||||
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||||
|
ctx.BottomUp("image", vendorMutator).Parallel()
|
||||||
ctx.BottomUp("link", linkageMutator).Parallel()
|
ctx.BottomUp("link", linkageMutator).Parallel()
|
||||||
ctx.BottomUp("vndk", vndkMutator).Parallel()
|
ctx.BottomUp("vndk", vndkMutator).Parallel()
|
||||||
ctx.BottomUp("image", vendorMutator).Parallel()
|
|
||||||
ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
|
ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
|
||||||
ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
|
ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
|
||||||
ctx.BottomUp("begin", beginMutator).Parallel()
|
ctx.BottomUp("begin", beginMutator).Parallel()
|
||||||
|
@ -1297,6 +1297,16 @@ const (
|
||||||
vendorMode = "vendor"
|
vendorMode = "vendor"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func squashVendorSrcs(m *Module) {
|
||||||
|
if lib, ok := m.compiler.(*libraryDecorator); ok {
|
||||||
|
lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
|
||||||
|
lib.baseCompiler.Properties.Target.Vendor.Srcs...)
|
||||||
|
|
||||||
|
lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
|
||||||
|
lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func vendorMutator(mctx android.BottomUpMutatorContext) {
|
func vendorMutator(mctx android.BottomUpMutatorContext) {
|
||||||
if mctx.Os() != android.Android {
|
if mctx.Os() != android.Android {
|
||||||
return
|
return
|
||||||
|
@ -1352,11 +1362,15 @@ func vendorMutator(mctx android.BottomUpMutatorContext) {
|
||||||
// This will be available in both /system and /vendor
|
// This will be available in both /system and /vendor
|
||||||
// or a /system directory that is available to vendor.
|
// or a /system directory that is available to vendor.
|
||||||
mod := mctx.CreateVariations(coreMode, vendorMode)
|
mod := mctx.CreateVariations(coreMode, vendorMode)
|
||||||
mod[1].(*Module).Properties.UseVndk = true
|
vendor := mod[1].(*Module)
|
||||||
|
vendor.Properties.UseVndk = true
|
||||||
|
squashVendorSrcs(vendor)
|
||||||
} else if mctx.Vendor() && m.Properties.Sdk_version == "" {
|
} else if mctx.Vendor() && m.Properties.Sdk_version == "" {
|
||||||
// This will be available in /vendor only
|
// This will be available in /vendor only
|
||||||
mod := mctx.CreateVariations(vendorMode)
|
mod := mctx.CreateVariations(vendorMode)
|
||||||
mod[0].(*Module).Properties.UseVndk = true
|
vendor := mod[0].(*Module)
|
||||||
|
vendor.Properties.UseVndk = true
|
||||||
|
squashVendorSrcs(vendor)
|
||||||
} else {
|
} else {
|
||||||
// This is either in /system (or similar: /data), or is a
|
// This is either in /system (or similar: /data), or is a
|
||||||
// modules built with the NDK. Modules built with the NDK
|
// modules built with the NDK. Modules built with the NDK
|
||||||
|
|
126
cc/cc_test.go
126
cc/cc_test.go
|
@ -2,10 +2,136 @@ package cc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var buildDir string
|
||||||
|
|
||||||
|
func setUp() {
|
||||||
|
var err error
|
||||||
|
buildDir, err = ioutil.TempDir("", "soong_cc_test")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tearDown() {
|
||||||
|
os.RemoveAll(buildDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
run := func() int {
|
||||||
|
setUp()
|
||||||
|
defer tearDown()
|
||||||
|
|
||||||
|
return m.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit(run())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCc(t *testing.T, bp string) *android.TestContext {
|
||||||
|
config := android.TestArchConfig(buildDir, nil)
|
||||||
|
config.ProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
|
||||||
|
|
||||||
|
ctx := android.NewTestArchContext()
|
||||||
|
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(libraryFactory))
|
||||||
|
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory))
|
||||||
|
ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
|
||||||
|
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||||
|
ctx.BottomUp("image", vendorMutator).Parallel()
|
||||||
|
ctx.BottomUp("link", linkageMutator).Parallel()
|
||||||
|
ctx.BottomUp("vndk", vndkMutator).Parallel()
|
||||||
|
})
|
||||||
|
ctx.Register()
|
||||||
|
|
||||||
|
ctx.MockFileSystem(map[string][]byte{
|
||||||
|
"Android.bp": []byte(bp),
|
||||||
|
"foo.c": nil,
|
||||||
|
"bar.c": nil,
|
||||||
|
})
|
||||||
|
|
||||||
|
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
|
||||||
|
fail(t, errs)
|
||||||
|
_, errs = ctx.PrepareBuildActions(config)
|
||||||
|
fail(t, errs)
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVendorSrc(t *testing.T) {
|
||||||
|
ctx := testCc(t, `
|
||||||
|
cc_library {
|
||||||
|
name: "libTest",
|
||||||
|
srcs: ["foo.c"],
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs : [],
|
||||||
|
vendor_available: true,
|
||||||
|
target: {
|
||||||
|
vendor: {
|
||||||
|
srcs: ["bar.c"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
toolchain_library {
|
||||||
|
name: "libatomic",
|
||||||
|
vendor_available: true,
|
||||||
|
}
|
||||||
|
toolchain_library {
|
||||||
|
name: "libcompiler_rt-extras",
|
||||||
|
vendor_available: true,
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libc",
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs: [],
|
||||||
|
}
|
||||||
|
llndk_library {
|
||||||
|
name: "libc",
|
||||||
|
symbol_file: "",
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libm",
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs: [],
|
||||||
|
}
|
||||||
|
llndk_library {
|
||||||
|
name: "libm",
|
||||||
|
symbol_file: "",
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libdl",
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs: [],
|
||||||
|
}
|
||||||
|
llndk_library {
|
||||||
|
name: "libdl",
|
||||||
|
symbol_file: "",
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
ld := ctx.ModuleForTests("libTest", "android_arm_armv7-a-neon_vendor_shared").Rule("ld")
|
||||||
|
var objs []string
|
||||||
|
for _, o := range ld.Inputs {
|
||||||
|
objs = append(objs, o.Base())
|
||||||
|
}
|
||||||
|
if len(objs) != 2 {
|
||||||
|
t.Errorf("inputs of libTest is expected to 2, but was %d.", len(objs))
|
||||||
|
}
|
||||||
|
if objs[0] != "foo.o" || objs[1] != "bar.o" {
|
||||||
|
t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var firstUniqueElementsTestCases = []struct {
|
var firstUniqueElementsTestCases = []struct {
|
||||||
in []string
|
in []string
|
||||||
out []string
|
out []string
|
||||||
|
|
|
@ -490,14 +490,6 @@ 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)...)
|
||||||
|
|
||||||
if ctx.vndk() {
|
|
||||||
compiler.Properties.Srcs = append(compiler.Properties.Srcs,
|
|
||||||
compiler.Properties.Target.Vendor.Srcs...)
|
|
||||||
|
|
||||||
compiler.Properties.Exclude_srcs = append(compiler.Properties.Exclude_srcs,
|
|
||||||
compiler.Properties.Target.Vendor.Exclude_srcs...)
|
|
||||||
}
|
|
||||||
|
|
||||||
srcs := ctx.ExpandSources(compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
|
srcs := ctx.ExpandSources(compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
|
||||||
srcs = append(srcs, deps.GeneratedSources...)
|
srcs = append(srcs, deps.GeneratedSources...)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue