Handle the 'enabled' property in bp2build
Also fix some bugs pertaining to configurable attribute handling of bool attributes and label sttributes, so that they may support values across multiple different axes at the same time. Test: unit tests for bp2build Test: mixed_droid Change-Id: I411efcfddf02d55dbc0775962068a11348a8bb2c
This commit is contained in:
parent
68542bfcb5
commit
58852a05f3
14 changed files with 612 additions and 49 deletions
|
@ -367,13 +367,21 @@ var (
|
|||
"libandroid_runtime_lazy", // depends on unconverted modules: libbinder_headers
|
||||
"libcmd", // depends on unconverted modules: libbinder
|
||||
|
||||
"libdexfile_support_static", // Depends on unconverted module: libdexfile_external_headers
|
||||
"libunwindstack_local", "libunwindstack_utils", "libc_malloc_debug", "libfdtrack", // Depends on unconverted module: libunwindstack
|
||||
|
||||
"libdexfile_support", // TODO(b/210546943): Enabled based on product variables.
|
||||
"libdexfile_external_headers", // TODO(b/210546943): Enabled based on product variables.
|
||||
|
||||
"libunwindstack", // Depends on unconverted module libdexfile_support.
|
||||
"libnativehelper_compat_libc++", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
|
||||
|
||||
"chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol
|
||||
|
||||
"libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules
|
||||
|
||||
"gen-kotlin-build-file.py", // module has same name as source
|
||||
|
||||
"libbinder", // TODO(b/188503688): Disabled for some archs,
|
||||
"libactivitymanager_aidl", // TODO(b/207426160): Depends on activity_manager_procstate_aidl, which is an aidl filegroup.
|
||||
|
||||
"libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libgmock_ndk
|
||||
|
@ -434,8 +442,7 @@ var (
|
|||
"linkerconfig", // http://b/202876379 has arch-variant static_executable
|
||||
"mdnsd", // http://b/202876379 has arch-variant static_executable
|
||||
|
||||
"acvp_modulewrapper", // disabled for android x86/x86_64
|
||||
"CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
|
||||
"CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
|
||||
|
||||
"libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette,
|
||||
"libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
|
||||
|
@ -443,9 +450,7 @@ var (
|
|||
|
||||
// Per-module denylist of cc_library modules to only generate the static
|
||||
// variant if their shared variant isn't ready or buildable by Bazel.
|
||||
bp2buildCcLibraryStaticOnlyList = []string{
|
||||
"libjemalloc5", // http://b/188503688, cc_library, `target: { android: { enabled: false } }` for android targets.
|
||||
}
|
||||
bp2buildCcLibraryStaticOnlyList = []string{}
|
||||
|
||||
// Per-module denylist to opt modules out of mixed builds. Such modules will
|
||||
// still be generated via bp2build.
|
||||
|
@ -513,6 +518,9 @@ func (b *BazelModuleBase) MixedBuildsEnabled(ctx ModuleContext) bool {
|
|||
// Windows toolchains are not currently supported.
|
||||
return false
|
||||
}
|
||||
if !ctx.Module().Enabled() {
|
||||
return false
|
||||
}
|
||||
if !ctx.Config().BazelContext.BazelEnabled() {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -869,6 +869,13 @@ type CommonAttributes struct {
|
|||
Data bazel.LabelListAttribute
|
||||
}
|
||||
|
||||
// constraintAttributes represents Bazel attributes pertaining to build constraints,
|
||||
// which make restrict building a Bazel target for some set of platforms.
|
||||
type constraintAttributes struct {
|
||||
// Constraint values this target can be built for.
|
||||
Target_compatible_with bazel.LabelListAttribute
|
||||
}
|
||||
|
||||
type distProperties struct {
|
||||
// configuration to distribute output files from this module to the distribution
|
||||
// directory (default: $OUT/dist, configurable with $DIST_DIR)
|
||||
|
@ -1089,7 +1096,8 @@ func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupport
|
|||
m.base().commonProperties.CreateCommonOSVariant = true
|
||||
}
|
||||
|
||||
func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext) {
|
||||
func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext,
|
||||
enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes {
|
||||
// Assert passed-in attributes include Name
|
||||
name := attrs.Name
|
||||
if len(name) == 0 {
|
||||
|
@ -1107,14 +1115,45 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator
|
|||
|
||||
required := depsToLabelList(props.Required)
|
||||
archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{})
|
||||
|
||||
var enabledProperty bazel.BoolAttribute
|
||||
if props.Enabled != nil {
|
||||
enabledProperty.Value = props.Enabled
|
||||
}
|
||||
|
||||
for axis, configToProps := range archVariantProps {
|
||||
for config, _props := range configToProps {
|
||||
if archProps, ok := _props.(*commonProperties); ok {
|
||||
required.SetSelectValue(axis, config, depsToLabelList(archProps.Required).Value)
|
||||
if archProps.Enabled != nil {
|
||||
enabledProperty.SetSelectValue(axis, config, archProps.Enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if enabledPropertyOverrides.Value != nil {
|
||||
enabledProperty.Value = enabledPropertyOverrides.Value
|
||||
}
|
||||
for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() {
|
||||
configToBools := enabledPropertyOverrides.ConfigurableValues[axis]
|
||||
for cfg, val := range configToBools {
|
||||
enabledProperty.SetSelectValue(axis, cfg, &val)
|
||||
}
|
||||
}
|
||||
|
||||
data.Append(required)
|
||||
|
||||
var err error
|
||||
constraints := constraintAttributes{}
|
||||
constraints.Target_compatible_with, err = enabledProperty.ToLabelListAttribute(
|
||||
bazel.LabelList{[]bazel.Label{bazel.Label{Label: "@platforms//:incompatible"}}, nil},
|
||||
bazel.LabelList{[]bazel.Label{}, nil})
|
||||
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("Error processing enabled attribute: %s", err)
|
||||
}
|
||||
return constraints
|
||||
}
|
||||
|
||||
// A ModuleBase object contains the properties that are common to all Android
|
||||
|
@ -1233,10 +1272,11 @@ type ModuleBase struct {
|
|||
|
||||
// A struct containing all relevant information about a Bazel target converted via bp2build.
|
||||
type bp2buildInfo struct {
|
||||
Dir string
|
||||
BazelProps bazel.BazelTargetModuleProperties
|
||||
CommonAttrs CommonAttributes
|
||||
Attrs interface{}
|
||||
Dir string
|
||||
BazelProps bazel.BazelTargetModuleProperties
|
||||
CommonAttrs CommonAttributes
|
||||
ConstraintAttrs constraintAttributes
|
||||
Attrs interface{}
|
||||
}
|
||||
|
||||
// TargetName returns the Bazel target name of a bp2build converted target.
|
||||
|
@ -1262,7 +1302,7 @@ func (b bp2buildInfo) BazelRuleLoadLocation() string {
|
|||
|
||||
// BazelAttributes returns the Bazel attributes of a bp2build converted target.
|
||||
func (b bp2buildInfo) BazelAttributes() []interface{} {
|
||||
return []interface{}{&b.CommonAttrs, b.Attrs}
|
||||
return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs}
|
||||
}
|
||||
|
||||
func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
|
||||
|
|
|
@ -254,6 +254,14 @@ type TopDownMutatorContext interface {
|
|||
// BazelTargetModuleProperties containing additional metadata for the
|
||||
// bp2build codegenerator.
|
||||
CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
|
||||
|
||||
// CreateBazelTargetModuleWithRestrictions creates a BazelTargetModule by calling the
|
||||
// factory method, just like in CreateModule, but also requires
|
||||
// BazelTargetModuleProperties containing additional metadata for the
|
||||
// bp2build codegenerator. The generated target is restricted to only be buildable for certain
|
||||
// platforms, as dictated by a given bool attribute: the target will not be buildable in
|
||||
// any platform for which this bool attribute is false.
|
||||
CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute)
|
||||
}
|
||||
|
||||
type topDownMutatorContext struct {
|
||||
|
@ -502,13 +510,30 @@ func (t *topDownMutatorContext) CreateBazelTargetModule(
|
|||
bazelProps bazel.BazelTargetModuleProperties,
|
||||
commonAttrs CommonAttributes,
|
||||
attrs interface{}) {
|
||||
commonAttrs.fillCommonBp2BuildModuleAttrs(t)
|
||||
t.createBazelTargetModule(bazelProps, commonAttrs, attrs, bazel.BoolAttribute{})
|
||||
}
|
||||
|
||||
func (t *topDownMutatorContext) CreateBazelTargetModuleWithRestrictions(
|
||||
bazelProps bazel.BazelTargetModuleProperties,
|
||||
commonAttrs CommonAttributes,
|
||||
attrs interface{},
|
||||
enabledProperty bazel.BoolAttribute) {
|
||||
t.createBazelTargetModule(bazelProps, commonAttrs, attrs, enabledProperty)
|
||||
}
|
||||
|
||||
func (t *topDownMutatorContext) createBazelTargetModule(
|
||||
bazelProps bazel.BazelTargetModuleProperties,
|
||||
commonAttrs CommonAttributes,
|
||||
attrs interface{},
|
||||
enabledProperty bazel.BoolAttribute) {
|
||||
constraintAttributes := commonAttrs.fillCommonBp2BuildModuleAttrs(t, enabledProperty)
|
||||
mod := t.Module()
|
||||
info := bp2buildInfo{
|
||||
Dir: t.OtherModuleDir(mod),
|
||||
BazelProps: bazelProps,
|
||||
CommonAttrs: commonAttrs,
|
||||
Attrs: attrs,
|
||||
Dir: t.OtherModuleDir(mod),
|
||||
BazelProps: bazelProps,
|
||||
CommonAttrs: commonAttrs,
|
||||
ConstraintAttrs: constraintAttributes,
|
||||
Attrs: attrs,
|
||||
}
|
||||
mod.base().addBp2buildInfo(info)
|
||||
}
|
||||
|
|
|
@ -109,6 +109,21 @@ var (
|
|||
osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
|
||||
ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
|
||||
}
|
||||
|
||||
// Map where keys are OsType names, and values are slices containing the archs
|
||||
// that that OS supports.
|
||||
// These definitions copied from arch.go.
|
||||
// TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results
|
||||
// in a cyclic dependency.
|
||||
osToArchMap = map[string][]string{
|
||||
osAndroid: {archArm, archArm64, archX86, archX86_64},
|
||||
osLinux: {archX86, archX86_64},
|
||||
osLinuxMusl: {archX86, archX86_64},
|
||||
osDarwin: {archArm64, archX86_64},
|
||||
osLinuxBionic: {archArm64, archX86_64},
|
||||
// TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well.
|
||||
osWindows: {archX86, archX86_64},
|
||||
}
|
||||
)
|
||||
|
||||
// basic configuration types
|
||||
|
@ -122,6 +137,10 @@ const (
|
|||
productVariables
|
||||
)
|
||||
|
||||
func osArchString(os string, arch string) string {
|
||||
return fmt.Sprintf("%s_%s", os, arch)
|
||||
}
|
||||
|
||||
func (ct configurationType) String() string {
|
||||
return map[configurationType]string{
|
||||
noConfig: "no_config",
|
||||
|
|
|
@ -244,9 +244,69 @@ type LabelAttribute struct {
|
|||
ConfigurableValues configurableLabels
|
||||
}
|
||||
|
||||
func (la *LabelAttribute) axisTypes() map[configurationType]bool {
|
||||
types := map[configurationType]bool{}
|
||||
for k := range la.ConfigurableValues {
|
||||
if len(la.ConfigurableValues[k]) > 0 {
|
||||
types[k.configurationType] = true
|
||||
}
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
// Collapse reduces the configurable axes of the label attribute to a single axis.
|
||||
// This is necessary for final writing to bp2build, as a configurable label
|
||||
// attribute can only be comprised by a single select.
|
||||
func (la *LabelAttribute) Collapse() error {
|
||||
axisTypes := la.axisTypes()
|
||||
_, containsOs := axisTypes[os]
|
||||
_, containsArch := axisTypes[arch]
|
||||
_, containsOsArch := axisTypes[osArch]
|
||||
_, containsProductVariables := axisTypes[productVariables]
|
||||
if containsProductVariables {
|
||||
if containsOs || containsArch || containsOsArch {
|
||||
return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
|
||||
}
|
||||
}
|
||||
if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
|
||||
// If a bool attribute has both os and arch configuration axes, the only
|
||||
// way to successfully union their values is to increase the granularity
|
||||
// of the configuration criteria to os_arch.
|
||||
for osType, supportedArchs := range osToArchMap {
|
||||
for _, supportedArch := range supportedArchs {
|
||||
osArch := osArchString(osType, supportedArch)
|
||||
if archOsVal := la.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
|
||||
// Do nothing, as the arch_os is explicitly defined already.
|
||||
} else {
|
||||
archVal := la.SelectValue(ArchConfigurationAxis, supportedArch)
|
||||
osVal := la.SelectValue(OsConfigurationAxis, osType)
|
||||
if osVal != nil && archVal != nil {
|
||||
// In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
|
||||
// runs after os mutator.
|
||||
la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal)
|
||||
} else if osVal != nil && archVal == nil {
|
||||
la.SetSelectValue(OsArchConfigurationAxis, osArch, *osVal)
|
||||
} else if osVal == nil && archVal != nil {
|
||||
la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// All os_arch values are now set. Clear os and arch axes.
|
||||
delete(la.ConfigurableValues, ArchConfigurationAxis)
|
||||
delete(la.ConfigurableValues, OsConfigurationAxis)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasConfigurableValues returns whether there are configurable values set for this label.
|
||||
func (la LabelAttribute) HasConfigurableValues() bool {
|
||||
return len(la.ConfigurableValues) > 0
|
||||
for _, selectValues := range la.ConfigurableValues {
|
||||
if len(selectValues) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SetValue sets the base, non-configured value for the Label
|
||||
|
@ -271,13 +331,13 @@ func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string,
|
|||
}
|
||||
|
||||
// SelectValue gets a value for a bazel select for the given axis and config.
|
||||
func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Label {
|
||||
func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) *Label {
|
||||
axis.validateConfig(config)
|
||||
switch axis.configurationType {
|
||||
case noConfig:
|
||||
return *la.Value
|
||||
return la.Value
|
||||
case arch, os, osArch, productVariables:
|
||||
return *la.ConfigurableValues[axis][config]
|
||||
return la.ConfigurableValues[axis][config]
|
||||
default:
|
||||
panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
|
||||
}
|
||||
|
@ -324,7 +384,12 @@ type BoolAttribute struct {
|
|||
|
||||
// HasConfigurableValues returns whether there are configurable values for this attribute.
|
||||
func (ba BoolAttribute) HasConfigurableValues() bool {
|
||||
return len(ba.ConfigurableValues) > 0
|
||||
for _, cfgToBools := range ba.ConfigurableValues {
|
||||
if len(cfgToBools) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SetSelectValue sets value for the given axis/config.
|
||||
|
@ -343,6 +408,106 @@ func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, v
|
|||
}
|
||||
}
|
||||
|
||||
// ToLabelListAttribute creates and returns a LabelListAttribute from this
|
||||
// bool attribute, where each bool in this attribute corresponds to a
|
||||
// label list value in the resultant attribute.
|
||||
func (ba *BoolAttribute) ToLabelListAttribute(falseVal LabelList, trueVal LabelList) (LabelListAttribute, error) {
|
||||
getLabelList := func(boolPtr *bool) LabelList {
|
||||
if boolPtr == nil {
|
||||
return LabelList{nil, nil}
|
||||
} else if *boolPtr {
|
||||
return trueVal
|
||||
} else {
|
||||
return falseVal
|
||||
}
|
||||
}
|
||||
|
||||
mainVal := getLabelList(ba.Value)
|
||||
if !ba.HasConfigurableValues() {
|
||||
return MakeLabelListAttribute(mainVal), nil
|
||||
}
|
||||
|
||||
result := LabelListAttribute{}
|
||||
if err := ba.Collapse(); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
for axis, configToBools := range ba.ConfigurableValues {
|
||||
if len(configToBools) < 1 {
|
||||
continue
|
||||
}
|
||||
for config, boolPtr := range configToBools {
|
||||
val := getLabelList(&boolPtr)
|
||||
if !val.Equals(mainVal) {
|
||||
result.SetSelectValue(axis, config, val)
|
||||
}
|
||||
}
|
||||
result.SetSelectValue(axis, ConditionsDefaultConfigKey, mainVal)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Collapse reduces the configurable axes of the boolean attribute to a single axis.
|
||||
// This is necessary for final writing to bp2build, as a configurable boolean
|
||||
// attribute can only be comprised by a single select.
|
||||
func (ba *BoolAttribute) Collapse() error {
|
||||
axisTypes := ba.axisTypes()
|
||||
_, containsOs := axisTypes[os]
|
||||
_, containsArch := axisTypes[arch]
|
||||
_, containsOsArch := axisTypes[osArch]
|
||||
_, containsProductVariables := axisTypes[productVariables]
|
||||
if containsProductVariables {
|
||||
if containsOs || containsArch || containsOsArch {
|
||||
return fmt.Errorf("boolean attribute could not be collapsed as it has two or more unrelated axes")
|
||||
}
|
||||
}
|
||||
if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
|
||||
// If a bool attribute has both os and arch configuration axes, the only
|
||||
// way to successfully union their values is to increase the granularity
|
||||
// of the configuration criteria to os_arch.
|
||||
for osType, supportedArchs := range osToArchMap {
|
||||
for _, supportedArch := range supportedArchs {
|
||||
osArch := osArchString(osType, supportedArch)
|
||||
if archOsVal := ba.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
|
||||
// Do nothing, as the arch_os is explicitly defined already.
|
||||
} else {
|
||||
archVal := ba.SelectValue(ArchConfigurationAxis, supportedArch)
|
||||
osVal := ba.SelectValue(OsConfigurationAxis, osType)
|
||||
if osVal != nil && archVal != nil {
|
||||
// In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
|
||||
// runs after os mutator.
|
||||
ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
|
||||
} else if osVal != nil && archVal == nil {
|
||||
ba.SetSelectValue(OsArchConfigurationAxis, osArch, osVal)
|
||||
} else if osVal == nil && archVal != nil {
|
||||
ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// All os_arch values are now set. Clear os and arch axes.
|
||||
delete(ba.ConfigurableValues, ArchConfigurationAxis)
|
||||
delete(ba.ConfigurableValues, OsConfigurationAxis)
|
||||
// Verify post-condition; this should never fail, provided no additional
|
||||
// axes are introduced.
|
||||
if len(ba.ConfigurableValues) > 1 {
|
||||
panic(fmt.Errorf("error in collapsing attribute: %s", ba))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ba *BoolAttribute) axisTypes() map[configurationType]bool {
|
||||
types := map[configurationType]bool{}
|
||||
for k := range ba.ConfigurableValues {
|
||||
if len(ba.ConfigurableValues[k]) > 0 {
|
||||
types[k.configurationType] = true
|
||||
}
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
// SelectValue gets the value for the given axis/config.
|
||||
func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool {
|
||||
axis.validateConfig(config)
|
||||
|
@ -550,7 +715,12 @@ func (lla *LabelListAttribute) Add(label *LabelAttribute) {
|
|||
|
||||
// HasConfigurableValues returns true if the attribute contains axis-specific label list values.
|
||||
func (lla LabelListAttribute) HasConfigurableValues() bool {
|
||||
return len(lla.ConfigurableValues) > 0
|
||||
for _, selectValues := range lla.ConfigurableValues {
|
||||
if len(selectValues) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the attribute has no values under any configuration.
|
||||
|
@ -800,7 +970,12 @@ func MakeStringListAttribute(value []string) StringListAttribute {
|
|||
|
||||
// HasConfigurableValues returns true if the attribute contains axis-specific string_list values.
|
||||
func (sla StringListAttribute) HasConfigurableValues() bool {
|
||||
return len(sla.ConfigurableValues) > 0
|
||||
for _, selectValues := range sla.ConfigurableValues {
|
||||
if len(selectValues) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Append appends all values, including os and arch specific ones, from another
|
||||
|
|
|
@ -1369,6 +1369,94 @@ cc_library {
|
|||
})
|
||||
}
|
||||
|
||||
func TestCCLibraryNoLibCrtArchAndTargetVariant(t *testing.T) {
|
||||
runCcLibraryTestCase(t, bp2buildTestCase{
|
||||
moduleTypeUnderTest: "cc_library",
|
||||
moduleTypeUnderTestFactory: cc.LibraryFactory,
|
||||
filesystem: map[string]string{
|
||||
"impl.cpp": "",
|
||||
},
|
||||
blueprint: soongCcLibraryPreamble + `
|
||||
cc_library {
|
||||
name: "foo-lib",
|
||||
srcs: ["impl.cpp"],
|
||||
arch: {
|
||||
arm: {
|
||||
no_libcrt: true,
|
||||
},
|
||||
x86: {
|
||||
no_libcrt: true,
|
||||
},
|
||||
},
|
||||
target: {
|
||||
darwin: {
|
||||
no_libcrt: true,
|
||||
}
|
||||
},
|
||||
include_build_directory: false,
|
||||
}
|
||||
`,
|
||||
expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
|
||||
"srcs": `["impl.cpp"]`,
|
||||
"use_libcrt": `select({
|
||||
"//build/bazel/platforms/os_arch:android_arm": False,
|
||||
"//build/bazel/platforms/os_arch:android_x86": False,
|
||||
"//build/bazel/platforms/os_arch:darwin_arm64": False,
|
||||
"//build/bazel/platforms/os_arch:darwin_x86_64": False,
|
||||
"//build/bazel/platforms/os_arch:linux_glibc_x86": False,
|
||||
"//build/bazel/platforms/os_arch:linux_musl_x86": False,
|
||||
"//build/bazel/platforms/os_arch:windows_x86": False,
|
||||
"//conditions:default": None,
|
||||
})`,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
func TestCCLibraryNoLibCrtArchAndTargetVariantConflict(t *testing.T) {
|
||||
runCcLibraryTestCase(t, bp2buildTestCase{
|
||||
moduleTypeUnderTest: "cc_library",
|
||||
moduleTypeUnderTestFactory: cc.LibraryFactory,
|
||||
filesystem: map[string]string{
|
||||
"impl.cpp": "",
|
||||
},
|
||||
blueprint: soongCcLibraryPreamble + `
|
||||
cc_library {
|
||||
name: "foo-lib",
|
||||
srcs: ["impl.cpp"],
|
||||
arch: {
|
||||
arm: {
|
||||
no_libcrt: true,
|
||||
},
|
||||
// This is expected to override the value for darwin_x86_64.
|
||||
x86_64: {
|
||||
no_libcrt: true,
|
||||
},
|
||||
},
|
||||
target: {
|
||||
darwin: {
|
||||
no_libcrt: false,
|
||||
}
|
||||
},
|
||||
include_build_directory: false,
|
||||
}
|
||||
`,
|
||||
expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
|
||||
"srcs": `["impl.cpp"]`,
|
||||
"use_libcrt": `select({
|
||||
"//build/bazel/platforms/os_arch:android_arm": False,
|
||||
"//build/bazel/platforms/os_arch:android_x86_64": False,
|
||||
"//build/bazel/platforms/os_arch:darwin_arm64": True,
|
||||
"//build/bazel/platforms/os_arch:darwin_x86_64": False,
|
||||
"//build/bazel/platforms/os_arch:linux_bionic_x86_64": False,
|
||||
"//build/bazel/platforms/os_arch:linux_glibc_x86_64": False,
|
||||
"//build/bazel/platforms/os_arch:linux_musl_x86_64": False,
|
||||
"//build/bazel/platforms/os_arch:windows_x86_64": False,
|
||||
"//conditions:default": None,
|
||||
})`,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
func TestCcLibraryStrip(t *testing.T) {
|
||||
expectedTargets := []string{}
|
||||
expectedTargets = append(expectedTargets, makeCcLibraryTargets("all", attrNameToString{
|
||||
|
@ -2159,3 +2247,146 @@ cc_library {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestCcLibraryDisabledArchAndTarget(t *testing.T) {
|
||||
runCcLibraryTestCase(t, bp2buildTestCase{
|
||||
moduleTypeUnderTest: "cc_library",
|
||||
moduleTypeUnderTestFactory: cc.LibraryFactory,
|
||||
blueprint: soongCcProtoPreamble + `cc_library {
|
||||
name: "foo",
|
||||
srcs: ["foo.cpp"],
|
||||
target: {
|
||||
darwin: {
|
||||
enabled: false,
|
||||
},
|
||||
windows: {
|
||||
enabled: false,
|
||||
},
|
||||
linux_glibc_x86: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
include_build_directory: false,
|
||||
}`,
|
||||
expectedBazelTargets: makeCcLibraryTargets("foo", attrNameToString{
|
||||
"srcs": `["foo.cpp"]`,
|
||||
"target_compatible_with": `select({
|
||||
"//build/bazel/platforms/os_arch:darwin_arm64": ["@platforms//:incompatible"],
|
||||
"//build/bazel/platforms/os_arch:darwin_x86_64": ["@platforms//:incompatible"],
|
||||
"//build/bazel/platforms/os_arch:linux_glibc_x86": ["@platforms//:incompatible"],
|
||||
"//build/bazel/platforms/os_arch:windows_x86": ["@platforms//:incompatible"],
|
||||
"//build/bazel/platforms/os_arch:windows_x86_64": ["@platforms//:incompatible"],
|
||||
"//conditions:default": [],
|
||||
})`,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
func TestCcLibraryDisabledArchAndTargetWithDefault(t *testing.T) {
|
||||
runCcLibraryTestCase(t, bp2buildTestCase{
|
||||
moduleTypeUnderTest: "cc_library",
|
||||
moduleTypeUnderTestFactory: cc.LibraryFactory,
|
||||
blueprint: soongCcProtoPreamble + `cc_library {
|
||||
name: "foo",
|
||||
srcs: ["foo.cpp"],
|
||||
enabled: false,
|
||||
target: {
|
||||
darwin: {
|
||||
enabled: true,
|
||||
},
|
||||
windows: {
|
||||
enabled: false,
|
||||
},
|
||||
linux_glibc_x86: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
include_build_directory: false,
|
||||
}`,
|
||||
expectedBazelTargets: makeCcLibraryTargets("foo", attrNameToString{
|
||||
"srcs": `["foo.cpp"]`,
|
||||
"target_compatible_with": `select({
|
||||
"//build/bazel/platforms/os_arch:darwin_arm64": [],
|
||||
"//build/bazel/platforms/os_arch:darwin_x86_64": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
})`,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
func TestCcLibrarySharedDisabled(t *testing.T) {
|
||||
runCcLibraryTestCase(t, bp2buildTestCase{
|
||||
moduleTypeUnderTest: "cc_library",
|
||||
moduleTypeUnderTestFactory: cc.LibraryFactory,
|
||||
blueprint: soongCcProtoPreamble + `cc_library {
|
||||
name: "foo",
|
||||
srcs: ["foo.cpp"],
|
||||
enabled: false,
|
||||
shared: {
|
||||
enabled: true,
|
||||
},
|
||||
target: {
|
||||
android: {
|
||||
shared: {
|
||||
enabled: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
include_build_directory: false,
|
||||
}`,
|
||||
expectedBazelTargets: []string{makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
|
||||
"srcs": `["foo.cpp"]`,
|
||||
"target_compatible_with": `["@platforms//:incompatible"]`,
|
||||
}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
|
||||
"srcs": `["foo.cpp"]`,
|
||||
"target_compatible_with": `select({
|
||||
"//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
|
||||
"//conditions:default": [],
|
||||
})`,
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestCcLibraryStaticDisabledForSomeArch(t *testing.T) {
|
||||
runCcLibraryTestCase(t, bp2buildTestCase{
|
||||
moduleTypeUnderTest: "cc_library",
|
||||
moduleTypeUnderTestFactory: cc.LibraryFactory,
|
||||
blueprint: soongCcProtoPreamble + `cc_library {
|
||||
name: "foo",
|
||||
srcs: ["foo.cpp"],
|
||||
shared: {
|
||||
enabled: false
|
||||
},
|
||||
target: {
|
||||
darwin: {
|
||||
enabled: true,
|
||||
},
|
||||
windows: {
|
||||
enabled: false,
|
||||
},
|
||||
linux_glibc_x86: {
|
||||
shared: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
include_build_directory: false,
|
||||
}`,
|
||||
expectedBazelTargets: []string{makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
|
||||
"srcs": `["foo.cpp"]`,
|
||||
"target_compatible_with": `select({
|
||||
"//build/bazel/platforms/os:windows": ["@platforms//:incompatible"],
|
||||
"//conditions:default": [],
|
||||
})`,
|
||||
}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
|
||||
"srcs": `["foo.cpp"]`,
|
||||
"target_compatible_with": `select({
|
||||
"//build/bazel/platforms/os_arch:darwin_arm64": [],
|
||||
"//build/bazel/platforms/os_arch:darwin_x86_64": [],
|
||||
"//build/bazel/platforms/os_arch:linux_glibc_x86": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
})`,
|
||||
}),
|
||||
}})
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package bp2build
|
||||
|
||||
import (
|
||||
"android/soong/android"
|
||||
"android/soong/bazel"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/bazel"
|
||||
)
|
||||
|
||||
// Configurability support for bp2build.
|
||||
|
@ -89,13 +90,15 @@ func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects
|
|||
}
|
||||
archSelects := map[string]reflect.Value{}
|
||||
defaultVal := configToLabels[bazel.ConditionsDefaultConfigKey]
|
||||
// Skip empty list values unless ether EmitEmptyList is true, or these values differ from the default.
|
||||
emitEmptyList := list.EmitEmptyList || len(defaultVal.Includes) > 0
|
||||
for config, labels := range configToLabels {
|
||||
// Omit any entries in the map which match the default value, for brevity.
|
||||
if config != bazel.ConditionsDefaultConfigKey && labels.Equals(defaultVal) {
|
||||
continue
|
||||
}
|
||||
selectKey := axis.SelectKey(config)
|
||||
if use, value := labelListSelectValue(selectKey, labels, list.EmitEmptyList); use {
|
||||
if use, value := labelListSelectValue(selectKey, labels, emitEmptyList); use {
|
||||
archSelects[selectKey] = value
|
||||
}
|
||||
}
|
||||
|
@ -144,9 +147,15 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
|
|||
shouldPrintDefault = true
|
||||
}
|
||||
case bazel.LabelAttribute:
|
||||
if err := list.Collapse(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
value, configurableAttrs = getLabelValue(list)
|
||||
defaultSelectValue = &bazelNone
|
||||
case bazel.BoolAttribute:
|
||||
if err := list.Collapse(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
value, configurableAttrs = getBoolValue(list)
|
||||
defaultSelectValue = &bazelNone
|
||||
default:
|
||||
|
@ -204,11 +213,12 @@ func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue *stri
|
|||
continue
|
||||
}
|
||||
value := selectMap[selectKey]
|
||||
if isZero(value) && !emitZeroValues {
|
||||
// Ignore zero values to not generate empty lists.
|
||||
if isZero(value) && !emitZeroValues && isZero(selectMap[bazel.ConditionsDefaultSelectKey]) {
|
||||
// Ignore zero values to not generate empty lists. However, always note zero values if
|
||||
// the default value is non-zero.
|
||||
continue
|
||||
}
|
||||
s, err := prettyPrintSelectEntry(value, selectKey, indent, emitZeroValues)
|
||||
s, err := prettyPrintSelectEntry(value, selectKey, indent, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -86,3 +86,45 @@ prebuilt_etc {
|
|||
"sub_dir": `"tz"`,
|
||||
})}})
|
||||
}
|
||||
|
||||
func TestPrebuiltEtcArchAndTargetVariant(t *testing.T) {
|
||||
runPrebuiltEtcTestCase(t, bp2buildTestCase{
|
||||
description: "prebuilt_etc - arch variant",
|
||||
filesystem: map[string]string{},
|
||||
blueprint: `
|
||||
prebuilt_etc {
|
||||
name: "apex_tz_version",
|
||||
src: "version/tz_version",
|
||||
filename: "tz_version",
|
||||
sub_dir: "tz",
|
||||
installable: false,
|
||||
arch: {
|
||||
arm: {
|
||||
src: "arm",
|
||||
},
|
||||
arm64: {
|
||||
src: "darwin_or_arm64",
|
||||
},
|
||||
},
|
||||
target: {
|
||||
darwin: {
|
||||
src: "darwin_or_arm64",
|
||||
}
|
||||
},
|
||||
}
|
||||
`,
|
||||
expectedBazelTargets: []string{
|
||||
makeBazelTarget("prebuilt_etc", "apex_tz_version", attrNameToString{
|
||||
"filename": `"tz_version"`,
|
||||
"installable": `False`,
|
||||
"src": `select({
|
||||
"//build/bazel/platforms/os_arch:android_arm": "arm",
|
||||
"//build/bazel/platforms/os_arch:android_arm64": "darwin_or_arm64",
|
||||
"//build/bazel/platforms/os_arch:darwin_arm64": "darwin_or_arm64",
|
||||
"//build/bazel/platforms/os_arch:darwin_x86_64": "darwin_or_arm64",
|
||||
"//build/bazel/platforms/os_arch:linux_bionic_arm64": "darwin_or_arm64",
|
||||
"//conditions:default": "version/tz_version",
|
||||
})`,
|
||||
"sub_dir": `"tz"`,
|
||||
})}})
|
||||
}
|
||||
|
|
23
cc/binary.go
23
cc/binary.go
|
@ -558,13 +558,6 @@ func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, lin
|
|||
}
|
||||
|
||||
func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) {
|
||||
var compatibleWith bazel.StringListAttribute
|
||||
if typ == "cc_binary_host" {
|
||||
//incompatible with android OS
|
||||
compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, []string{"@platforms//:incompatible"})
|
||||
compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, bazel.ConditionsDefaultConfigKey, []string{})
|
||||
}
|
||||
|
||||
baseAttrs := bp2BuildParseBaseProps(ctx, m)
|
||||
binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
|
||||
|
||||
|
@ -610,16 +603,22 @@ func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) {
|
|||
None: baseAttrs.stripNone,
|
||||
},
|
||||
|
||||
Target_compatible_with: compatibleWith,
|
||||
Features: baseAttrs.features,
|
||||
Features: baseAttrs.features,
|
||||
}
|
||||
|
||||
ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
|
||||
var enabledProperty bazel.BoolAttribute
|
||||
if typ == "cc_binary_host" {
|
||||
falseVal := false
|
||||
enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, &falseVal)
|
||||
}
|
||||
|
||||
ctx.CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties{
|
||||
Rule_class: "cc_binary",
|
||||
Bzl_load_location: "//build/bazel/rules:cc_binary.bzl",
|
||||
},
|
||||
android.CommonAttributes{Name: m.Name()},
|
||||
attrs)
|
||||
attrs,
|
||||
enabledProperty)
|
||||
}
|
||||
|
||||
// binaryAttributes contains Bazel attributes corresponding to a cc binary
|
||||
|
@ -655,6 +654,4 @@ type binaryAttributes struct {
|
|||
Strip stripAttributes
|
||||
|
||||
Features bazel.StringListAttribute
|
||||
|
||||
Target_compatible_with bazel.StringListAttribute
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ type staticOrSharedAttributes struct {
|
|||
Implementation_whole_archive_deps bazel.LabelListAttribute
|
||||
|
||||
System_dynamic_deps bazel.LabelListAttribute
|
||||
|
||||
Enabled bazel.BoolAttribute
|
||||
}
|
||||
|
||||
func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
|
||||
|
@ -175,6 +177,7 @@ func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, mo
|
|||
attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
|
||||
|
||||
attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
|
||||
attrs.Enabled.SetSelectValue(axis, config, props.Enabled)
|
||||
}
|
||||
// system_dynamic_deps distinguishes between nil/empty list behavior:
|
||||
// nil -> use default values
|
||||
|
|
11
cc/cc.go
11
cc/cc.go
|
@ -3461,8 +3461,15 @@ func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
|
|||
objectBp2Build(ctx, c)
|
||||
}
|
||||
} else if c.CcLibrary() {
|
||||
static := c.BuildStaticVariant()
|
||||
shared := c.BuildSharedVariant()
|
||||
static := false
|
||||
shared := false
|
||||
if library, ok := c.linker.(*libraryDecorator); ok {
|
||||
static = library.MutatedProperties.BuildStatic
|
||||
shared = library.MutatedProperties.BuildShared
|
||||
} else if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
|
||||
static = library.MutatedProperties.BuildStatic
|
||||
shared = library.MutatedProperties.BuildShared
|
||||
}
|
||||
|
||||
if static && shared {
|
||||
if !prebuilt {
|
||||
|
|
|
@ -392,8 +392,12 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) {
|
|||
Bzl_load_location: "//build/bazel/rules:cc_library_shared.bzl",
|
||||
}
|
||||
|
||||
ctx.CreateBazelTargetModule(staticProps, android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"}, staticTargetAttrs)
|
||||
ctx.CreateBazelTargetModule(sharedProps, android.CommonAttributes{Name: m.Name()}, sharedTargetAttrs)
|
||||
ctx.CreateBazelTargetModuleWithRestrictions(staticProps,
|
||||
android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"},
|
||||
staticTargetAttrs, staticAttrs.Enabled)
|
||||
ctx.CreateBazelTargetModuleWithRestrictions(sharedProps,
|
||||
android.CommonAttributes{Name: m.Name()},
|
||||
sharedTargetAttrs, sharedAttrs.Enabled)
|
||||
}
|
||||
|
||||
// cc_library creates both static and/or shared libraries for a device and/or
|
||||
|
|
|
@ -155,7 +155,8 @@ func objectBp2Build(ctx android.TopDownMutatorContext, m *Module) {
|
|||
for config, props := range configToProps {
|
||||
if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
|
||||
if objectLinkerProps.Linker_script != nil {
|
||||
linkerScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script))
|
||||
label := android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script)
|
||||
linkerScript.SetSelectValue(axis, config, label)
|
||||
}
|
||||
deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
|
||||
systemSharedLibs := objectLinkerProps.System_shared_libs
|
||||
|
|
|
@ -681,7 +681,8 @@ func prebuiltEtcBp2BuildInternal(ctx android.TopDownMutatorContext, module *Preb
|
|||
continue
|
||||
}
|
||||
if props.Src != nil {
|
||||
srcLabelAttribute.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *props.Src))
|
||||
label := android.BazelLabelForModuleSrcSingle(ctx, *props.Src)
|
||||
srcLabelAttribute.SetSelectValue(axis, config, label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue