Merge changes I4a5ea40c,I40ab16e3 am: 2f26595072

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1726010

Change-Id: I2e034f2bfd4b5e49478e62e49db7643a90512bba
This commit is contained in:
Liz Kammer
2021-06-07 17:03:48 +00:00
committed by Automerger Merge Worker
7 changed files with 388 additions and 81 deletions

View File

@@ -100,6 +100,22 @@ func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) b
return labels return labels
} }
// BazelLabelForModuleDeps expects two lists: modules (containing modules to include in the list),
// and excludes (modules to exclude from the list). Both of these should contain references to other
// modules, ("<module>" or ":<module>"). It returns a Bazel-compatible label list which corresponds
// to dependencies on the module within the given ctx, and the excluded dependencies.
func BazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
moduleLabels := BazelLabelForModuleDeps(ctx, RemoveListFromList(modules, excludes))
if len(excludes) == 0 {
return moduleLabels
}
excludeLabels := BazelLabelForModuleDeps(ctx, excludes)
return bazel.LabelList{
Includes: moduleLabels.Includes,
Excludes: excludeLabels.Includes,
}
}
func BazelLabelForModuleSrcSingle(ctx BazelConversionPathContext, path string) bazel.Label { func BazelLabelForModuleSrcSingle(ctx BazelConversionPathContext, path string) bazel.Label {
return BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes[0] return BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes[0]
} }

View File

@@ -458,12 +458,13 @@ type ProductConfigContext interface {
// with the appropriate ProductConfigVariable. // with the appropriate ProductConfigVariable.
type ProductConfigProperty struct { type ProductConfigProperty struct {
ProductConfigVariable string ProductConfigVariable string
FullConfig string
Property interface{} Property interface{}
} }
// ProductConfigProperties is a map of property name to a slice of ProductConfigProperty such that // ProductConfigProperties is a map of property name to a slice of ProductConfigProperty such that
// all it all product variable-specific versions of a property are easily accessed together // all it all product variable-specific versions of a property are easily accessed together
type ProductConfigProperties map[string][]ProductConfigProperty type ProductConfigProperties map[string]map[string]ProductConfigProperty
// ProductVariableProperties returns a ProductConfigProperties containing only the properties which // ProductVariableProperties returns a ProductConfigProperties containing only the properties which
// have been set for the module in the given context. // have been set for the module in the given context.
@@ -512,11 +513,15 @@ func productVariableValues(variableProps interface{}, suffix string, productConf
// e.g. Asflags, Cflags, Enabled, etc. // e.g. Asflags, Cflags, Enabled, etc.
propertyName := variableValue.Type().Field(j).Name propertyName := variableValue.Type().Field(j).Name
(*productConfigProperties)[propertyName] = append((*productConfigProperties)[propertyName], if (*productConfigProperties)[propertyName] == nil {
ProductConfigProperty{ (*productConfigProperties)[propertyName] = make(map[string]ProductConfigProperty)
ProductConfigVariable: productVariableName + suffix, }
config := productVariableName + suffix
(*productConfigProperties)[propertyName][config] = ProductConfigProperty{
ProductConfigVariable: productVariableName,
FullConfig: config,
Property: property.Interface(), Property: property.Interface(),
}) }
} }
} }
} }

View File

