diff --git a/bazel/properties.go b/bazel/properties.go index 813a7012c..b9d6ead59 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -140,7 +140,6 @@ func SubtractStrings(haystack []string, needle []string) []string { // Return all needles in a given haystack, where needleFn is true for needles. func FilterLabelList(haystack LabelList, needleFn func(string) bool) LabelList { var includes []Label - for _, inc := range haystack.Includes { if needleFn(inc.Label) { includes = append(includes, inc) diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go index 388c8cf66..6bdfc0e69 100644 --- a/bp2build/build_conversion.go +++ b/bp2build/build_conversion.go @@ -445,7 +445,7 @@ func prettyPrint(propertyValue reflect.Value, indent int) (string, error) { return prettyPrint(propertyValue.Elem(), indent) case reflect.Slice: if propertyValue.Len() == 0 { - return "", nil + return "[]", nil } if propertyValue.Len() == 1 { diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 833ceba09..770925466 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -850,6 +850,84 @@ cc_library_static { }) } +func TestCcLibraryStaticOneArchEmpty(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static one arch empty", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build}, + filesystem: map[string]string{ + "common.cc": "", + "foo-no-arm.cc": "", + "foo-excluded.cc": "", + }, + blueprint: soongCcLibraryStaticPreamble + ` +cc_library_static { + name: "foo_static", + srcs: ["common.cc", "foo-*.cc"], + exclude_srcs: ["foo-excluded.cc"], + arch: { + arm: { exclude_srcs: ["foo-no-arm.cc"] }, + }, +}`, + expectedBazelTargets: []string{`cc_library_static( + name = "foo_static", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + srcs = ["common.cc"] + select({ + "//build/bazel/platforms/arch:arm": [], + "//conditions:default": ["foo-no-arm.cc"], + }), +)`}, + }) +} + +func TestCcLibraryStaticOneArchEmptyOtherSet(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static one arch empty other set", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build}, + filesystem: map[string]string{ + "common.cc": "", + "foo-no-arm.cc": "", + "x86-only.cc": "", + "foo-excluded.cc": "", + }, + blueprint: soongCcLibraryStaticPreamble + ` +cc_library_static { + name: "foo_static", + srcs: ["common.cc", "foo-*.cc"], + exclude_srcs: ["foo-excluded.cc"], + arch: { + arm: { exclude_srcs: ["foo-no-arm.cc"] }, + x86: { srcs: ["x86-only.cc"] }, + }, +}`, + expectedBazelTargets: []string{`cc_library_static( + name = "foo_static", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + srcs = ["common.cc"] + select({ + "//build/bazel/platforms/arch:arm": [], + "//build/bazel/platforms/arch:x86": [ + "foo-no-arm.cc", + "x86-only.cc", + ], + "//conditions:default": ["foo-no-arm.cc"], + }), +)`}, + }) +} + func TestCcLibraryStaticMultipleDepSameName(t *testing.T) { runCcLibraryStaticTestCase(t, bp2buildTestCase{ description: "cc_library_static multiple dep same name panic", diff --git a/bp2build/configurability.go b/bp2build/configurability.go index c13e737c0..7e1a2989d 100644 --- a/bp2build/configurability.go +++ b/bp2build/configurability.go @@ -128,32 +128,55 @@ func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects if !list.HasConfigurableValues() { return value, []selects{} } + var ret []selects archSelects := map[string]reflect.Value{} for arch, selectKey := range bazel.PlatformArchMap { - archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch).Includes) + if use, value := labelListSelectValue(selectKey, list.GetValueForArch(arch)); use { + archSelects[selectKey] = value + } + } + if len(archSelects) > 0 { + ret = append(ret, archSelects) } osSelects := map[string]reflect.Value{} - osArchSelects := make([]selects, 0) + osArchSelects := []selects{} for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) { selectKey := bazel.PlatformOsMap[os] - osSelects[selectKey] = reflect.ValueOf(list.GetOsValueForTarget(os).Includes) - archSelects := make(map[string]reflect.Value) + if use, value := labelListSelectValue(selectKey, list.GetOsValueForTarget(os)); use { + osSelects[selectKey] = value + } + selects := make(map[string]reflect.Value) // TODO(b/187530594): Should we also check arch=CONDITIOSN_DEFAULT? (not in AllArches) for _, arch := range bazel.AllArches { target := os + "_" + arch selectKey := bazel.PlatformTargetMap[target] - archSelects[selectKey] = reflect.ValueOf(list.GetOsArchValueForTarget(os, arch).Includes) + if use, value := labelListSelectValue(selectKey, list.GetOsArchValueForTarget(os, arch)); use { + selects[selectKey] = value + } + } + if len(selects) > 0 { + osArchSelects = append(osArchSelects, selects) } - osArchSelects = append(osArchSelects, archSelects) } + if len(osSelects) > 0 { + ret = append(ret, osSelects) + } + ret = append(ret, osArchSelects...) - var selects []selects - selects = append(selects, archSelects) - selects = append(selects, osSelects) - selects = append(selects, osArchSelects...) - return value, selects + return value, ret +} + +func labelListSelectValue(selectKey string, list bazel.LabelList) (bool, reflect.Value) { + if selectKey == bazel.ConditionsDefaultSelectKey || len(list.Includes) > 0 { + return true, reflect.ValueOf(list.Includes) + } else if len(list.Excludes) > 0 { + // if there is still an excludes -- we need to have an empty list for this select & use the + // value in conditions default Includes + return true, reflect.ValueOf([]string{}) + } + return false, reflect.Zero(reflect.TypeOf([]string{})) } // prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain diff --git a/cc/bp2build.go b/cc/bp2build.go index 711410c39..5d024f865 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -421,7 +421,9 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul if baseCompilerProps, ok := osProps.Properties.(*BaseCompilerProperties); ok { srcsList := parseSrcs(baseCompilerProps) // TODO(b/186153868): add support for os-specific srcs and exclude_srcs - srcs.SetOsValueForTarget(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList)) + if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { + srcs.SetOsValueForTarget(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList)) + } copts.SetOsValueForTarget(os.Name, parseCopts(baseCompilerProps)) asFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Asflags)) conlyFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags)) @@ -431,7 +433,9 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul if baseCompilerProps, ok := archProps.(*BaseCompilerProperties); ok { srcsList := parseSrcs(baseCompilerProps) // TODO(b/186153868): add support for os-specific srcs and exclude_srcs - srcs.SetOsArchValueForTarget(os.Name, arch.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList)) + if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { + srcs.SetOsArchValueForTarget(os.Name, arch.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList)) + } copts.SetOsArchValueForTarget(os.Name, arch.Name, parseCopts(baseCompilerProps)) asFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Asflags)) conlyFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags))