Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74deed44 authored by Liz Kammer's avatar Liz Kammer
Browse files

Extract function to handle configurable excludes

This allows it to be used for other modules types and other properties
(e.g. static_libs & exclude_static_libs).

Test: go test soong tests
Bug: 188497994
Change-Id: I40ab16e3b540ece0a6684558b32f7e8e25df6f24
parent 9abd62d1
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ const (
	// This is consistently named "conditions_default" to mirror the Soong
	// config variable default key in an Android.bp file, although there's no
	// integration with Soong config variables (yet).
	ConditionsDefault = "conditions_default"
	conditionsDefault = "conditions_default"

	ConditionsDefaultSelectKey = "//conditions:default"

@@ -76,7 +76,7 @@ var (
		archArm64:         "//build/bazel/platforms/arch:arm64",
		archX86:           "//build/bazel/platforms/arch:x86",
		archX86_64:        "//build/bazel/platforms/arch:x86_64",
		ConditionsDefault: ConditionsDefaultSelectKey, // The default condition of as arch select map.
		conditionsDefault: ConditionsDefaultSelectKey, // The default condition of as arch select map.
	}

	// A map of target operating systems to the Bazel label of the
@@ -88,7 +88,7 @@ var (
		osLinux:           "//build/bazel/platforms/os:linux",
		osLinuxBionic:     "//build/bazel/platforms/os:linux_bionic",
		osWindows:         "//build/bazel/platforms/os:windows",
		ConditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
		conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
	}

	platformOsArchMap = map[string]string{
@@ -105,7 +105,7 @@ var (
		osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
		osArchWindowsX86:        "//build/bazel/platforms/os_arch:windows_x86",
		osArchWindowsX86_64:     "//build/bazel/platforms/os_arch:windows_x86_64",
		ConditionsDefault:       ConditionsDefaultSelectKey, // The default condition of an os select map.
		conditionsDefault:       ConditionsDefaultSelectKey, // The default condition of an os select map.
	}
)

@@ -168,7 +168,7 @@ func (ct configurationType) SelectKey(config string) string {
	case osArch:
		return platformOsArchMap[config]
	case productVariables:
		if config == ConditionsDefault {
		if config == conditionsDefault {
			return ConditionsDefaultSelectKey
		}
		return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config))
+40 −0
Original line number Diff line number Diff line
@@ -68,6 +68,13 @@ func (ll *LabelList) IsNil() bool {
	return ll.Includes == nil && ll.Excludes == nil
}

func (ll *LabelList) deepCopy() LabelList {
	return LabelList{
		Includes: ll.Includes[:],
		Excludes: ll.Excludes[:],
	}
}

// uniqueParentDirectories returns a list of the unique parent directories for
// all files in ll.Includes.
func (ll *LabelList) uniqueParentDirectories() []string {
@@ -469,6 +476,39 @@ func (lla LabelListAttribute) HasConfigurableValues() bool {
	return len(lla.ConfigurableValues) > 0
}

// ResolveExcludes handles excludes across the various axes, ensuring that items are removed from
// the base value and included in default values as appropriate.
func (lla *LabelListAttribute) ResolveExcludes() {
	for axis, configToLabels := range lla.ConfigurableValues {
		baseLabels := lla.Value.deepCopy()
		for config, val := range configToLabels {
			// Exclude config-specific excludes from base value
			lla.Value = SubtractBazelLabelList(lla.Value, LabelList{Includes: val.Excludes})

			// add base values to config specific to add labels excluded by others in this axis
			// then remove all config-specific excludes
			allLabels := baseLabels.deepCopy()
			allLabels.Append(val)
			lla.ConfigurableValues[axis][config] = SubtractBazelLabelList(allLabels, LabelList{Includes: val.Excludes})
		}

		// After going through all configs, delete the duplicates in the config
		// values that are already in the base Value.
		for config, val := range configToLabels {
			lla.ConfigurableValues[axis][config] = SubtractBazelLabelList(val, lla.Value)
		}

		// Now that the Value list is finalized for this axis, compare it with the original
		// list, and put the difference into the default condition for the axis.
		lla.ConfigurableValues[axis][conditionsDefault] = SubtractBazelLabelList(baseLabels, lla.Value)

		// if everything ends up without includes, just delete the axis
		if !lla.ConfigurableValues[axis].HasConfigurableValues() {
			delete(lla.ConfigurableValues, axis)
		}
	}
}

// StringListAttribute corresponds to the string_list Bazel attribute type with
// support for additional metadata, like configurations.
type StringListAttribute struct {
+88 −0
Original line number Diff line number Diff line
@@ -205,3 +205,91 @@ func TestUniqueSortedBazelLabelList(t *testing.T) {
		}
	}
}

func makeLabels(labels ...string) []Label {
	var ret []Label
	for _, l := range labels {
		ret = append(ret, Label{Label: l})
	}
	return ret
}

func makeLabelList(includes, excludes []string) LabelList {
	return LabelList{
		Includes: makeLabels(includes...),
		Excludes: makeLabels(excludes...),
	}
}

func TestResolveExcludes(t *testing.T) {
	attr := LabelListAttribute{
		Value: makeLabelList(
			[]string{
				"all_include",
				"arm_exclude",
				"android_exclude",
			},
			[]string{"all_exclude"},
		),
		ConfigurableValues: configurableLabelLists{
			ArchConfigurationAxis: labelListSelectValues{
				"arm": makeLabelList([]string{}, []string{"arm_exclude"}),
				"x86": makeLabelList([]string{"x86_include"}, []string{}),
			},
			OsConfigurationAxis: labelListSelectValues{
				"android": makeLabelList([]string{}, []string{"android_exclude"}),
				"linux":   makeLabelList([]string{"linux_include"}, []string{}),
			},
			OsArchConfigurationAxis: labelListSelectValues{
				"linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
			},
			ProductVariableConfigurationAxis("a"): labelListSelectValues{
				"a": makeLabelList([]string{}, []string{"not_in_value"}),
			},
		},
	}

	attr.ResolveExcludes()

	expectedBaseIncludes := []Label{Label{Label: "all_include"}}
	if !reflect.DeepEqual(expectedBaseIncludes, attr.Value.Includes) {
		t.Errorf("Expected Value includes %q, got %q", attr.Value.Includes, expectedBaseIncludes)
	}
	var nilLabels []Label
	expectedConfiguredIncludes := map[ConfigurationAxis]map[string][]Label{
		ArchConfigurationAxis: map[string][]Label{
			"arm":                nilLabels,
			"x86":                makeLabels("arm_exclude", "x86_include"),
			"conditions_default": makeLabels("arm_exclude"),
		},
		OsConfigurationAxis: map[string][]Label{
			"android":            nilLabels,
			"linux":              makeLabels("android_exclude", "linux_include"),
			"conditions_default": makeLabels("android_exclude"),
		},
		OsArchConfigurationAxis: map[string][]Label{
			"linux_x86":          makeLabels("linux_x86_include"),
			"conditions_default": nilLabels,
		},
	}
	for _, axis := range attr.SortedConfigurationAxes() {
		if _, ok := expectedConfiguredIncludes[axis]; !ok {
			t.Errorf("Found unexpected axis %s", axis)
			continue
		}
		expectedForAxis := expectedConfiguredIncludes[axis]
		gotForAxis := attr.ConfigurableValues[axis]
		if len(expectedForAxis) != len(gotForAxis) {
			t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
		}
		for config, value := range gotForAxis {
			if expected, ok := expectedForAxis[config]; ok {
				if !reflect.DeepEqual(expected, value.Includes) {
					t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value.Includes)
				}
			} else {
				t.Errorf("Got unexpected config %q for %s", config, axis)
			}
		}
	}
}
+3 −40
Original line number Diff line number Diff line
@@ -372,29 +372,15 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
		return copts
	}

	// baseSrcs contain the list of src files that are used for every configuration.
	var baseSrcs []string
	// baseExcludeSrcs contain the list of src files that are excluded for every configuration.
	var baseExcludeSrcs []string
	// baseSrcsLabelList is a clone of the base srcs LabelList, used for computing the
	// arch or os specific srcs later.
	var baseSrcsLabelList bazel.LabelList

	// Parse srcs from an arch or OS's props value, taking the base srcs and
	// exclude srcs into account.
	// Parse srcs from an arch or OS's props value.
	parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
		// Combine the base srcs and arch-specific srcs
		allSrcs := append(baseSrcs, baseCompilerProps.Srcs...)
		// Add srcs-like dependencies such as generated files.
		// First create a LabelList containing these dependencies, then merge the values with srcs.
		generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
		generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)

		generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)

		// Combine the base exclude_srcs and configuration-specific exclude_srcs
		allExcludeSrcs := append(baseExcludeSrcs, baseCompilerProps.Exclude_srcs...)
		allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, allSrcs, allExcludeSrcs)
		allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
		return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
	}

