Make FirstTarget treat HostCross separately from Host
Use Target.Os and Target.HostCross as the key in FirstTarget so that it returns a separate target for host and host cross architectures. This is useful when host and host cross are both linux_musl, but host cross is an independenct architecture like arm64. Also filter the targets returned by ctx.MultiTargets() to match the HostCross value of ctx.Target() to prevent the newly created HostCross variants from colliding with Host variants in JNI or test data attached to Java targets using a common arch. This relands If75790001afe9d0f9d4d8166f207847851812297 with the addition of the ctx.MultiTargets() filtering. Bug: 236052820 Test: TestArchMutator Change-Id: Ia6fe1185915d174d0ad6b401c227e0e57bee5c24
This commit is contained in:
@@ -616,6 +616,12 @@ func archMutator(bpctx blueprint.BottomUpMutatorContext) {
|
|||||||
mctx.ModuleErrorf("%s", err.Error())
|
mctx.ModuleErrorf("%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are no supported targets disable the module.
|
||||||
|
if len(targets) == 0 {
|
||||||
|
base.Disable()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// If the module is using extraMultilib, decode the extraMultilib selection into
|
// If the module is using extraMultilib, decode the extraMultilib selection into
|
||||||
// a separate list of Targets.
|
// a separate list of Targets.
|
||||||
var multiTargets []Target
|
var multiTargets []Target
|
||||||
@@ -624,6 +630,7 @@ func archMutator(bpctx blueprint.BottomUpMutatorContext) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
mctx.ModuleErrorf("%s", err.Error())
|
mctx.ModuleErrorf("%s", err.Error())
|
||||||
}
|
}
|
||||||
|
multiTargets = filterHostCross(multiTargets, targets[0].HostCross)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recovery is always the primary architecture, filter out any other architectures.
|
// Recovery is always the primary architecture, filter out any other architectures.
|
||||||
@@ -760,6 +767,18 @@ func filterToArch(targets []Target, archs ...ArchType) []Target {
|
|||||||
return targets
|
return targets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filterHostCross takes a list of Targets and a hostCross value, and returns a modified list
|
||||||
|
// that contains only Targets that have the specified HostCross.
|
||||||
|
func filterHostCross(targets []Target, hostCross bool) []Target {
|
||||||
|
for i := 0; i < len(targets); i++ {
|
||||||
|
if targets[i].HostCross != hostCross {
|
||||||
|
targets = append(targets[:i], targets[i+1:]...)
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targets
|
||||||
|
}
|
||||||
|
|
||||||
// archPropRoot is a struct type used as the top level of the arch-specific properties. It
|
// archPropRoot is a struct type used as the top level of the arch-specific properties. It
|
||||||
// contains the "arch", "multilib", and "target" property structs. It is used to split up the
|
// contains the "arch", "multilib", and "target" property structs. It is used to split up the
|
||||||
// property structs to limit how much is allocated when a single arch-specific property group is
|
// property structs to limit how much is allocated when a single arch-specific property group is
|
||||||
@@ -1789,20 +1808,23 @@ func getCommonTargets(targets []Target) []Target {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FirstTarget takes a list of Targets and a list of multilib values and returns a list of Targets
|
// FirstTarget takes a list of Targets and a list of multilib values and returns a list of Targets
|
||||||
// that contains zero or one Target for each OsType, selecting the one that matches the earliest
|
// that contains zero or one Target for each OsType and HostCross, selecting the one that matches
|
||||||
// filter.
|
// the earliest filter.
|
||||||
func FirstTarget(targets []Target, filters ...string) []Target {
|
func FirstTarget(targets []Target, filters ...string) []Target {
|
||||||
// find the first target from each OS
|
// find the first target from each OS
|
||||||
var ret []Target
|
var ret []Target
|
||||||
hasHost := false
|
type osHostCross struct {
|
||||||
set := make(map[OsType]bool)
|
os OsType
|
||||||
|
hostCross bool
|
||||||
|
}
|
||||||
|
set := make(map[osHostCross]bool)
|
||||||
|
|
||||||
for _, filter := range filters {
|
for _, filter := range filters {
|
||||||
buildTargets := filterMultilibTargets(targets, filter)
|
buildTargets := filterMultilibTargets(targets, filter)
|
||||||
for _, t := range buildTargets {
|
for _, t := range buildTargets {
|
||||||
if _, found := set[t.Os]; !found {
|
key := osHostCross{t.Os, t.HostCross}
|
||||||
hasHost = hasHost || (t.Os.Class == Host)
|
if _, found := set[key]; !found {
|
||||||
set[t.Os] = true
|
set[key] = true
|
||||||
ret = append(ret, t)
|
ret = append(ret, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -259,6 +259,27 @@ type archTestModule struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *archTestMultiTargetsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *archTestMultiTargetsModule) DepsMutator(ctx BottomUpMutatorContext) {
|
||||||
|
ctx.AddDependency(ctx.Module(), nil, m.props.Deps...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func archTestMultiTargetsModuleFactory() Module {
|
||||||
|
m := &archTestMultiTargetsModule{}
|
||||||
|
m.AddProperties(&m.props)
|
||||||
|
InitAndroidMultiTargetsArchModule(m, HostAndDeviceSupported, MultilibCommon)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
type archTestMultiTargetsModule struct {
|
||||||
|
ModuleBase
|
||||||
|
props struct {
|
||||||
|
Deps []string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (m *archTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
func (m *archTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,19 +298,27 @@ var prepareForArchTest = GroupFixturePreparers(
|
|||||||
PrepareForTestWithArchMutator,
|
PrepareForTestWithArchMutator,
|
||||||
FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
||||||
ctx.RegisterModuleType("module", archTestModuleFactory)
|
ctx.RegisterModuleType("module", archTestModuleFactory)
|
||||||
|
ctx.RegisterModuleType("multi_targets_module", archTestMultiTargetsModuleFactory)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestArchMutator(t *testing.T) {
|
func TestArchMutator(t *testing.T) {
|
||||||
var buildOSVariants []string
|
var buildOSVariants []string
|
||||||
|
var buildOS64Variants []string
|
||||||
var buildOS32Variants []string
|
var buildOS32Variants []string
|
||||||
|
var buildOSCommonVariant string
|
||||||
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "linux":
|
case "linux":
|
||||||
buildOSVariants = []string{"linux_glibc_x86_64", "linux_glibc_x86"}
|
buildOSVariants = []string{"linux_glibc_x86_64", "linux_glibc_x86"}
|
||||||
|
buildOS64Variants = []string{"linux_glibc_x86_64"}
|
||||||
buildOS32Variants = []string{"linux_glibc_x86"}
|
buildOS32Variants = []string{"linux_glibc_x86"}
|
||||||
|
buildOSCommonVariant = "linux_glibc_common"
|
||||||
case "darwin":
|
case "darwin":
|
||||||
buildOSVariants = []string{"darwin_x86_64"}
|
buildOSVariants = []string{"darwin_x86_64"}
|
||||||
|
buildOS64Variants = []string{"darwin_x86_64"}
|
||||||
buildOS32Variants = nil
|
buildOS32Variants = nil
|
||||||
|
buildOSCommonVariant = "darwin_common"
|
||||||
}
|
}
|
||||||
|
|
||||||
bp := `
|
bp := `
|
||||||
@@ -312,24 +341,46 @@ func TestArchMutator(t *testing.T) {
|
|||||||
host_supported: true,
|
host_supported: true,
|
||||||
compile_multilib: "32",
|
compile_multilib: "32",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module {
|
||||||
|
name: "first",
|
||||||
|
host_supported: true,
|
||||||
|
compile_multilib: "first",
|
||||||
|
}
|
||||||
|
|
||||||
|
multi_targets_module {
|
||||||
|
name: "multi_targets",
|
||||||
|
host_supported: true,
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
preparer FixturePreparer
|
preparer FixturePreparer
|
||||||
fooVariants []string
|
fooVariants []string
|
||||||
barVariants []string
|
barVariants []string
|
||||||
bazVariants []string
|
bazVariants []string
|
||||||
quxVariants []string
|
quxVariants []string
|
||||||
|
firstVariants []string
|
||||||
|
|
||||||
|
multiTargetVariants []string
|
||||||
|
multiTargetVariantsMap map[string][]string
|
||||||
|
|
||||||
|
goOS string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "normal",
|
name: "normal",
|
||||||
preparer: nil,
|
preparer: nil,
|
||||||
fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
|
fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
|
||||||
barVariants: append(buildOSVariants, "android_arm64_armv8-a", "android_arm_armv7-a-neon"),
|
barVariants: append(buildOSVariants, "android_arm64_armv8-a", "android_arm_armv7-a-neon"),
|
||||||
bazVariants: nil,
|
bazVariants: nil,
|
||||||
quxVariants: append(buildOS32Variants, "android_arm_armv7-a-neon"),
|
quxVariants: append(buildOS32Variants, "android_arm_armv7-a-neon"),
|
||||||
},
|
firstVariants: append(buildOS64Variants, "android_arm64_armv8-a"),
|
||||||
|
multiTargetVariants: []string{buildOSCommonVariant, "android_common"},
|
||||||
|
multiTargetVariantsMap: map[string][]string{
|
||||||
|
buildOSCommonVariant: buildOS64Variants,
|
||||||
|
"android_common": {"android_arm64_armv8-a"},
|
||||||
|
}},
|
||||||
{
|
{
|
||||||
name: "host-only",
|
name: "host-only",
|
||||||
preparer: FixtureModifyConfig(func(config Config) {
|
preparer: FixtureModifyConfig(func(config Config) {
|
||||||
@@ -337,10 +388,33 @@ func TestArchMutator(t *testing.T) {
|
|||||||
config.BuildOSCommonTarget = Target{}
|
config.BuildOSCommonTarget = Target{}
|
||||||
config.Targets[Android] = nil
|
config.Targets[Android] = nil
|
||||||
}),
|
}),
|
||||||
fooVariants: nil,
|
fooVariants: nil,
|
||||||
barVariants: buildOSVariants,
|
barVariants: buildOSVariants,
|
||||||
bazVariants: nil,
|
bazVariants: nil,
|
||||||
quxVariants: buildOS32Variants,
|
quxVariants: buildOS32Variants,
|
||||||
|
firstVariants: buildOS64Variants,
|
||||||
|
multiTargetVariants: []string{buildOSCommonVariant},
|
||||||
|
multiTargetVariantsMap: map[string][]string{
|
||||||
|
buildOSCommonVariant: buildOS64Variants,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "same arch host and host cross",
|
||||||
|
preparer: FixtureModifyConfig(func(config Config) {
|
||||||
|
modifyTestConfigForMusl(config)
|
||||||
|
modifyTestConfigForMuslArm64HostCross(config)
|
||||||
|
}),
|
||||||
|
fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
|
||||||
|
barVariants: []string{"linux_musl_x86_64", "linux_musl_arm64", "linux_musl_x86", "android_arm64_armv8-a", "android_arm_armv7-a-neon"},
|
||||||
|
bazVariants: nil,
|
||||||
|
quxVariants: []string{"linux_musl_x86", "android_arm_armv7-a-neon"},
|
||||||
|
firstVariants: []string{"linux_musl_x86_64", "linux_musl_arm64", "android_arm64_armv8-a"},
|
||||||
|
multiTargetVariants: []string{"linux_musl_common", "android_common"},
|
||||||
|
multiTargetVariantsMap: map[string][]string{
|
||||||
|
"linux_musl_common": {"linux_musl_x86_64"},
|
||||||
|
"android_common": {"android_arm64_armv8-a"},
|
||||||
|
},
|
||||||
|
goOS: "linux",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,8 +430,21 @@ func TestArchMutator(t *testing.T) {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moduleMultiTargets := func(ctx *TestContext, name string, variant string) []string {
|
||||||
|
var ret []string
|
||||||
|
targets := ctx.ModuleForTests(name, variant).Module().MultiTargets()
|
||||||
|
for _, t := range targets {
|
||||||
|
ret = append(ret, t.String())
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
for _, tt := range testCases {
|
for _, tt := range testCases {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.goOS != runtime.GOOS {
|
||||||
|
t.Skipf("requries runtime.GOOS %s", tt.goOS)
|
||||||
|
}
|
||||||
|
|
||||||
result := GroupFixturePreparers(
|
result := GroupFixturePreparers(
|
||||||
prepareForArchTest,
|
prepareForArchTest,
|
||||||
// Test specific preparer
|
// Test specific preparer
|
||||||
@@ -381,6 +468,20 @@ func TestArchMutator(t *testing.T) {
|
|||||||
if g, w := enabledVariants(ctx, "qux"), tt.quxVariants; !reflect.DeepEqual(w, g) {
|
if g, w := enabledVariants(ctx, "qux"), tt.quxVariants; !reflect.DeepEqual(w, g) {
|
||||||
t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
|
t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
|
||||||
}
|
}
|
||||||
|
if g, w := enabledVariants(ctx, "first"), tt.firstVariants; !reflect.DeepEqual(w, g) {
|
||||||
|
t.Errorf("want first variants:\n%q\ngot:\n%q\n", w, g)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, w := enabledVariants(ctx, "multi_targets"), tt.multiTargetVariants; !reflect.DeepEqual(w, g) {
|
||||||
|
t.Fatalf("want multi_target variants:\n%q\ngot:\n%q\n", w, g)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, variant := range tt.multiTargetVariants {
|
||||||
|
targets := moduleMultiTargets(ctx, "multi_targets", variant)
|
||||||
|
if g, w := targets, tt.multiTargetVariantsMap[variant]; !reflect.DeepEqual(w, g) {
|
||||||
|
t.Errorf("want ctx.MultiTarget() for %q:\n%q\ngot:\n%q\n", variant, w, g)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -118,6 +118,11 @@ func modifyTestConfigForMusl(config Config) {
|
|||||||
config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
|
config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func modifyTestConfigForMuslArm64HostCross(config Config) {
|
||||||
|
config.Targets[LinuxMusl] = append(config.Targets[LinuxMusl],
|
||||||
|
Target{config.BuildOS, Arch{ArchType: Arm64}, NativeBridgeDisabled, "", "", true})
|
||||||
|
}
|
||||||
|
|
||||||
// TestArchConfig returns a Config object suitable for using for tests that
|
// TestArchConfig returns a Config object suitable for using for tests that
|
||||||
// need to run the arch mutator.
|
// need to run the arch mutator.
|
||||||
func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
|
func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
|
||||||
|
Reference in New Issue
Block a user