Refactor code for partitions c srcs
To support protos (and other srcs that generate sources), we need to partition further. Separate out into a separate common function. Bug: 200601772 Test: build/bazel/ci/bp2build.sh Change-Id: I7bf4cd96fd9a9fca4ccb3c96f21a04303201f891
This commit is contained in:
@@ -19,6 +19,9 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
// BazelTargetModuleProperties contain properties and metadata used for
|
||||
@@ -182,76 +185,6 @@ func SubtractStrings(haystack []string, needle []string) []string {
|
||||
return strings
|
||||
}
|
||||
|
||||
// Map a function over all labels in a LabelList.
|
||||
func MapLabelList(mapOver LabelList, mapFn func(string) string) LabelList {
|
||||
var includes []Label
|
||||
for _, inc := range mapOver.Includes {
|
||||
mappedLabel := Label{Label: mapFn(inc.Label), OriginalModuleName: inc.OriginalModuleName}
|
||||
includes = append(includes, mappedLabel)
|
||||
}
|
||||
// mapFn is not applied over excludes, but they are propagated as-is.
|
||||
return LabelList{Includes: includes, Excludes: mapOver.Excludes}
|
||||
}
|
||||
|
||||
// Map a function over all Labels in a LabelListAttribute
|
||||
func MapLabelListAttribute(mapOver LabelListAttribute, mapFn func(string) string) LabelListAttribute {
|
||||
var result LabelListAttribute
|
||||
|
||||
result.Value = MapLabelList(mapOver.Value, mapFn)
|
||||
|
||||
for axis, configToLabels := range mapOver.ConfigurableValues {
|
||||
for config, value := range configToLabels {
|
||||
result.SetSelectValue(axis, config, MapLabelList(value, mapFn))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
// needleFn is not applied over excludes, but they are propagated as-is.
|
||||
return LabelList{Includes: includes, Excludes: haystack.Excludes}
|
||||
}
|
||||
|
||||
// Return all needles in a given haystack, where needleFn is true for needles.
|
||||
func FilterLabelListAttribute(haystack LabelListAttribute, needleFn func(string) bool) LabelListAttribute {
|
||||
result := MakeLabelListAttribute(FilterLabelList(haystack.Value, needleFn))
|
||||
|
||||
for config, selects := range haystack.ConfigurableValues {
|
||||
newSelects := make(labelListSelectValues, len(selects))
|
||||
for k, v := range selects {
|
||||
newSelects[k] = FilterLabelList(v, needleFn)
|
||||
}
|
||||
result.ConfigurableValues[config] = newSelects
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Subtract needle from haystack
|
||||
func SubtractBazelLabelListAttribute(haystack LabelListAttribute, needle LabelListAttribute) LabelListAttribute {
|
||||
result := MakeLabelListAttribute(SubtractBazelLabelList(haystack.Value, needle.Value))
|
||||
|
||||
for config, selects := range haystack.ConfigurableValues {
|
||||
newSelects := make(labelListSelectValues, len(selects))
|
||||
needleSelects := needle.ConfigurableValues[config]
|
||||
|
||||
for k, v := range selects {
|
||||
newSelects[k] = SubtractBazelLabelList(v, needleSelects[k])
|
||||
}
|
||||
result.ConfigurableValues[config] = newSelects
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Subtract needle from haystack
|
||||
func SubtractBazelLabels(haystack []Label, needle []Label) []Label {
|
||||
// This is really a set
|
||||
@@ -624,6 +557,144 @@ func (lla *LabelListAttribute) ResolveExcludes() {
|
||||
}
|
||||
}
|
||||
|
||||
// OtherModuleContext is a limited context that has methods with information about other modules.
|
||||
type OtherModuleContext interface {
|
||||
ModuleFromName(name string) (blueprint.Module, bool)
|
||||
OtherModuleType(m blueprint.Module) string
|
||||
OtherModuleName(m blueprint.Module) string
|
||||
OtherModuleDir(m blueprint.Module) string
|
||||
ModuleErrorf(fmt string, args ...interface{})
|
||||
}
|
||||
|
||||
// LabelMapper is a function that takes a OtherModuleContext and returns a (potentially changed)
|
||||
// label and whether it was changed.
|
||||
type LabelMapper func(OtherModuleContext, string) (string, bool)
|
||||
|
||||
// LabelPartition contains descriptions of a partition for labels
|
||||
type LabelPartition struct {
|
||||
// Extensions to include in this partition
|
||||
Extensions []string
|
||||
// LabelMapper is a function that can map a label to a new label, and indicate whether to include
|
||||
// the mapped label in the partition
|
||||
LabelMapper LabelMapper
|
||||
// Whether to store files not included in any other partition in a group of LabelPartitions
|
||||
// Only one partition in a group of LabelPartitions can enabled Keep_remainder
|
||||
Keep_remainder bool
|
||||
}
|
||||
|
||||
// LabelPartitions is a map of partition name to a LabelPartition describing the elements of the
|
||||
// partition
|
||||
type LabelPartitions map[string]LabelPartition
|
||||
|
||||
// filter returns a pointer to a label if the label should be included in the partition or nil if
|
||||
// not.
|
||||
func (lf LabelPartition) filter(ctx OtherModuleContext, label Label) *Label {
|
||||
if lf.LabelMapper != nil {
|
||||
if newLabel, changed := lf.LabelMapper(ctx, label.Label); changed {
|
||||
return &Label{newLabel, label.OriginalModuleName}
|
||||
}
|
||||
}
|
||||
for _, ext := range lf.Extensions {
|
||||
if strings.HasSuffix(label.Label, ext) {
|
||||
return &label
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PartitionToLabelListAttribute is map of partition name to a LabelListAttribute
|
||||
type PartitionToLabelListAttribute map[string]LabelListAttribute
|
||||
|
||||
type partitionToLabelList map[string]*LabelList
|
||||
|
||||
func (p partitionToLabelList) appendIncludes(partition string, label Label) {
|
||||
if _, ok := p[partition]; !ok {
|
||||
p[partition] = &LabelList{}
|
||||
}
|
||||
p[partition].Includes = append(p[partition].Includes, label)
|
||||
}
|
||||
|
||||
func (p partitionToLabelList) excludes(partition string, excludes []Label) {
|
||||
if _, ok := p[partition]; !ok {
|
||||
p[partition] = &LabelList{}
|
||||
}
|
||||
p[partition].Excludes = excludes
|
||||
}
|
||||
|
||||
// PartitionLabelListAttribute partitions a LabelListAttribute into the requested partitions
|
||||
func PartitionLabelListAttribute(ctx OtherModuleContext, lla *LabelListAttribute, partitions LabelPartitions) PartitionToLabelListAttribute {
|
||||
ret := PartitionToLabelListAttribute{}
|
||||
var partitionNames []string
|
||||
// Stored as a pointer to distinguish nil (no remainder partition) from empty string partition
|
||||
var remainderPartition *string
|
||||
for p, f := range partitions {
|
||||
partitionNames = append(partitionNames, p)
|
||||
if f.Keep_remainder {
|
||||
if remainderPartition != nil {
|
||||
panic("only one partition can store the remainder")
|
||||
}
|
||||
// If we take the address of p in a loop, we'll end up with the last value of p in
|
||||
// remainderPartition, we want the requested partition
|
||||
capturePartition := p
|
||||
remainderPartition = &capturePartition
|
||||
}
|
||||
}
|
||||
|
||||
partitionLabelList := func(axis ConfigurationAxis, config string) {
|
||||
value := lla.SelectValue(axis, config)
|
||||
partitionToLabels := partitionToLabelList{}
|
||||
for _, item := range value.Includes {
|
||||
wasFiltered := false
|
||||
var inPartition *string
|
||||
for partition, f := range partitions {
|
||||
filtered := f.filter(ctx, item)
|
||||
if filtered == nil {
|
||||
// did not match this filter, keep looking
|
||||
continue
|
||||
}
|
||||
wasFiltered = true
|
||||
partitionToLabels.appendIncludes(partition, *filtered)
|
||||
// don't need to check other partitions if this filter used the item,
|
||||
// continue checking if mapped to another name
|
||||
if *filtered == item {
|
||||
if inPartition != nil {
|
||||
ctx.ModuleErrorf("%q was found in multiple partitions: %q, %q", item.Label, *inPartition, partition)
|
||||
}
|
||||
capturePartition := partition
|
||||
inPartition = &capturePartition
|
||||
}
|
||||
}
|
||||
|
||||
// if not specified in a partition, add to remainder partition if one exists
|
||||
if !wasFiltered && remainderPartition != nil {
|
||||
partitionToLabels.appendIncludes(*remainderPartition, item)
|
||||
}
|
||||
}
|
||||
|
||||
// ensure empty lists are maintained
|
||||
if value.Excludes != nil {
|
||||
for _, partition := range partitionNames {
|
||||
partitionToLabels.excludes(partition, value.Excludes)
|
||||
}
|
||||
}
|
||||
|
||||
for partition, list := range partitionToLabels {
|
||||
val := ret[partition]
|
||||
(&val).SetSelectValue(axis, config, *list)
|
||||
ret[partition] = val
|
||||
}
|
||||
}
|
||||
|
||||
partitionLabelList(NoConfigAxis, "")
|
||||
for axis, configToList := range lla.ConfigurableValues {
|
||||
for config, _ := range configToList {
|
||||
partitionLabelList(axis, config)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// StringListAttribute corresponds to the string_list Bazel attribute type with
|
||||
// support for additional metadata, like configurations.
|
||||
type StringListAttribute struct {
|
||||
|
Reference in New Issue
Block a user