From cc271e20654dbc54c6cf5c72b3303723bf322164 Mon Sep 17 00:00:00 2001 From: Sam Delmerico Date: Wed, 1 Jun 2022 15:45:02 +0000 Subject: [PATCH] add multilib data_device_bins properties Some targets need to be able to specify the specific architecture for a data_device_bin module. This commit adds new properties to allow specification of first, both, 32, or 64 multilib properties. Bug: 231448797 Bug: 232408185 Test: go test ./java -run TestDataDeviceBinsBuildsDeviceBinary Change-Id: I457cf4b1a9ccb28b46042f874c96bd0a87009fab --- android/arch.go | 14 ++-- android/config.go | 4 +- java/java.go | 133 +++++++++++++++++++++++++++++--- java/java_test.go | 192 ++++++++++++++++++++++++++++++++++++---------- 4 files changed, 284 insertions(+), 59 deletions(-) diff --git a/android/arch.go b/android/arch.go index f732a7dd0..cbf77c758 100644 --- a/android/arch.go +++ b/android/arch.go @@ -1832,10 +1832,10 @@ func getCommonTargets(targets []Target) []Target { return ret } -// 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 // filter. -func firstTarget(targets []Target, filters ...string) []Target { +func FirstTarget(targets []Target, filters ...string) []Target { // find the first target from each OS var ret []Target hasHost := false @@ -1865,9 +1865,9 @@ func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([] case "common_first": buildTargets = getCommonTargets(targets) if prefer32 { - buildTargets = append(buildTargets, firstTarget(targets, "lib32", "lib64")...) + buildTargets = append(buildTargets, FirstTarget(targets, "lib32", "lib64")...) } else { - buildTargets = append(buildTargets, firstTarget(targets, "lib64", "lib32")...) + buildTargets = append(buildTargets, FirstTarget(targets, "lib64", "lib32")...) } case "both": if prefer32 { @@ -1883,12 +1883,12 @@ func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([] buildTargets = filterMultilibTargets(targets, "lib64") case "first": if prefer32 { - buildTargets = firstTarget(targets, "lib32", "lib64") + buildTargets = FirstTarget(targets, "lib32", "lib64") } else { - buildTargets = firstTarget(targets, "lib64", "lib32") + buildTargets = FirstTarget(targets, "lib64", "lib32") } case "first_prefer32": - buildTargets = firstTarget(targets, "lib32", "lib64") + buildTargets = FirstTarget(targets, "lib32", "lib64") case "prefer32": buildTargets = filterMultilibTargets(targets, "lib32") if len(buildTargets) == 0 { diff --git a/android/config.go b/android/config.go index eb01baaf6..ef712926f 100644 --- a/android/config.go +++ b/android/config.go @@ -416,7 +416,7 @@ func modifyTestConfigToSupportArchMutator(testConfig Config) { config.BuildOSTarget = config.Targets[config.BuildOS][0] config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0] config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] - config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] + config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0] config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64") config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a") config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm") @@ -554,7 +554,7 @@ func NewConfig(moduleListFile string, runGoTests bool, outDir, soongOutDir strin // Compilation targets for Android. if len(config.Targets[Android]) > 0 { config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] - config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] + config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0] } config.BazelContext, err = NewBazelContext(config) diff --git a/java/java.go b/java/java.go index 0dfb968e9..feb49ad1d 100644 --- a/java/java.go +++ b/java/java.go @@ -864,7 +864,25 @@ type hostTestProperties struct { Data_native_bins []string `android:"arch_variant"` // list of device binary modules that should be installed alongside the test - Data_device_bins []string `android:"arch_variant"` + // This property only adds the first variant of the dependency + Data_device_bins_first []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property adds 64bit AND 32bit variants of the dependency + Data_device_bins_both []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property only adds 64bit variants of the dependency + Data_device_bins_64 []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property adds 32bit variants of the dependency if available, or else + // defaults to the 64bit variant + Data_device_bins_prefer32 []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property only adds 32bit variants of the dependency + Data_device_bins_32 []string `android:"arch_variant"` } type testHelperLibraryProperties struct { @@ -931,6 +949,83 @@ func (j *JavaTestImport) InstallInTestcases() bool { return true } +func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) { + if len(j.testHostProperties.Data_device_bins_first) > 0 { + deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() + ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...) + } + + var maybeAndroid32Target *android.Target + var maybeAndroid64Target *android.Target + android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32") + android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64") + if len(android32TargetList) > 0 { + maybeAndroid32Target = &android32TargetList[0] + } + if len(android64TargetList) > 0 { + maybeAndroid64Target = &android64TargetList[0] + } + + if len(j.testHostProperties.Data_device_bins_both) > 0 { + if maybeAndroid32Target == nil && maybeAndroid64Target == nil { + ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets) + return + } + if maybeAndroid32Target != nil { + ctx.AddFarVariationDependencies( + maybeAndroid32Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_both..., + ) + } + if maybeAndroid64Target != nil { + ctx.AddFarVariationDependencies( + maybeAndroid64Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_both..., + ) + } + } + + if len(j.testHostProperties.Data_device_bins_prefer32) > 0 { + if maybeAndroid32Target != nil { + ctx.AddFarVariationDependencies( + maybeAndroid32Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_prefer32..., + ) + } else { + if maybeAndroid64Target == nil { + ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets) + return + } + ctx.AddFarVariationDependencies( + maybeAndroid64Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_prefer32..., + ) + } + } + + if len(j.testHostProperties.Data_device_bins_32) > 0 { + if maybeAndroid32Target == nil { + ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets) + return + } + deviceVariations := maybeAndroid32Target.Variations() + ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...) + } + + if len(j.testHostProperties.Data_device_bins_64) > 0 { + if maybeAndroid64Target == nil { + ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets) + return + } + deviceVariations := maybeAndroid64Target.Variations() + ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...) + } +} + func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { if len(j.testHostProperties.Data_native_bins) > 0 { for _, target := range ctx.MultiTargets() { @@ -938,11 +1033,6 @@ func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { } } - if len(j.testHostProperties.Data_device_bins) > 0 { - deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() - ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins...) - } - if len(j.testProperties.Jni_libs) > 0 { for _, target := range ctx.MultiTargets() { sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) @@ -950,6 +1040,8 @@ func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { } } + j.addDataDeviceBinsDeps(ctx) + j.deps(ctx) } @@ -957,17 +1049,40 @@ func (j *TestHost) AddExtraResource(p android.Path) { j.extraResources = append(j.extraResources, p) } +func (j *TestHost) dataDeviceBins() []string { + ret := make([]string, 0, + len(j.testHostProperties.Data_device_bins_first)+ + len(j.testHostProperties.Data_device_bins_both)+ + len(j.testHostProperties.Data_device_bins_prefer32)+ + len(j.testHostProperties.Data_device_bins_32)+ + len(j.testHostProperties.Data_device_bins_64), + ) + + ret = append(ret, j.testHostProperties.Data_device_bins_first...) + ret = append(ret, j.testHostProperties.Data_device_bins_both...) + ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...) + ret = append(ret, j.testHostProperties.Data_device_bins_32...) + ret = append(ret, j.testHostProperties.Data_device_bins_64...) + + return ret +} + func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { var configs []tradefed.Config - if len(j.testHostProperties.Data_device_bins) > 0 { + dataDeviceBins := j.dataDeviceBins() + if len(dataDeviceBins) > 0 { // add Tradefed configuration to push device bins to device for testing remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name()) options := []tradefed.Option{{Name: "cleanup", Value: "true"}} - for _, bin := range j.testHostProperties.Data_device_bins { + for _, bin := range dataDeviceBins { fullPath := filepath.Join(remoteDir, bin) options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath}) } - configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options}) + configs = append(configs, tradefed.Object{ + Type: "target_preparer", + Class: "com.android.tradefed.targetprep.PushFilePreparer", + Options: options, + }) } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) diff --git a/java/java_test.go b/java/java_test.go index 4c9382413..af889ccd4 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1498,62 +1498,172 @@ func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) { } func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) { - bp := ` + testCases := []struct { + dataDeviceBinType string + depCompileMultilib string + variants []string + expectedError string + }{ + { + dataDeviceBinType: "first", + depCompileMultilib: "first", + variants: []string{"android_arm64_armv8-a"}, + }, + { + dataDeviceBinType: "first", + depCompileMultilib: "both", + variants: []string{"android_arm64_armv8-a"}, + }, + { + // this is true because our testing framework is set up with + // Targets ~ [<64bit target>, <32bit target>], where 64bit is "first" + dataDeviceBinType: "first", + depCompileMultilib: "32", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "first", + depCompileMultilib: "64", + variants: []string{"android_arm64_armv8-a"}, + }, + { + dataDeviceBinType: "both", + depCompileMultilib: "both", + variants: []string{ + "android_arm_armv7-a-neon", + "android_arm64_armv8-a", + }, + }, + { + dataDeviceBinType: "both", + depCompileMultilib: "32", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "both", + depCompileMultilib: "64", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "both", + depCompileMultilib: "first", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "32", + depCompileMultilib: "32", + variants: []string{"android_arm_armv7-a-neon"}, + }, + { + dataDeviceBinType: "32", + depCompileMultilib: "first", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "32", + depCompileMultilib: "both", + variants: []string{"android_arm_armv7-a-neon"}, + }, + { + dataDeviceBinType: "32", + depCompileMultilib: "64", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "64", + depCompileMultilib: "64", + variants: []string{"android_arm64_armv8-a"}, + }, + { + dataDeviceBinType: "64", + depCompileMultilib: "both", + variants: []string{"android_arm64_armv8-a"}, + }, + { + dataDeviceBinType: "64", + depCompileMultilib: "first", + variants: []string{"android_arm64_armv8-a"}, + }, + { + dataDeviceBinType: "64", + depCompileMultilib: "32", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "prefer32", + depCompileMultilib: "32", + variants: []string{"android_arm_armv7-a-neon"}, + }, + { + dataDeviceBinType: "prefer32", + depCompileMultilib: "both", + variants: []string{"android_arm_armv7-a-neon"}, + }, + { + dataDeviceBinType: "prefer32", + depCompileMultilib: "first", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + { + dataDeviceBinType: "prefer32", + depCompileMultilib: "64", + expectedError: `Android.bp:2:3: dependency "bar" of "foo" missing variant`, + }, + } + + bpTemplate := ` java_test_host { name: "foo", srcs: ["test.java"], - data_device_bins: ["bar"], + data_device_bins_%s: ["bar"], } cc_binary { name: "bar", + compile_multilib: "%s", } ` - ctx := android.GroupFixturePreparers( - PrepareForIntegrationTestWithJava, - ).RunTestWithBp(t, bp) + for _, tc := range testCases { + bp := fmt.Sprintf(bpTemplate, tc.dataDeviceBinType, tc.depCompileMultilib) - buildOS := ctx.Config.BuildOS.String() - fooVariant := ctx.ModuleForTests("foo", buildOS+"_common") - barVariant := ctx.ModuleForTests("bar", "android_arm64_armv8-a") - fooMod := fooVariant.Module().(*TestHost) - - relocated := barVariant.Output("bar") - expectedInput := "out/soong/.intermediates/bar/android_arm64_armv8-a/unstripped/bar" - android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input) - - entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0] - expectedData := []string{ - "out/soong/.intermediates/bar/android_arm64_armv8-a/bar:bar", - } - actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] - android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData) -} - -func TestDataDeviceBinsAutogenTradefedConfig(t *testing.T) { - bp := ` - java_test_host { - name: "foo", - srcs: ["test.java"], - data_device_bins: ["bar"], + errorHandler := android.FixtureExpectsNoErrors + if tc.expectedError != "" { + errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError) } - cc_binary { - name: "bar", - } - ` + testName := fmt.Sprintf(`data_device_bins_%s with compile_multilib:"%s"`, tc.dataDeviceBinType, tc.depCompileMultilib) + t.Run(testName, func(t *testing.T) { + ctx := android.GroupFixturePreparers(PrepareForIntegrationTestWithJava). + ExtendWithErrorHandler(errorHandler). + RunTestWithBp(t, bp) + if tc.expectedError != "" { + return + } - ctx := android.GroupFixturePreparers( - PrepareForIntegrationTestWithJava, - ).RunTestWithBp(t, bp) + buildOS := ctx.Config.BuildOS.String() + fooVariant := ctx.ModuleForTests("foo", buildOS+"_common") + fooMod := fooVariant.Module().(*TestHost) + entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0] - buildOS := ctx.Config.BuildOS.String() - fooModule := ctx.ModuleForTests("foo", buildOS+"_common") - expectedAutogenConfig := `