Handle excludes_{shared,static}_libs
Bug: 188497994 Test: bp2build.sh Change-Id: I4a5ea40cbd804e8542fe33143e4926abc0c6164f
This commit is contained in:
parent
74deed445b
commit
47535c51fa
4 changed files with 252 additions and 36 deletions
|
@ -100,6 +100,22 @@ func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) b
|
|||
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 {
|
||||
return BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes[0]
|
||||
}
|
||||
|
|
|
@ -458,12 +458,13 @@ type ProductConfigContext interface {
|
|||
// with the appropriate ProductConfigVariable.
|
||||
type ProductConfigProperty struct {
|
||||
ProductConfigVariable string
|
||||
FullConfig string
|
||||
Property interface{}
|
||||
}
|
||||
|
||||
// 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
|
||||
type ProductConfigProperties map[string][]ProductConfigProperty
|
||||
type ProductConfigProperties map[string]map[string]ProductConfigProperty
|
||||
|
||||
// ProductVariableProperties returns a ProductConfigProperties containing only the properties which
|
||||
// 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.
|
||||
propertyName := variableValue.Type().Field(j).Name
|
||||
(*productConfigProperties)[propertyName] = append((*productConfigProperties)[propertyName],
|
||||
ProductConfigProperty{
|
||||
ProductConfigVariable: productVariableName + suffix,
|
||||
Property: property.Interface(),
|
||||
})
|
||||
if (*productConfigProperties)[propertyName] == nil {
|
||||
(*productConfigProperties)[propertyName] = make(map[string]ProductConfigProperty)
|
||||
}
|
||||
config := productVariableName + suffix
|
||||
(*productConfigProperties)[propertyName][config] = ProductConfigProperty{
|
||||
ProductConfigVariable: productVariableName,
|
||||
FullConfig: config,
|
||||
Property: property.Interface(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"],
|
||||
}),
|
||||
)`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
141
cc/bp2build.go
141
cc/bp2build.go
|
@ -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)...)
|
||||
}
|
||||
|
||||
|
@ -441,7 +465,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
|
|||
ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
|
||||
}
|
||||
newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
|
||||
attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.ProductConfigVariable), prop.ProductConfigVariable, newFlags)
|
||||
attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -481,37 +505,37 @@ func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
|
|||
// bp2BuildParseLinkerProps parses the linker properties of a module, including
|
||||
// configurable attribute values.
|
||||
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 dynamicDeps bazel.LabelListAttribute
|
||||
var wholeArchiveDeps bazel.LabelListAttribute
|
||||
var linkopts bazel.StringListAttribute
|
||||
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() {
|
||||
if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
|
||||
libs := getLibs(baseLinkerProps)
|
||||
exportedLibs := baseLinkerProps.Export_header_lib_headers
|
||||
wholeArchiveLibs := baseLinkerProps.Whole_static_libs
|
||||
deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, libs))
|
||||
exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
|
||||
linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
|
||||
wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
|
||||
// Excludes to parallel Soong:
|
||||
// https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
|
||||
staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
|
||||
staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
|
||||
wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
|
||||
wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
|
||||
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 {
|
||||
versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
|
||||
}
|
||||
|
||||
sharedLibs := baseLinkerProps.Shared_libs
|
||||
dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, sharedLibs))
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -519,26 +543,83 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
|
|||
for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
|
||||
for config, props := range configToProps {
|
||||
if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
|
||||
libs := getLibs(baseLinkerProps)
|
||||
exportedLibs := baseLinkerProps.Export_header_lib_headers
|
||||
wholeArchiveLibs := baseLinkerProps.Whole_static_libs
|
||||
deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, libs))
|
||||
exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
|
||||
linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
|
||||
wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
|
||||
staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
|
||||
staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
|
||||
wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
|
||||
wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
|
||||
sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
|
||||
dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
|
||||
|
||||
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 {
|
||||
versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
|
||||
}
|
||||
|
||||
sharedLibs := baseLinkerProps.Shared_libs
|
||||
dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, sharedLibs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type productVarDep struct {
|
||||
// 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{
|
||||
deps: deps,
|
||||
deps: headerDeps,
|
||||
exportedDeps: exportedDeps,
|
||||
dynamicDeps: dynamicDeps,
|
||||
wholeArchiveDeps: wholeArchiveDeps,
|
||||
|
|
Loading…
Reference in a new issue