@@ -406,10 +392,6 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
			conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
			cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)

			// Used for arch-specific srcs later.
			baseSrcs = baseCompilerProps.Srcs
			baseSrcsLabelList = parseSrcs(baseCompilerProps)
			baseExcludeSrcs = baseCompilerProps.Exclude_srcs
			break
		}
	}
@@ -433,8 +415,6 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
				if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
					srcsList := parseSrcs(baseCompilerProps)
					srcs.SetSelectValue(axis, config, srcsList)
					// The base srcs value should not contain any arch-specific excludes.
					srcs.SetValue(bazel.SubtractBazelLabelList(srcs.Value, bazel.LabelList{Includes: srcsList.Excludes}))
				}

				copts.SetSelectValue(axis, config, parseCopts(baseCompilerProps))
@@ -445,24 +425,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
		}
	}

	// After going through all archs, delete the duplicate files in the arch
	// values that are already in the base srcs.Value.
	for axis, configToProps := range archVariantCompilerProps {
		for config, props := range configToProps {
			if _, ok := props.(*BaseCompilerProperties); ok {
				// TODO: handle non-arch
				srcs.SetSelectValue(axis, config, bazel.SubtractBazelLabelList(srcs.SelectValue(axis, config), srcs.Value))
			}
		}
	}

	// Now that the srcs.Value list is finalized, compare it with the original
	// list, and put the difference into the default condition for the arch
	// select.
	for axis := range archVariantCompilerProps {
		defaultsSrcs := bazel.SubtractBazelLabelList(baseSrcsLabelList, srcs.Value)
		srcs.SetSelectValue(axis, bazel.ConditionsDefault, defaultsSrcs)
	}
	srcs.ResolveExcludes()

	productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
		"Cflags":   &copts,