Merge "Handle the 'enabled' property in bp2build" am: 948e851b83
am: fdb30910fc
am: e40c2f5076
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1917398 Change-Id: I5a60df27f103b10f55abc35852f1ffd08c3338cb
This commit is contained in:
commit
5f81eb4dd6
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