@@ -56,7 +56,7 @@ const (
// This is consistently named "conditions_default" to mirror the Soong // This is consistently named "conditions_default" to mirror the Soong
// config variable default key in an Android.bp file, although there's no // config variable default key in an Android.bp file, although there's no
// integration with Soong config variables (yet). // integration with Soong config variables (yet).
ConditionsDefault = "conditions_default" conditionsDefault = "conditions_default"
ConditionsDefaultSelectKey = "//conditions:default" ConditionsDefaultSelectKey = "//conditions:default"
@@ -76,7 +76,7 @@ var (
archArm64: "//build/bazel/platforms/arch:arm64", archArm64: "//build/bazel/platforms/arch:arm64",
archX86: "//build/bazel/platforms/arch:x86", archX86: "//build/bazel/platforms/arch:x86",
archX86_64: "//build/bazel/platforms/arch:x86_64", 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 // A map of target operating systems to the Bazel label of the
@@ -88,7 +88,7 @@ var (
osLinux: "//build/bazel/platforms/os:linux", osLinux: "//build/bazel/platforms/os:linux",
osLinuxBionic: "//build/bazel/platforms/os:linux_bionic", osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
osWindows: "//build/bazel/platforms/os:windows", 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{ platformOsArchMap = map[string]string{
@@ -105,7 +105,7 @@ var (
osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64", osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86", osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86",
osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64", 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: case osArch:
return platformOsArchMap[config] return platformOsArchMap[config]
case productVariables: case productVariables:
if config == ConditionsDefault { if config == conditionsDefault {
return ConditionsDefaultSelectKey return ConditionsDefaultSelectKey
} }
return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config)) return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config))

View File

@@ -68,6 +68,13 @@ func (ll *LabelList) IsNil() bool {
return ll.Includes == nil && ll.Excludes == nil 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 // uniqueParentDirectories returns a list of the unique parent directories for
// all files in ll.Includes. // all files in ll.Includes.
func (ll *LabelList) uniqueParentDirectories() []string { func (ll *LabelList) uniqueParentDirectories() []string {
@@ -469,6 +476,39 @@ func (lla LabelListAttribute) HasConfigurableValues() bool {
return len(lla.ConfigurableValues) > 0 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 // StringListAttribute corresponds to the string_list Bazel attribute type with
// support for additional metadata, like configurations. // support for additional metadata, like configurations.
type StringListAttribute struct { type StringListAttribute struct {

View File

@@ -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)
}
}
}
}

View File

@@ -985,3 +985,117 @@ func TestCcLibraryLabelAttributeGetTargetProperties(t *testing.T) {
)`}, )`},
}) })
} }
func TestCcLibraryExcludeLibs(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
filesystem: map[string]string{},
blueprint: soongCcLibraryStaticPreamble + `
cc_library {
name: "foo_static",
srcs: ["common.c"],
whole_static_libs: [
"arm_whole_static_lib_excludes",
"malloc_not_svelte_whole_static_lib_excludes"
],
static_libs: [
"arm_static_lib_excludes",
"malloc_not_svelte_static_lib_excludes"
],
shared_libs: [
"arm_shared_lib_excludes",
],
arch: {
arm: {
exclude_shared_libs: [
"arm_shared_lib_excludes",
],
exclude_static_libs: [
"arm_static_lib_excludes",
"arm_whole_static_lib_excludes",
],
},
},
product_variables: {
malloc_not_svelte: {
shared_libs: ["malloc_not_svelte_shared_lib"],
whole_static_libs: ["malloc_not_svelte_whole_static_lib"],
exclude_static_libs: [
"malloc_not_svelte_static_lib_excludes",
"malloc_not_svelte_whole_static_lib_excludes",
],
},
},
}
cc_library {
name: "arm_whole_static_lib_excludes",
bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_whole_static_lib",
bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_whole_static_lib_excludes",
bazel_module: { bp2build_available: false },
}
cc_library {
name: "arm_static_lib_excludes",
bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_static_lib_excludes",
bazel_module: { bp2build_available: false },
}
cc_library {
name: "arm_shared_lib_excludes",
bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_shared_lib",
bazel_module: { bp2build_available: false },
}
`,
expectedBazelTargets: []string{
`cc_library(
name = "foo_static",
copts = [
"-I.",
"-I$(BINDIR)/.",
],
dynamic_deps = select({
"//build/bazel/platforms/arch:arm": [],
"//conditions:default": [":arm_shared_lib_excludes"],
}) + select({
"//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_shared_lib"],
"//conditions:default": [],
}),
implementation_deps = select({
"//build/bazel/platforms/arch:arm": [],
"//conditions:default": [":arm_static_lib_excludes"],
}) + select({
"//build/bazel/product_variables:malloc_not_svelte": [],
"//conditions:default": [":malloc_not_svelte_static_lib_excludes"],
}),
srcs_c = ["common.c"],
whole_archive_deps = select({
"//build/bazel/platforms/arch:arm": [],
"//conditions:default": [":arm_whole_static_lib_excludes"],
}) + select({
"//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib"],
"//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes"],
}),
)`,
},
})
}

View File

