diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 2e4dc946e..a5e7cd6d1 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -204,6 +204,7 @@ var ( "system/libziparchive": Bp2BuildDefaultTrueRecursively, "system/logging/liblog": Bp2BuildDefaultTrueRecursively, "system/media/audio": Bp2BuildDefaultTrueRecursively, + "system/memory/libion": Bp2BuildDefaultTrueRecursively, "system/memory/libmemunreachable": Bp2BuildDefaultTrueRecursively, "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively, "system/timezone/apex": Bp2BuildDefaultTrueRecursively, @@ -263,21 +264,23 @@ var ( Bp2buildModuleAlwaysConvertList = []string{ // cc mainline modules - "libnativeloader-headers", - "libgui_bufferqueue_sources", "code_coverage.policy", "code_coverage.policy.other", "codec2_soft_exports", "com.android.media.swcodec-ld.config.txt", - "libcodec2_headers", - "libcodec2_internal", "com.android.media.swcodec-mediaswcodec.rc", "flatbuffer_headers", "gemmlowp_headers", "gl_headers", - "libbluetooth-types-header", "libaudioclient_aidl_conversion_util", "libaudioutils_fixedfft", + "libbluetooth-types-header", + "libcodec2_headers", + "libcodec2_internal", + "libdmabufheap", + "libgui_bufferqueue_sources", + "libnativeloader-headers", + "libsync", //external/avb "avbtool", diff --git a/android/module.go b/android/module.go index 21d5a3d7e..8bbfd8a7f 100644 --- a/android/module.go +++ b/android/module.go @@ -1181,33 +1181,89 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{}) var enabledProperty bazel.BoolAttribute - if props.Enabled != nil { - enabledProperty.Value = props.Enabled + + onlyAndroid := false + neitherHostNorDevice := false + + osSupport := map[string]bool{} + + // if the target is enabled and supports arch variance, determine the defaults based on the module + // type's host or device property and host_supported/device_supported properties + if mod.commonProperties.ArchSpecific { + moduleSupportsDevice := mod.DeviceSupported() + moduleSupportsHost := mod.HostSupported() + if moduleSupportsHost && !moduleSupportsDevice { + // for host only, we specify as unsupported on android rather than listing all host osSupport + // TODO(b/220874839): consider replacing this with a constraint that covers all host osSupport + // instead + enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(false)) + } else if moduleSupportsDevice && !moduleSupportsHost { + enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(true)) + // specify as a positive to ensure any target-specific enabled can be resolved + // also save that a target is only android, as if there is only the positive restriction on + // android, it'll be dropped, so we may need to add it back later + onlyAndroid = true + } else if !moduleSupportsHost && !moduleSupportsDevice { + neitherHostNorDevice = true + } + + for _, os := range OsTypeList() { + if os.Class == Host { + osSupport[os.Name] = moduleSupportsHost + } else if os.Class == Device { + osSupport[os.Name] = moduleSupportsDevice + } + } + } + + if neitherHostNorDevice { + // we can't build this, disable + enabledProperty.Value = proptools.BoolPtr(false) + } else if props.Enabled != nil { + enabledProperty.SetValue(props.Enabled) + if !*props.Enabled { + for os, enabled := range osSupport { + if val := enabledProperty.SelectValue(bazel.OsConfigurationAxis, os); enabled && val != nil && *val { + // if this should be disabled by default, clear out any enabling we've done + enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, os, nil) + } + } + } } for axis, configToProps := range archVariantProps { for config, _props := range configToProps { if archProps, ok := _props.(*commonProperties); ok { required.SetSelectValue(axis, config, depsToLabelList(archProps.Required).Value) - if archProps.Enabled != nil { - enabledProperty.SetSelectValue(axis, config, archProps.Enabled) + if !neitherHostNorDevice { + if archProps.Enabled != nil { + if axis != bazel.OsConfigurationAxis || osSupport[config] { + enabledProperty.SetSelectValue(axis, config, archProps.Enabled) + } + } } } } } - if enabledPropertyOverrides.Value != nil { - enabledProperty.Value = enabledPropertyOverrides.Value - } - for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() { - configToBools := enabledPropertyOverrides.ConfigurableValues[axis] - for cfg, val := range configToBools { - enabledProperty.SetSelectValue(axis, cfg, &val) + if !neitherHostNorDevice { + if enabledPropertyOverrides.Value != nil { + enabledProperty.Value = enabledPropertyOverrides.Value + } + for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() { + configToBools := enabledPropertyOverrides.ConfigurableValues[axis] + for cfg, val := range configToBools { + if axis != bazel.OsConfigurationAxis || osSupport[cfg] { + enabledProperty.SetSelectValue(axis, cfg, &val) + } + } } } productConfigEnabledLabels := []bazel.Label{} - if !proptools.BoolDefault(enabledProperty.Value, true) { + // TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we + // should handle it correctly + if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice { // If the module is not enabled by default, then we can check if a // product variable enables it productConfigEnabledLabels = productVariableConfigEnableLabels(ctx) @@ -1224,11 +1280,6 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator productConfigEnabledLabels, nil, }) - moduleSupportsDevice := mod.commonProperties.HostOrDeviceSupported&deviceSupported == deviceSupported - if mod.commonProperties.HostOrDeviceSupported != NeitherHostNorDeviceSupported && !moduleSupportsDevice { - enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(false)) - } - platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute( bazel.LabelList{[]bazel.Label{bazel.Label{Label: "@platforms//:incompatible"}}, nil}, bazel.LabelList{[]bazel.Label{}, nil}) @@ -1236,6 +1287,13 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator ctx.ModuleErrorf("Error processing platform enabled attribute: %s", err) } + // if android is the only arch/os enabled, then add a restriction to only be compatible with android + if platformEnabledAttribute.IsNil() && onlyAndroid { + l := bazel.LabelAttribute{} + l.SetValue(bazel.Label{Label: bazel.OsConfigurationAxis.SelectKey(Android.Name)}) + platformEnabledAttribute.Add(&l) + } + data.Append(required) constraints := constraintAttributes{} diff --git a/bazel/properties.go b/bazel/properties.go index 41bcaca81..e29b9e137 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -409,6 +409,11 @@ func (ba BoolAttribute) HasConfigurableValues() bool { return false } +// SetValue sets value for the no config axis +func (ba *BoolAttribute) SetValue(value *bool) { + ba.SetSelectValue(NoConfigAxis, "", value) +} + // SetSelectValue sets value for the given axis/config. func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, value *bool) { axis.validateConfig(config) diff --git a/bp2build/android_app_certificate_conversion_test.go b/bp2build/android_app_certificate_conversion_test.go index 035a3529e..173b4e485 100644 --- a/bp2build/android_app_certificate_conversion_test.go +++ b/bp2build/android_app_certificate_conversion_test.go @@ -42,7 +42,7 @@ android_app_certificate { } `, expectedBazelTargets: []string{ - makeBazelTarget("android_app_certificate", "com.android.apogee.cert", attrNameToString{ + makeBazelTargetNoRestrictions("android_app_certificate", "com.android.apogee.cert", attrNameToString{ "certificate": `"chamber_of_secrets_dir"`, }), }}) diff --git a/bp2build/apex_key_conversion_test.go b/bp2build/apex_key_conversion_test.go index 1d949901c..dfa96a290 100644 --- a/bp2build/apex_key_conversion_test.go +++ b/bp2build/apex_key_conversion_test.go @@ -42,7 +42,7 @@ apex_key { private_key: "com.android.apogee.pem", } `, - expectedBazelTargets: []string{makeBazelTarget("apex_key", "com.android.apogee.key", attrNameToString{ + expectedBazelTargets: []string{makeBazelTargetNoRestrictions("apex_key", "com.android.apogee.key", attrNameToString{ "private_key": `"com.android.apogee.pem"`, "public_key": `"com.android.apogee.avbpubkey"`, }), diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index 0f6e13942..19209f634 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -201,7 +201,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) { config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) - ctx.RegisterModuleType("custom", customModuleFactory) + ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice) ctx.Register() _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) @@ -501,6 +501,215 @@ custom { } } +func TestBp2buildHostAndDevice(t *testing.T) { + testCases := []bp2buildTestCase{ + { + description: "host and device, device only", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetHostOrDevice("custom", "foo", attrNameToString{}, android.DeviceSupported), + }, + }, + { + description: "host and device, both", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + host_supported: true, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetNoRestrictions("custom", "foo", attrNameToString{}), + }, + }, + { + description: "host and device, host explicitly disabled", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + host_supported: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetHostOrDevice("custom", "foo", attrNameToString{}, android.DeviceSupported), + }, + }, + { + description: "host and device, neither", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + host_supported: false, + device_supported: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetNoRestrictions("custom", "foo", attrNameToString{ + "target_compatible_with": `["@platforms//:incompatible"]`, + }), + }, + }, + { + description: "host and device, neither, cannot override with product_var", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + host_supported: false, + device_supported: false, + product_variables: { unbundled_build: { enabled: true } }, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetNoRestrictions("custom", "foo", attrNameToString{ + "target_compatible_with": `["@platforms//:incompatible"]`, + }), + }, + }, + { + description: "host and device, both, disabled overrided with product_var", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + host_supported: true, + device_supported: true, + enabled: false, + product_variables: { unbundled_build: { enabled: true } }, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetNoRestrictions("custom", "foo", attrNameToString{ + "target_compatible_with": `["//build/bazel/product_variables:unbundled_build"]`, + }), + }, + }, + { + description: "host and device, neither, cannot override with arch enabled", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + host_supported: false, + device_supported: false, + arch: { x86: { enabled: true } }, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetNoRestrictions("custom", "foo", attrNameToString{ + "target_compatible_with": `["@platforms//:incompatible"]`, + }), + }, + }, + { + description: "host and device, host only", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, + blueprint: `custom { + name: "foo", + host_supported: true, + device_supported: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetHostOrDevice("custom", "foo", attrNameToString{}, android.HostSupported), + }, + }, + { + description: "host only", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostSupported, + blueprint: `custom { + name: "foo", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetHostOrDevice("custom", "foo", attrNameToString{}, android.HostSupported), + }, + }, + { + description: "device only", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryDeviceSupported, + blueprint: `custom { + name: "foo", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetHostOrDevice("custom", "foo", attrNameToString{}, android.DeviceSupported), + }, + }, + { + description: "host and device default, default", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault, + blueprint: `custom { + name: "foo", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetNoRestrictions("custom", "foo", attrNameToString{}), + }, + }, + { + description: "host and device default, device only", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault, + blueprint: `custom { + name: "foo", + host_supported: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetHostOrDevice("custom", "foo", attrNameToString{}, android.DeviceSupported), + }, + }, + { + description: "host and device default, host only", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault, + blueprint: `custom { + name: "foo", + device_supported: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetHostOrDevice("custom", "foo", attrNameToString{}, android.HostSupported), + }, + }, + { + description: "host and device default, neither", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault, + blueprint: `custom { + name: "foo", + host_supported: false, + device_supported: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTargetNoRestrictions("custom", "foo", attrNameToString{ + "target_compatible_with": `["@platforms//:incompatible"]`, + }), + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + runBp2BuildTestCaseSimple(t, tc) + }) + } +} + func TestLoadStatements(t *testing.T) { testCases := []struct { bazelTargets BazelTargets @@ -610,6 +819,7 @@ func TestGenerateBazelTargetModules_OneToMany_LoadedFromStarlark(t *testing.T) { { bp: `custom { name: "bar", + host_supported: true, one_to_many_prop: true, bazel_module: { bp2build_available: true }, }`, @@ -634,7 +844,7 @@ load("//build/bazel/rules:rules.bzl", "my_library")`, for _, testCase := range testCases { config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) - ctx.RegisterModuleType("custom", customModuleFactory) + ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice) ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) @@ -680,7 +890,7 @@ func TestModuleTypeBp2Build(t *testing.T) { bazel_module: { bp2build_available: true }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{}), + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{}), }, }, { @@ -693,7 +903,7 @@ func TestModuleTypeBp2Build(t *testing.T) { bazel_module: { bp2build_available: true }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{}), + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{}), }, }, { @@ -706,7 +916,7 @@ func TestModuleTypeBp2Build(t *testing.T) { bazel_module: { bp2build_available: true }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "srcs": `[ "a", "b", @@ -725,7 +935,7 @@ func TestModuleTypeBp2Build(t *testing.T) { bazel_module: { bp2build_available: true }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "srcs": `["b"]`, }), }, @@ -740,7 +950,7 @@ func TestModuleTypeBp2Build(t *testing.T) { bazel_module: { bp2build_available: true }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "srcs": `[ "other/a.txt", "other/b.txt", @@ -772,7 +982,7 @@ func TestModuleTypeBp2Build(t *testing.T) { "other/file": "", }, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "srcs": `[ "a.txt", "b.txt", @@ -801,7 +1011,7 @@ func TestModuleTypeBp2Build(t *testing.T) { }`, }, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "srcs": `[ "//other:foo", "c", @@ -884,7 +1094,7 @@ func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { { description: "generates more than 1 target if needed", moduleTypeUnderTest: "custom", - moduleTypeUnderTestFactory: customModuleFactory, + moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice, bp: `custom { name: "foo", one_to_many_prop: true, @@ -1092,7 +1302,7 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { "other/BUILD.bazel": `// definition for fg_bar`, }, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{}), + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{}), `// definition for fg_bar`, }, }, @@ -1118,7 +1328,7 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_bar", map[string]string{}), + makeBazelTargetNoRestrictions("filegroup", "fg_bar", map[string]string{}), `// BUILD file`, }, }, @@ -1203,7 +1413,7 @@ func TestGlobExcludeSrcs(t *testing.T) { "dir/f.txt": "", }, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "srcs": `[ "a.txt", "b.txt", @@ -1234,7 +1444,7 @@ func TestGlobExcludeSrcs(t *testing.T) { "dir/subdir/f.txt": "", }, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "srcs": `[ "a.txt", "//dir/subdir:e.txt", @@ -1265,7 +1475,7 @@ filegroup { bazel_module: { bp2build_available: true }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "data": `[":reqd"]`, }), }, @@ -1337,7 +1547,7 @@ filegroup { bazel_module: { bp2build_available: true }, }`, expectedBazelTargets: []string{ - makeBazelTarget("filegroup", "fg_foo", map[string]string{ + makeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{ "data": `[":reqd"]`, }), }, diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 30be9979e..4794269e4 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -34,10 +34,11 @@ type testBazelTarget struct { attrs attrNameToString } -func generateBazelTargetsForTest(targets []testBazelTarget) []string { +func generateBazelTargetsForTest(targets []testBazelTarget, hod android.HostOrDeviceSupported) []string { ret := make([]string, 0, len(targets)) for _, t := range targets { - ret = append(ret, makeBazelTarget(t.typ, t.name, t.attrs)) + attrs := t.attrs.clone() + ret = append(ret, makeBazelTargetHostOrDevice(t.typ, t.name, attrs, hod)) } return ret } @@ -65,42 +66,33 @@ func runCcBinaryTests(t *testing.T, tc ccBinaryBp2buildTestCase) { runCcHostBinaryTestCase(t, tc) } -func runCcBinaryTestCase(t *testing.T, tc ccBinaryBp2buildTestCase) { +func runCcBinaryTestCase(t *testing.T, testCase ccBinaryBp2buildTestCase) { t.Helper() moduleTypeUnderTest := "cc_binary" - testCase := bp2buildTestCase{ - expectedBazelTargets: generateBazelTargetsForTest(tc.targets), - moduleTypeUnderTest: moduleTypeUnderTest, - moduleTypeUnderTestFactory: cc.BinaryFactory, - description: fmt.Sprintf("%s %s", moduleTypeUnderTest, tc.description), - blueprint: binaryReplacer.Replace(tc.blueprint), - } - t.Run(testCase.description, func(t *testing.T) { + + description := fmt.Sprintf("%s %s", moduleTypeUnderTest, testCase.description) + t.Run(description, func(t *testing.T) { t.Helper() - runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase) + runBp2BuildTestCase(t, registerCcBinaryModuleTypes, bp2buildTestCase{ + expectedBazelTargets: generateBazelTargetsForTest(testCase.targets, android.DeviceSupported), + moduleTypeUnderTest: moduleTypeUnderTest, + moduleTypeUnderTestFactory: cc.BinaryFactory, + description: description, + blueprint: binaryReplacer.Replace(testCase.blueprint), + }) }) } -func runCcHostBinaryTestCase(t *testing.T, tc ccBinaryBp2buildTestCase) { +func runCcHostBinaryTestCase(t *testing.T, testCase ccBinaryBp2buildTestCase) { t.Helper() - testCase := tc - for i, tar := range testCase.targets { - switch tar.typ { - case "cc_binary", "proto_library", "cc_lite_proto_library", "genlex": - tar.attrs["target_compatible_with"] = `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - } - testCase.targets[i] = tar - } moduleTypeUnderTest := "cc_binary_host" - t.Run(testCase.description, func(t *testing.T) { + description := fmt.Sprintf("%s %s", moduleTypeUnderTest, testCase.description) + t.Run(description, func(t *testing.T) { runBp2BuildTestCase(t, registerCcBinaryModuleTypes, bp2buildTestCase{ - expectedBazelTargets: generateBazelTargetsForTest(testCase.targets), + expectedBazelTargets: generateBazelTargetsForTest(testCase.targets, android.HostSupported), moduleTypeUnderTest: moduleTypeUnderTest, moduleTypeUnderTestFactory: cc.BinaryHostFactory, - description: fmt.Sprintf("%s %s", moduleTypeUnderTest, tc.description), + description: description, blueprint: hostBinaryReplacer.Replace(testCase.blueprint), }) }) diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index a0bc9e7b4..b7de45273 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -2278,6 +2278,7 @@ func TestCcLibraryDisabledArchAndTarget(t *testing.T) { blueprint: soongCcProtoPreamble + `cc_library { name: "foo", srcs: ["foo.cpp"], + host_supported: true, target: { darwin: { enabled: false, @@ -2313,6 +2314,7 @@ func TestCcLibraryDisabledArchAndTargetWithDefault(t *testing.T) { name: "foo", srcs: ["foo.cpp"], enabled: false, + host_supported: true, target: { darwin: { enabled: true, @@ -2377,6 +2379,7 @@ func TestCcLibraryStaticDisabledForSomeArch(t *testing.T) { moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcProtoPreamble + `cc_library { name: "foo", + host_supported: true, srcs: ["foo.cpp"], shared: { enabled: false diff --git a/bp2build/genrule_conversion_test.go b/bp2build/genrule_conversion_test.go index 9244b9922..45048924e 100644 --- a/bp2build/genrule_conversion_test.go +++ b/bp2build/genrule_conversion_test.go @@ -56,6 +56,7 @@ func TestGenruleCliVariableReplacement(t *testing.T) { moduleType string factory android.ModuleFactory genDir string + hod android.HostOrDeviceSupported }{ { moduleType: "genrule", @@ -66,16 +67,19 @@ func TestGenruleCliVariableReplacement(t *testing.T) { moduleType: "cc_genrule", factory: cc.GenRuleFactory, genDir: "$(RULEDIR)", + hod: android.DeviceSupported, }, { moduleType: "java_genrule", factory: java.GenRuleFactory, genDir: "$(RULEDIR)", + hod: android.DeviceSupported, }, { moduleType: "java_genrule_host", factory: java.GenRuleFactoryHost, genDir: "$(RULEDIR)", + hod: android.HostSupported, }, } @@ -104,15 +108,8 @@ func TestGenruleCliVariableReplacement(t *testing.T) { "tools": `[":foo.tool"]`, } - if tc.moduleType == "java_genrule_host" { - moduleAttrs["target_compatible_with"] = `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - } - expectedBazelTargets := []string{ - makeBazelTarget("genrule", "foo", moduleAttrs), + makeBazelTargetHostOrDevice("genrule", "foo", moduleAttrs, tc.hod), } t.Run(tc.moduleType, func(t *testing.T) { @@ -131,6 +128,7 @@ func TestGenruleLocationsLabel(t *testing.T) { testCases := []struct { moduleType string factory android.ModuleFactory + hod android.HostOrDeviceSupported }{ { moduleType: "genrule", @@ -139,14 +137,17 @@ func TestGenruleLocationsLabel(t *testing.T) { { moduleType: "cc_genrule", factory: cc.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule", factory: java.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule_host", factory: java.GenRuleFactoryHost, + hod: android.HostSupported, }, } @@ -183,18 +184,9 @@ func TestGenruleLocationsLabel(t *testing.T) { "srcs": `["foo_tool.in"]`, } - if tc.moduleType == "java_genrule_host" { - compatibilityAttrs := `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - fooAttrs["target_compatible_with"] = compatibilityAttrs - fooToolsAttrs["target_compatible_with"] = compatibilityAttrs - } - expectedBazelTargets := []string{ - makeBazelTarget("genrule", "foo", fooAttrs), - makeBazelTarget("genrule", "foo.tools", fooToolsAttrs), + makeBazelTargetHostOrDevice("genrule", "foo", fooAttrs, tc.hod), + makeBazelTargetHostOrDevice("genrule", "foo.tools", fooToolsAttrs, tc.hod), } t.Run(tc.moduleType, func(t *testing.T) { @@ -213,6 +205,7 @@ func TestGenruleLocationsAbsoluteLabel(t *testing.T) { testCases := []struct { moduleType string factory android.ModuleFactory + hod android.HostOrDeviceSupported }{ { moduleType: "genrule", @@ -221,14 +214,17 @@ func TestGenruleLocationsAbsoluteLabel(t *testing.T) { { moduleType: "cc_genrule", factory: cc.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule", factory: java.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule_host", factory: java.GenRuleFactoryHost, + hod: android.HostSupported, }, } @@ -249,15 +245,8 @@ func TestGenruleLocationsAbsoluteLabel(t *testing.T) { "tools": `["//other:foo.tool"]`, } - if tc.moduleType == "java_genrule_host" { - moduleAttrs["target_compatible_with"] = `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - } - expectedBazelTargets := []string{ - makeBazelTarget("genrule", "foo", moduleAttrs), + makeBazelTargetHostOrDevice("genrule", "foo", moduleAttrs, tc.hod), } t.Run(tc.moduleType, func(t *testing.T) { @@ -277,6 +266,7 @@ func TestGenruleSrcsLocationsAbsoluteLabel(t *testing.T) { testCases := []struct { moduleType string factory android.ModuleFactory + hod android.HostOrDeviceSupported }{ { moduleType: "genrule", @@ -285,14 +275,17 @@ func TestGenruleSrcsLocationsAbsoluteLabel(t *testing.T) { { moduleType: "cc_genrule", factory: cc.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule", factory: java.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule_host", factory: java.GenRuleFactoryHost, + hod: android.HostSupported, }, } @@ -313,15 +306,8 @@ func TestGenruleSrcsLocationsAbsoluteLabel(t *testing.T) { "tools": `["//other:foo.tool"]`, } - if tc.moduleType == "java_genrule_host" { - moduleAttrs["target_compatible_with"] = `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - } - expectedBazelTargets := []string{ - makeBazelTarget("genrule", "foo", moduleAttrs), + makeBazelTargetHostOrDevice("genrule", "foo", moduleAttrs, tc.hod), } t.Run(tc.moduleType, func(t *testing.T) { @@ -341,6 +327,7 @@ func TestGenruleLocationLabelShouldSubstituteFirstToolLabel(t *testing.T) { testCases := []struct { moduleType string factory android.ModuleFactory + hod android.HostOrDeviceSupported }{ { moduleType: "genrule", @@ -349,14 +336,17 @@ func TestGenruleLocationLabelShouldSubstituteFirstToolLabel(t *testing.T) { { moduleType: "cc_genrule", factory: cc.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule", factory: java.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule_host", factory: java.GenRuleFactoryHost, + hod: android.HostSupported, }, } @@ -380,15 +370,8 @@ func TestGenruleLocationLabelShouldSubstituteFirstToolLabel(t *testing.T) { ]`, } - if tc.moduleType == "java_genrule_host" { - moduleAttrs["target_compatible_with"] = `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - } - expectedBazelTargets := []string{ - makeBazelTarget("genrule", "foo", moduleAttrs), + makeBazelTargetHostOrDevice("genrule", "foo", moduleAttrs, tc.hod), } t.Run(tc.moduleType, func(t *testing.T) { @@ -408,6 +391,7 @@ func TestGenruleLocationsLabelShouldSubstituteFirstToolLabel(t *testing.T) { testCases := []struct { moduleType string factory android.ModuleFactory + hod android.HostOrDeviceSupported }{ { moduleType: "genrule", @@ -416,14 +400,17 @@ func TestGenruleLocationsLabelShouldSubstituteFirstToolLabel(t *testing.T) { { moduleType: "cc_genrule", factory: cc.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule", factory: java.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule_host", factory: java.GenRuleFactoryHost, + hod: android.HostSupported, }, } @@ -447,15 +434,8 @@ func TestGenruleLocationsLabelShouldSubstituteFirstToolLabel(t *testing.T) { ]`, } - if tc.moduleType == "java_genrule_host" { - moduleAttrs["target_compatible_with"] = `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - } - expectedBazelTargets := []string{ - makeBazelTarget("genrule", "foo", moduleAttrs), + makeBazelTargetHostOrDevice("genrule", "foo", moduleAttrs, tc.hod), } t.Run(tc.moduleType, func(t *testing.T) { @@ -475,6 +455,7 @@ func TestGenruleWithoutToolsOrToolFiles(t *testing.T) { testCases := []struct { moduleType string factory android.ModuleFactory + hod android.HostOrDeviceSupported }{ { moduleType: "genrule", @@ -483,14 +464,17 @@ func TestGenruleWithoutToolsOrToolFiles(t *testing.T) { { moduleType: "cc_genrule", factory: cc.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule", factory: java.GenRuleFactory, + hod: android.DeviceSupported, }, { moduleType: "java_genrule_host", factory: java.GenRuleFactoryHost, + hod: android.HostSupported, }, } @@ -509,15 +493,8 @@ func TestGenruleWithoutToolsOrToolFiles(t *testing.T) { "srcs": `["foo.in"]`, } - if tc.moduleType == "java_genrule_host" { - moduleAttrs["target_compatible_with"] = `select({ - "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], - "//conditions:default": [], - })` - } - expectedBazelTargets := []string{ - makeBazelTarget("genrule", "foo", moduleAttrs), + makeBazelTargetHostOrDevice("genrule", "foo", moduleAttrs, tc.hod), } t.Run(tc.moduleType, func(t *testing.T) { @@ -549,7 +526,7 @@ genrule { } `, expectedBazelTargets: []string{ - makeBazelTarget("genrule", "gen", attrNameToString{ + makeBazelTargetNoRestrictions("genrule", "gen", attrNameToString{ "cmd": `"do-something $(SRCS) $(OUTS)"`, "outs": `["out"]`, "srcs": `["in1"]`, @@ -574,7 +551,7 @@ genrule { } `, expectedBazelTargets: []string{ - makeBazelTarget("genrule", "gen", attrNameToString{ + makeBazelTargetNoRestrictions("genrule", "gen", attrNameToString{ "cmd": `"do-something $(SRCS) $(OUTS)"`, "outs": `[ "out-from-defaults", @@ -607,7 +584,7 @@ genrule { } `, expectedBazelTargets: []string{ - makeBazelTarget("genrule", "gen", attrNameToString{ + makeBazelTargetNoRestrictions("genrule", "gen", attrNameToString{ "cmd": `"cp $(SRCS) $(OUTS)"`, "outs": `["out"]`, "srcs": `["in1"]`, @@ -644,7 +621,7 @@ genrule { } `, expectedBazelTargets: []string{ - makeBazelTarget("genrule", "gen", attrNameToString{ + makeBazelTargetNoRestrictions("genrule", "gen", attrNameToString{ "cmd": `"cmd1 $(SRCS) $(OUTS)"`, "outs": `[ "out-from-3", diff --git a/bp2build/soong_config_module_type_conversion_test.go b/bp2build/soong_config_module_type_conversion_test.go index b1e1fb2ee..8460caeb3 100644 --- a/bp2build/soong_config_module_type_conversion_test.go +++ b/bp2build/soong_config_module_type_conversion_test.go @@ -49,6 +49,7 @@ soong_config_module_type { custom_cc_library_static { name: "foo", bazel_module: { bp2build_available: true }, + host_supported: true, soong_config_variables: { feature1: { conditions_default: { @@ -94,6 +95,7 @@ soong_config_module_type_import { custom_cc_library_static { name: "foo", bazel_module: { bp2build_available: true }, + host_supported: true, soong_config_variables: { feature1: { conditions_default: { @@ -141,6 +143,7 @@ soong_config_module_type { custom_cc_library_static { name: "foo", bazel_module: { bp2build_available: true }, + host_supported: true, soong_config_variables: { board: { soc_a: { @@ -200,6 +203,7 @@ soong_config_module_type { custom_cc_library_static { name: "foo", bazel_module: { bp2build_available: true }, + host_supported: true, soong_config_variables: { feature1: { conditions_default: { @@ -268,6 +272,7 @@ soong_config_module_type { custom_cc_library_static { name: "foo", bazel_module: { bp2build_available: true }, + host_supported: true, soong_config_variables: { board: { soc_a: { @@ -356,6 +361,7 @@ cc_library_static { name: "lib", defaults: ["foo_defaults_2"], bazel_module: { bp2build_available: true }, + host_supported: true, } ` @@ -429,12 +435,14 @@ cc_library_static { name: "lib", defaults: ["foo_defaults", "bar_defaults"], bazel_module: { bp2build_available: true }, + host_supported: true, } cc_library_static { name: "lib2", defaults: ["bar_defaults", "foo_defaults"], bazel_module: { bp2build_available: true }, + host_supported: true, } ` @@ -550,6 +558,7 @@ cc_library_static { name: "lib", defaults: ["foo_defaults", "qux_defaults"], bazel_module: { bp2build_available: true }, + host_supported: true, } ` @@ -615,6 +624,7 @@ library_linking_strategy_cc_defaults { library_linking_strategy_cc_defaults { name: "library_linking_strategy_merged_defaults", defaults: ["library_linking_strategy_lib_a_defaults"], + host_supported: true, soong_config_variables: { library_linking_strategy: { prefer_static: { @@ -714,6 +724,7 @@ library_linking_strategy_cc_defaults { cc_binary { name: "library_linking_strategy_sample_binary", + host_supported: true, srcs: ["library_linking_strategy.cc"], defaults: ["library_linking_strategy_sample_defaults"], }` @@ -800,6 +811,7 @@ alphabet_cc_defaults { cc_binary { name: "alphabet_binary", + host_supported: true, srcs: ["main.cc"], defaults: ["alphabet_sample_cc_defaults"], }` @@ -861,6 +873,7 @@ alphabet_cc_defaults { cc_binary { name: "alphabet_binary", srcs: ["main.cc"], + host_supported: true, defaults: ["alphabet_sample_cc_defaults"], enabled: false, arch: { @@ -958,6 +971,7 @@ soong_config_module_type { alphabet_cc_defaults { name: "alphabet_sample_cc_defaults", + host_supported: true, soong_config_variables: { special_build: { enabled: true, diff --git a/bp2build/testing.go b/bp2build/testing.go index 93414956e..580bac4a5 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -213,12 +213,36 @@ func customModuleFactoryBase() android.Module { return module } -func customModuleFactory() android.Module { +func customModuleFactoryHostAndDevice() android.Module { m := customModuleFactoryBase() android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth) return m } +func customModuleFactoryDeviceSupported() android.Module { + m := customModuleFactoryBase() + android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth) + return m +} + +func customModuleFactoryHostSupported() android.Module { + m := customModuleFactoryBase() + android.InitAndroidArchModule(m, android.HostSupported, android.MultilibBoth) + return m +} + +func customModuleFactoryHostAndDeviceDefault() android.Module { + m := customModuleFactoryBase() + android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibBoth) + return m +} + +func customModuleFactoryNeitherHostNorDeviceSupported() android.Module { + m := customModuleFactoryBase() + android.InitAndroidArchModule(m, android.NeitherHostNorDeviceSupported, android.MultilibBoth) + return m +} + type testProps struct { Test_prop struct { Test_string_prop string @@ -355,7 +379,7 @@ func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTa } func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) { - ctx.RegisterModuleType("custom", customModuleFactory) + ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice) ctx.RegisterForBazelConversion() } @@ -369,7 +393,29 @@ func simpleModuleDoNotConvertBp2build(typ, name string) string { type attrNameToString map[string]string -func makeBazelTarget(typ, name string, attrs attrNameToString) string { +func (a attrNameToString) clone() attrNameToString { + newAttrs := make(attrNameToString, len(a)) + for k, v := range a { + newAttrs[k] = v + } + return newAttrs +} + +// makeBazelTargetNoRestrictions returns bazel target build file definition that can be host or +// device specific, or independent of host/device. +func makeBazelTargetHostOrDevice(typ, name string, attrs attrNameToString, hod android.HostOrDeviceSupported) string { + if _, ok := attrs["target_compatible_with"]; !ok { + switch hod { + case android.HostSupported: + attrs["target_compatible_with"] = `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })` + case android.DeviceSupported: + attrs["target_compatible_with"] = `["//build/bazel/platforms/os:android"]` + } + } + attrStrings := make([]string, 0, len(attrs)+1) attrStrings = append(attrStrings, fmt.Sprintf(` name = "%s",`, name)) for _, k := range android.SortedStringKeys(attrs) { @@ -379,3 +425,16 @@ func makeBazelTarget(typ, name string, attrs attrNameToString) string { %s )`, typ, strings.Join(attrStrings, "\n")) } + +// makeBazelTargetNoRestrictions returns bazel target build file definition that does not add a +// target_compatible_with. This is useful for module types like filegroup and genrule that arch not +// arch variant +func makeBazelTargetNoRestrictions(typ, name string, attrs attrNameToString) string { + return makeBazelTargetHostOrDevice(typ, name, attrs, android.HostAndDeviceDefault) +} + +// makeBazelTargetNoRestrictions returns bazel target build file definition that is device specific +// as this is the most common default in Soong. +func makeBazelTarget(typ, name string, attrs attrNameToString) string { + return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported) +}