@@ -112,6 +112,30 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) {
} }
} }
// product variables only support a limited set of fields, this is the full list of field names
// related to cc module dependency management that are supported.
productVariableDepFields := [4]string{
"Shared_libs",
"Static_libs",
"Exclude_static_libs",
"Whole_static_libs",
}
productVariableProps := android.ProductVariableProperties(ctx)
for _, name := range productVariableDepFields {
props, exists := productVariableProps[name]
if !exists {
continue
}
for _, prop := range props {
if p, ok := prop.Property.([]string); !ok {
ctx.ModuleErrorf("Could not convert product variable %s property", name)
} else {
allDeps = append(allDeps, p...)
}
}
}
ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...) ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
} }
@@ -372,29 +396,15 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
return copts return copts
} }
// baseSrcs contain the list of src files that are used for every configuration. // Parse srcs from an arch or OS's props value.
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.
parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList { 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. // Add srcs-like dependencies such as generated files.
// First create a LabelList containing these dependencies, then merge the values with srcs. // First create a LabelList containing these dependencies, then merge the values with srcs.
generatedHdrsAndSrcs := baseCompilerProps.Generated_headers generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...) generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs) generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
// Combine the base exclude_srcs and configuration-specific exclude_srcs allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
allExcludeSrcs := append(baseExcludeSrcs, baseCompilerProps.Exclude_srcs...)
allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, allSrcs, allExcludeSrcs)
return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList) return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
} }
@@ -406,10 +416,6 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags) conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags) cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
// Used for arch-specific srcs later.
baseSrcs = baseCompilerProps.Srcs
baseSrcsLabelList = parseSrcs(baseCompilerProps)
baseExcludeSrcs = baseCompilerProps.Exclude_srcs
break break
} }
} }
@@ -433,8 +439,6 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
srcsList := parseSrcs(baseCompilerProps) srcsList := parseSrcs(baseCompilerProps)
srcs.SetSelectValue(axis, config, srcsList) 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)) copts.SetSelectValue(axis, config, parseCopts(baseCompilerProps))
@@ -445,24 +449,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
} }
} }
// After going through all archs, delete the duplicate files in the arch srcs.ResolveExcludes()
// 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)
}
productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{ productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
"Cflags": &copts, "Cflags": &copts,
@@ -478,7 +465,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName)) ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
} }
newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable) newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.ProductConfigVariable), prop.ProductConfigVariable, newFlags) attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
} }
} }
} }
@@ -518,37 +505,37 @@ func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
// bp2BuildParseLinkerProps parses the linker properties of a module, including // bp2BuildParseLinkerProps parses the linker properties of a module, including
// configurable attribute values. // configurable attribute values.
func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes { func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
var deps bazel.LabelListAttribute var headerDeps bazel.LabelListAttribute
var staticDeps bazel.LabelListAttribute
var exportedDeps bazel.LabelListAttribute var exportedDeps bazel.LabelListAttribute
var dynamicDeps bazel.LabelListAttribute var dynamicDeps bazel.LabelListAttribute
var wholeArchiveDeps bazel.LabelListAttribute var wholeArchiveDeps bazel.LabelListAttribute
var linkopts bazel.StringListAttribute var linkopts bazel.StringListAttribute
var versionScript bazel.LabelAttribute var versionScript bazel.LabelAttribute
getLibs := func(baseLinkerProps *BaseLinkerProperties) []string {
libs := baseLinkerProps.Header_libs
libs = append(libs, baseLinkerProps.Static_libs...)
libs = android.SortedUniqueStrings(libs)
return libs
}
for _, linkerProps := range module.linker.linkerProps() { for _, linkerProps := range module.linker.linkerProps() {
if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok { if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
libs := getLibs(baseLinkerProps) // Excludes to parallel Soong:
exportedLibs := baseLinkerProps.Export_header_lib_headers // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
wholeArchiveLibs := baseLinkerProps.Whole_static_libs staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, libs)) staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs)) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps) wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
// TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
// export_generated_headers
exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
if baseLinkerProps.Version_script != nil { if baseLinkerProps.Version_script != nil {
versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
} }
sharedLibs := baseLinkerProps.Shared_libs
dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, sharedLibs))
break break
} }
} }
@@ -556,26 +543,83 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) { for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
for config, props := range configToProps { for config, props := range configToProps {
if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok { if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
libs := getLibs(baseLinkerProps) staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
exportedLibs := baseLinkerProps.Export_header_lib_headers staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
wholeArchiveLibs := baseLinkerProps.Whole_static_libs wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, libs)) wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs)) sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps)) dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs))
exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
if baseLinkerProps.Version_script != nil { if baseLinkerProps.Version_script != nil {
versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
} }
}
}
}
sharedLibs := baseLinkerProps.Shared_libs type productVarDep struct {
dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, sharedLibs)) // the name of the corresponding excludes field, if one exists
} excludesField string
// reference to the bazel attribute that should be set for the given product variable config
attribute *bazel.LabelListAttribute
}
productVarToDepFields := map[string]productVarDep{
// product variables do not support exclude_shared_libs
"Shared_libs": productVarDep{attribute: &dynamicDeps},
"Static_libs": productVarDep{"Exclude_static_libs", &staticDeps},
"Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps},
}
productVariableProps := android.ProductVariableProperties(ctx)
for name, dep := range productVarToDepFields {
props, exists := productVariableProps[name]
excludeProps, excludesExists := productVariableProps[dep.excludesField]
// if neither an include or excludes property exists, then skip it
if !exists && !excludesExists {
continue
}
// collect all the configurations that an include or exclude property exists for.
// we want to iterate all configurations rather than either the include or exclude because for a
// particular configuration we may have only and include or only an exclude to handle
configs := make(map[string]bool, len(props)+len(excludeProps))
for config := range props {
configs[config] = true
}
for config := range excludeProps {
configs[config] = true
}
for config := range configs {
prop, includesExists := props[config]
excludesProp, excludesExists := excludeProps[config]
var includes, excludes []string
var ok bool
// if there was no includes/excludes property, casting fails and that's expected
if includes, ok = prop.Property.([]string); includesExists && !ok {
ctx.ModuleErrorf("Could not convert product variable %s property", name)
}
if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
}
dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, android.BazelLabelForModuleDepsExcludes(ctx, android.FirstUniqueStrings(includes), excludes))
} }
} }
staticDeps.ResolveExcludes()
dynamicDeps.ResolveExcludes()
wholeArchiveDeps.ResolveExcludes()
headerDeps.Append(staticDeps)
return linkerAttributes{ return linkerAttributes{
deps: deps, deps: headerDeps,
exportedDeps: exportedDeps, exportedDeps: exportedDeps,
dynamicDeps: dynamicDeps, dynamicDeps: dynamicDeps,
wholeArchiveDeps: wholeArchiveDeps, wholeArchiveDeps: wholeArchiveDeps,