diff options
37 files changed, 1079 insertions, 106 deletions
diff --git a/android/bazel.go b/android/bazel.go index 9a966b617..970ad0d71 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -364,18 +364,24 @@ var ( // Per-module denylist to always opt modules out of both bp2build and mixed builds. bp2buildModuleDoNotConvertList = []string{ - "libnativehelper_compat_libc", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99 - "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 @@ -436,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 @@ -445,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. @@ -515,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 } diff --git a/android/config.go b/android/config.go index b4f8b8d3b..0187a8ad5 100644 --- a/android/config.go +++ b/android/config.go @@ -658,6 +658,10 @@ func (c *config) IsEnvFalse(key string) bool { return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" } +func (c *config) TargetsJava11() bool { + return c.IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_11") +} + // EnvDeps returns the environment variables this build depends on. The first // call to this function blocks future reads from the environment. func (c *config) EnvDeps() map[string]string { @@ -1241,6 +1245,10 @@ func (c *deviceConfig) NativeCoverageEnabledForPath(path string) bool { return coverage } +func (c *deviceConfig) AfdoAdditionalProfileDirs() []string { + return c.config.productVariables.AfdoAdditionalProfileDirs +} + func (c *deviceConfig) PgoAdditionalProfileDirs() []string { return c.config.productVariables.PgoAdditionalProfileDirs } diff --git a/android/module.go b/android/module.go index 6de416535..2750131d8 100644 --- a/android/module.go +++ b/android/module.go @@ -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) { diff --git a/android/mutator.go b/android/mutator.go index dbd8c04db..fa6f2be8d 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -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) } diff --git a/android/neverallow.go b/android/neverallow.go index 034861958..4bb3e57b5 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -15,6 +15,7 @@ package android import ( + "fmt" "path/filepath" "reflect" "regexp" @@ -372,6 +373,20 @@ type ruleProperty struct { matcher ValueMatcher } +func (r *ruleProperty) String() string { + return fmt.Sprintf("%q matches: %s", strings.Join(r.fields, "."), r.matcher) +} + +type ruleProperties []ruleProperty + +func (r ruleProperties) String() string { + var s []string + for _, r := range r { + s = append(s, r.String()) + } + return strings.Join(s, " ") +} + // A NeverAllow rule. type Rule interface { In(path ...string) Rule @@ -413,8 +428,8 @@ type rule struct { moduleTypes []string unlessModuleTypes []string - props []ruleProperty - unlessProps []ruleProperty + props ruleProperties + unlessProps ruleProperties onlyBootclasspathJar bool } @@ -424,16 +439,19 @@ func NeverAllow() Rule { return &rule{directDeps: make(map[string]bool)} } +// In adds path(s) where this rule applies. func (r *rule) In(path ...string) Rule { r.paths = append(r.paths, cleanPaths(path)...) return r } +// NotIn adds path(s) to that this rule does not apply to. func (r *rule) NotIn(path ...string) Rule { r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...) return r } +// InDirectDeps adds dep(s) that are not allowed with this rule. func (r *rule) InDirectDeps(deps ...string) Rule { for _, d := range deps { r.directDeps[d] = true @@ -441,25 +459,30 @@ func (r *rule) InDirectDeps(deps ...string) Rule { return r } +// WithOsClass adds osClass(es) that this rule applies to. func (r *rule) WithOsClass(osClasses ...OsClass) Rule { r.osClasses = append(r.osClasses, osClasses...) return r } +// ModuleType adds type(s) that this rule applies to. func (r *rule) ModuleType(types ...string) Rule { r.moduleTypes = append(r.moduleTypes, types...) return r } +// NotModuleType adds type(s) that this rule does not apply to.. func (r *rule) NotModuleType(types ...string) Rule { r.unlessModuleTypes = append(r.unlessModuleTypes, types...) return r } +// With specifies property/value combinations that are restricted for this rule. func (r *rule) With(properties, value string) Rule { return r.WithMatcher(properties, selectMatcher(value)) } +// WithMatcher specifies property/matcher combinations that are restricted for this rule. func (r *rule) WithMatcher(properties string, matcher ValueMatcher) Rule { r.props = append(r.props, ruleProperty{ fields: fieldNamesForProperties(properties), @@ -468,10 +491,12 @@ func (r *rule) WithMatcher(properties string, matcher ValueMatcher) Rule { return r } +// Without specifies property/value combinations that this rule does not apply to. func (r *rule) Without(properties, value string) Rule { return r.WithoutMatcher(properties, selectMatcher(value)) } +// Without specifies property/matcher combinations that this rule does not apply to. func (r *rule) WithoutMatcher(properties string, matcher ValueMatcher) Rule { r.unlessProps = append(r.unlessProps, ruleProperty{ fields: fieldNamesForProperties(properties), @@ -487,49 +512,54 @@ func selectMatcher(expected string) ValueMatcher { return &equalMatcher{expected: expected} } +// Because specifies a reason for this rule. func (r *rule) Because(reason string) Rule { r.reason = reason return r } +// BootclasspathJar whether this rule only applies to Jars in the Bootclasspath func (r *rule) BootclasspathJar() Rule { r.onlyBootclasspathJar = true return r } func (r *rule) String() string { - s := "neverallow" - for _, v := range r.paths { - s += " dir:" + v + "*" + s := []string{"neverallow requirements. Not allowed:"} + if len(r.paths) > 0 { + s = append(s, fmt.Sprintf("in dirs: %q", r.paths)) } - for _, v := range r.unlessPaths { - s += " -dir:" + v + "*" + if len(r.moduleTypes) > 0 { + s = append(s, fmt.Sprintf("module types: %q", r.moduleTypes)) } - for _, v := range r.moduleTypes { - s += " type:" + v + if len(r.props) > 0 { + s = append(s, fmt.Sprintf("properties matching: %s", r.props)) } - for _, v := range r.unlessModuleTypes { - s += " -type:" + v + if len(r.directDeps) > 0 { + s = append(s, fmt.Sprintf("dep(s): %q", SortedStringKeys(r.directDeps))) } - for _, v := range r.props { - s += " " + strings.Join(v.fields, ".") + v.matcher.String() + if len(r.osClasses) > 0 { + s = append(s, fmt.Sprintf("os class(es): %q", r.osClasses)) } - for _, v := range r.unlessProps { - s += " -" + strings.Join(v.fields, ".") + v.matcher.String() + if r.onlyBootclasspathJar { + s = append(s, "in bootclasspath jar") } - for k := range r.directDeps { - s += " deps:" + k + if len(r.unlessPaths) > 0 { + s = append(s, fmt.Sprintf("EXCEPT in dirs: %q", r.unlessPaths)) } - for _, v := range r.osClasses { - s += " os:" + v.String() + if len(r.unlessModuleTypes) > 0 { + s = append(s, fmt.Sprintf("EXCEPT module types: %q", r.unlessModuleTypes)) } - if r.onlyBootclasspathJar { - s += " inBcp" + if len(r.unlessProps) > 0 { + s = append(s, fmt.Sprintf("EXCEPT properties matching: %q", r.unlessProps)) } if len(r.reason) != 0 { - s += " which is restricted because " + r.reason + s = append(s, " which is restricted because "+r.reason) + } + if len(s) == 1 { + s[0] = "neverallow requirements (empty)" } - return s + return strings.Join(s, "\n\t") } func (r *rule) appliesToPath(dir string) bool { diff --git a/android/neverallow_test.go b/android/neverallow_test.go index 18a870501..58a90b307 100644 --- a/android/neverallow_test.go +++ b/android/neverallow_test.go @@ -15,6 +15,7 @@ package android import ( + "regexp" "testing" "github.com/google/blueprint" @@ -55,7 +56,37 @@ var neverallowTests = []struct { }`), }, expectedErrors: []string{ - `module "libother": violates neverallow deps:not_allowed_in_direct_deps`, + regexp.QuoteMeta("module \"libother\": violates neverallow requirements. Not allowed:\n\tdep(s): [\"not_allowed_in_direct_deps\"]"), + }, + }, + { + name: "multiple constraints", + rules: []Rule{ + NeverAllow(). + InDirectDeps("not_allowed_in_direct_deps"). + In("other"). + ModuleType("cc_library"). + NotIn("top"). + NotModuleType("cc_binary"), + }, + fs: map[string][]byte{ + "top/Android.bp": []byte(` + cc_library { + name: "not_allowed_in_direct_deps", + }`), + "other/Android.bp": []byte(` + cc_library { + name: "libother", + static_libs: ["not_allowed_in_direct_deps"], + }`), + }, + expectedErrors: []string{ + regexp.QuoteMeta(`module "libother": violates neverallow requirements. Not allowed: + in dirs: ["other/"] + module types: ["cc_library"] + dep(s): ["not_allowed_in_direct_deps"] + EXCEPT in dirs: ["top/"] + EXCEPT module types: ["cc_binary"]`), }, }, diff --git a/android/variable.go b/android/variable.go index bc93835f2..a6156b1f7 100644 --- a/android/variable.go +++ b/android/variable.go @@ -124,6 +124,8 @@ type variableProperties struct { Shared_libs []string Cmdline []string + Srcs []string + Exclude_srcs []string } // eng is true for -eng builds, and can be used to turn on additionaly heavyweight debugging @@ -327,7 +329,8 @@ type productVariables struct { NamespacesToExport []string `json:",omitempty"` - PgoAdditionalProfileDirs []string `json:",omitempty"` + AfdoAdditionalProfileDirs []string `json:",omitempty"` + PgoAdditionalProfileDirs []string `json:",omitempty"` VndkUseCoreVariant *bool `json:",omitempty"` VndkSnapshotBuildArtifacts *bool `json:",omitempty"` diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go index 1045ca6e4..ae526887a 100644 --- a/androidmk/androidmk/android.go +++ b/androidmk/androidmk/android.go @@ -229,6 +229,8 @@ func init() { "LOCAL_IS_UNIT_TEST": "unit_test", "LOCAL_ENFORCE_USES_LIBRARIES": "enforce_uses_libs", + + "LOCAL_CHECK_ELF_FILES": "check_elf_files", }) } diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go index a2d6992e6..ea537056d 100644 --- a/androidmk/androidmk/androidmk_test.go +++ b/androidmk/androidmk/androidmk_test.go @@ -1566,6 +1566,25 @@ android_app { } `, }, + { + desc: "LOCAL_CHECK_ELF_FILES", + in: ` +include $(CLEAR_VARS) +LOCAL_MODULE := foo +LOCAL_SRC_FILES := test.c +LOCAL_MODULE_CLASS := SHARED_LIBRARIES +LOCAL_CHECK_ELF_FILES := false +include $(BUILD_PREBUILT) + `, + expected: ` +cc_prebuilt_library_shared { + name: "foo", + srcs: ["test.c"], + + check_elf_files: false, +} +`, + }, } func TestEndToEnd(t *testing.T) { diff --git a/apex/apex_test.go b/apex/apex_test.go index 9ab8ca1c5..727a1f2ec 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7457,7 +7457,7 @@ func TestApexPermittedPackagesRules(t *testing.T) { }, { name: "Bootclasspath apex jar not satisfying allowed module packages on Q.", - expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`, + expectedError: `(?s)module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`, bp: ` java_library { name: "bcp_lib1", @@ -7494,7 +7494,7 @@ func TestApexPermittedPackagesRules(t *testing.T) { }, { name: "Bootclasspath apex jar not satisfying allowed module packages on R.", - expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`, + expectedError: `(?s)module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`, bp: ` java_library { name: "bcp_lib1", diff --git a/bazel/configurability.go b/bazel/configurability.go index 1993f76fc..7355ac7d3 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -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", diff --git a/bazel/properties.go b/bazel/properties.go index 76be0581b..d8b3a3a02 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -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 diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index eaceea969..59a238976 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -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"], + })`, + }), + }}) +} diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index e2e55ddee..e65a1fa0b 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1433,3 +1433,21 @@ func TestCcLibraryStaticUseVersionLib(t *testing.T) { }, }) } + +func TestCcLibraryStaticStdInFlags(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + blueprint: soongCcProtoPreamble + `cc_library_static { + name: "foo", + cflags: ["-std=candcpp"], + conlyflags: ["-std=conly"], + cppflags: ["-std=cpp"], + include_build_directory: false, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("cc_library_static", "foo", attrNameToString{ + "conlyflags": `["-std=conly"]`, + "cppflags": `["-std=cpp"]`, + }), + }, + }) +} diff --git a/bp2build/configurability.go b/bp2build/configurability.go index c953259f9..dfbb265d2 100644 --- a/bp2build/configurability.go +++ b/bp2build/configurability.go @@ -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 } diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go index 506589389..3a5d5bb2a 100644 --- a/bp2build/prebuilt_etc_conversion_test.go +++ b/bp2build/prebuilt_etc_conversion_test.go @@ -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"`, + })}}) +} diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go index f6d2a2066..ac890878b 100644 --- a/bp2build/sh_conversion_test.go +++ b/bp2build/sh_conversion_test.go @@ -73,3 +73,20 @@ func TestShBinarySimple(t *testing.T) { })}, }) } + +func TestShBinaryDefaults(t *testing.T) { + runShBinaryTestCase(t, bp2buildTestCase{ + description: "sh_binary test", + moduleTypeUnderTest: "sh_binary", + moduleTypeUnderTestFactory: sh.ShBinaryFactory, + blueprint: `sh_binary { + name: "foo", + src: "foo.sh", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("sh_binary", "foo", attrNameToString{ + "srcs": `["foo.sh"]`, + })}, + }) +} diff --git a/cc/Android.bp b/cc/Android.bp index 07aa7cbbe..0bf0045d3 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -19,10 +19,11 @@ bootstrap_go_package { "soong-tradefed", ], srcs: [ + "afdo.go", "androidmk.go", "api_level.go", - "builder.go", "bp2build.go", + "builder.go", "cc.go", "ccdeps.go", "check.go", diff --git a/cc/afdo.go b/cc/afdo.go new file mode 100644 index 000000000..022f2833b --- /dev/null +++ b/cc/afdo.go @@ -0,0 +1,194 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cc + +import ( + "fmt" + "strings" + + "github.com/google/blueprint/proptools" + + "android/soong/android" +) + +var ( + globalAfdoProfileProjects = []string{ + "vendor/google_data/pgo_profile/sampling/", + "toolchain/pgo-profiles/sampling/", + } +) + +var afdoProfileProjectsConfigKey = android.NewOnceKey("AfdoProfileProjects") + +const afdoCFlagsFormat = "-fprofile-sample-accurate -fprofile-sample-use=%s" + +func getAfdoProfileProjects(config android.DeviceConfig) []string { + return config.OnceStringSlice(afdoProfileProjectsConfigKey, func() []string { + return append(globalAfdoProfileProjects, config.AfdoAdditionalProfileDirs()...) + }) +} + +func recordMissingAfdoProfileFile(ctx BaseModuleContext, missing string) { + getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true) +} + +type AfdoProperties struct { + Afdo bool + + AfdoTarget *string `blueprint:"mutated"` + AfdoDeps []string `blueprint:"mutated"` +} + +type afdo struct { + Properties AfdoProperties +} + +func (afdo *afdo) props() []interface{} { + return []interface{}{&afdo.Properties} +} + +func (afdo *afdo) AfdoEnabled() bool { + return afdo != nil && afdo.Properties.Afdo && afdo.Properties.AfdoTarget != nil +} + +// Get list of profile file names, ordered by level of specialisation. For example: +// 1. libfoo_arm64.afdo +// 2. libfoo.afdo +// Add more specialisation as needed. +func getProfileFiles(ctx BaseModuleContext, moduleName string) []string { + var files []string + files = append(files, moduleName+"_"+ctx.Arch().ArchType.String()+".afdo") + files = append(files, moduleName+".afdo") + return files +} + +func (props *AfdoProperties) getAfdoProfileFile(ctx BaseModuleContext, module string) android.OptionalPath { + // Test if the profile_file is present in any of the Afdo profile projects + for _, profileFile := range getProfileFiles(ctx, module) { + for _, profileProject := range getAfdoProfileProjects(ctx.DeviceConfig()) { + path := android.ExistentPathForSource(ctx, profileProject, profileFile) + if path.Valid() { + return path + } + } + } + + // Record that this module's profile file is absent + missing := ctx.ModuleDir() + ":" + module + recordMissingAfdoProfileFile(ctx, missing) + + return android.OptionalPathForPath(nil) +} + +func (afdo *afdo) begin(ctx BaseModuleContext) { + if afdo.Properties.Afdo && !ctx.static() && !ctx.Host() { + module := ctx.ModuleName() + if afdo.Properties.getAfdoProfileFile(ctx, module).Valid() { + afdo.Properties.AfdoTarget = proptools.StringPtr(module) + } + } +} + +func (afdo *afdo) flags(ctx ModuleContext, flags Flags) Flags { + if profile := afdo.Properties.AfdoTarget; profile != nil { + if profileFile := afdo.Properties.getAfdoProfileFile(ctx, *profile); profileFile.Valid() { + profileFilePath := profileFile.Path() + + profileUseFlag := fmt.Sprintf(afdoCFlagsFormat, profileFile) + flags.Local.CFlags = append(flags.Local.CFlags, profileUseFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, profileUseFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-no-warn-sample-unused=true") + + // Update CFlagsDeps and LdFlagsDeps so the module is rebuilt + // if profileFile gets updated + flags.CFlagsDeps = append(flags.CFlagsDeps, profileFilePath) + flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFilePath) + } + } + + return flags +} + +// Propagate afdo requirements down from binaries +func afdoDepsMutator(mctx android.TopDownMutatorContext) { + if m, ok := mctx.Module().(*Module); ok && m.afdo.AfdoEnabled() { + afdoTarget := *m.afdo.Properties.AfdoTarget + mctx.WalkDeps(func(dep android.Module, parent android.Module) bool { + tag := mctx.OtherModuleDependencyTag(dep) + libTag, isLibTag := tag.(libraryDependencyTag) + + // Do not recurse down non-static dependencies + if isLibTag { + if !libTag.static() { + return false + } + } else { + if tag != objDepTag && tag != reuseObjTag { + return false + } + } + + if dep, ok := dep.(*Module); ok { + dep.afdo.Properties.AfdoDeps = append(dep.afdo.Properties.AfdoDeps, afdoTarget) + } + + return true + }) + } +} + +// Create afdo variants for modules that need them +func afdoMutator(mctx android.BottomUpMutatorContext) { + if m, ok := mctx.Module().(*Module); ok && m.afdo != nil { + if m.afdo.AfdoEnabled() && !m.static() { + afdoTarget := *m.afdo.Properties.AfdoTarget + mctx.SetDependencyVariation(encodeTarget(afdoTarget)) + } + + variationNames := []string{""} + afdoDeps := android.FirstUniqueStrings(m.afdo.Properties.AfdoDeps) + for _, dep := range afdoDeps { + variationNames = append(variationNames, encodeTarget(dep)) + } + if len(variationNames) > 1 { + modules := mctx.CreateVariations(variationNames...) + for i, name := range variationNames { + if name == "" { + continue + } + variation := modules[i].(*Module) + variation.Properties.PreventInstall = true + variation.Properties.HideFromMake = true + variation.afdo.Properties.AfdoTarget = proptools.StringPtr(decodeTarget(name)) + } + } + } +} + +// Encode target name to variation name. +func encodeTarget(target string) string { + if target == "" { + return "" + } + return "afdo-" + target +} + +// Decode target name from variation name. +func decodeTarget(variation string) string { + if variation == "" { + return "" + } + return strings.TrimPrefix(variation, "afdo-") +} diff --git a/cc/binary.go b/cc/binary.go index 50175d92f..b59e762aa 100644 --- a/cc/binary.go +++ b/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 } diff --git a/cc/bp2build.go b/cc/bp2build.go index fad40beea..e4762a064 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -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 { @@ -162,7 +164,7 @@ func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, mo attrs := staticOrSharedAttributes{} setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) { - attrs.Copts.SetSelectValue(axis, config, props.Cflags) + attrs.Copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag)) attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs)) attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs)) @@ -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 @@ -279,9 +282,18 @@ type compilerAttributes struct { protoSrcs bazel.LabelListAttribute } -func parseCommandLineFlags(soongFlags []string) []string { +type filterOutFn func(string) bool + +func filterOutStdFlag(flag string) bool { + return strings.HasPrefix(flag, "-std=") +} + +func parseCommandLineFlags(soongFlags []string, filterOut filterOutFn) []string { var result []string for _, flag := range soongFlags { + if filterOut != nil && filterOut(flag) { + continue + } // Soong's cflags can contain spaces, like `-include header.h`. For // Bazel's copts, split them up to be compatible with the // no_copts_tokenization feature. @@ -308,10 +320,14 @@ func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversi ca.absoluteIncludes.SetSelectValue(axis, config, props.Include_dirs) ca.localIncludes.SetSelectValue(axis, config, localIncludeDirs) - ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags)) - ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags)) - ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags)) - ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags)) + // In Soong, cflags occur on the command line before -std=<val> flag, resulting in the value being + // overridden. In Bazel we always allow overriding, via flags; however, this can cause + // incompatibilities, so we remove "-std=" flags from Cflag properties while leaving it in other + // cases. + ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag)) + ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags, nil)) + ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags, nil)) + ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags, nil)) ca.rtti.SetSelectValue(axis, config, props.Rtti) } @@ -64,6 +64,9 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("coverage", coverageMutator).Parallel() + ctx.TopDown("afdo_deps", afdoDepsMutator) + ctx.BottomUp("afdo", afdoMutator).Parallel() + ctx.TopDown("lto_deps", ltoDepsMutator) ctx.BottomUp("lto", ltoMutator).Parallel() @@ -810,6 +813,7 @@ type Module struct { sabi *sabi vndkdep *vndkdep lto *lto + afdo *afdo pgo *pgo library libraryInterface @@ -1143,6 +1147,9 @@ func (c *Module) Init() android.Module { if c.lto != nil { c.AddProperties(c.lto.props()...) } + if c.afdo != nil { + c.AddProperties(c.afdo.props()...) + } if c.pgo != nil { c.AddProperties(c.pgo.props()...) } @@ -1620,6 +1627,7 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo module.sabi = &sabi{} module.vndkdep = &vndkdep{} module.lto = <o{} + module.afdo = &afdo{} module.pgo = &pgo{} return module } @@ -1815,6 +1823,9 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if c.lto != nil { flags = c.lto.flags(ctx, flags) } + if c.afdo != nil { + flags = c.afdo.flags(ctx, flags) + } if c.pgo != nil { flags = c.pgo.flags(ctx, flags) } @@ -1942,6 +1953,9 @@ func (c *Module) begin(ctx BaseModuleContext) { if c.lto != nil { c.lto.begin(ctx) } + if c.afdo != nil { + c.afdo.begin(ctx) + } if c.pgo != nil { c.pgo.begin(ctx) } @@ -3461,8 +3475,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 { @@ -3534,6 +3555,7 @@ func DefaultsFactory(props ...interface{}) android.Module { &SAbiProperties{}, &VndkProperties{}, <OProperties{}, + &AfdoProperties{}, &PgoProperties{}, &android.ProtoProperties{}, // RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules. diff --git a/cc/cc_test.go b/cc/cc_test.go index bcc6fcd36..31d91b663 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -3980,9 +3980,9 @@ func TestIncludeDirectoryOrdering(t *testing.T) { conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"} cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"} - cflags := []string{"-Wall", "-Werror"} - cstd := []string{"-std=gnu99"} - cppstd := []string{"-std=gnu++17", "-fno-rtti"} + cflags := []string{"-Wall", "-Werror", "-std=candcpp"} + cstd := []string{"-std=gnu99", "-std=conly"} + cppstd := []string{"-std=gnu++17", "-std=cpp", "-fno-rtti"} lastIncludes := []string{ "out/soong/ndk/sysroot/usr/include", @@ -4025,6 +4025,9 @@ func TestIncludeDirectoryOrdering(t *testing.T) { cc_library { name: "libfoo", srcs: ["%s"], + cflags: ["-std=candcpp"], + conlyflags: ["-std=conly"], + cppflags: ["-std=cpp"], local_include_dirs: ["local_include_dirs"], export_include_dirs: ["export_include_dirs"], export_system_include_dirs: ["export_system_include_dirs"], diff --git a/cc/library.go b/cc/library.go index 216c12409..5720944ab 100644 --- a/cc/library.go +++ b/cc/library.go @@ -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 diff --git a/cc/object.go b/cc/object.go index bd43e3670..24f6ed455 100644 --- a/cc/object.go +++ b/cc/object.go @@ -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 diff --git a/cc/sanitize.go b/cc/sanitize.go index d7b1adee5..6c6882217 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -539,11 +539,6 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { if Bool(s.Hwaddress) { s.Address = nil s.Thread = nil - // Disable ubsan diagnosic as a workaround for a compiler bug. - // TODO(b/191808836): re-enable. - s.Diag.Undefined = nil - s.Diag.Integer_overflow = nil - s.Diag.Misc_undefined = nil } // TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index c2866abfa..83de65fe0 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -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) } } } diff --git a/java/base.go b/java/base.go index c45ef641e..7cd71a270 100644 --- a/java/base.go +++ b/java/base.go @@ -122,6 +122,14 @@ type CommonProperties struct { Javacflags []string } + Openjdk11 struct { + // List of source files that should only be used when passing -source 1.9 or higher + Srcs []string `android:"path"` + + // List of javac flags that should only be used when passing -source 1.9 or higher + Javacflags []string + } + // When compiling language level 9+ .java code in packages that are part of // a system module, patch_module names the module that your sources and // dependencies should be patched into. The Android runtime currently @@ -959,6 +967,10 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { if flags.javaVersion.usesJavaModules() { j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...) } + if ctx.Config().TargetsJava11() { + j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk11.Srcs...) + } + srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) if hasSrcExt(srcFiles.Strings(), ".proto") { flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags) diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go index 149cbb758..83c088cd4 100644 --- a/java/dexpreopt_check.go +++ b/java/dexpreopt_check.go @@ -72,8 +72,7 @@ func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.Mod return } - // TODO(b/203198541): Check all system server jars. - systemServerJars := global.AllSystemServerClasspathJars(ctx) + systemServerJars := global.AllSystemServerJars(ctx) for _, jar := range systemServerJars.CopyOfJars() { dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, jar) odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType) diff --git a/java/java.go b/java/java.go index 35b5ec31b..9b4a005f0 100644 --- a/java/java.go +++ b/java/java.go @@ -449,7 +449,7 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext an return normalizeJavaVersion(ctx, javaVersion) } else if ctx.Device() { return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) - } else if ctx.Config().IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_11") { + } else if ctx.Config().TargetsJava11() { // Temporary experimental flag to be able to try and build with // java version 11 options. The flag, if used, just sets Java // 11 as the default version, leaving any components that diff --git a/java/lint.go b/java/lint.go index fe3218e90..7845c336b 100644 --- a/java/lint.go +++ b/java/lint.go @@ -377,6 +377,7 @@ func (l *linter) lint(ctx android.ModuleContext) { html := android.PathForModuleOut(ctx, "lint", "lint-report.html") text := android.PathForModuleOut(ctx, "lint", "lint-report.txt") xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml") + baseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml") depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml) @@ -447,6 +448,8 @@ func (l *linter) lint(ctx android.ModuleContext) { cmd.FlagWithInput("--baseline ", lintBaseline.Path()) } + cmd.FlagWithOutput("--write-reference-baseline ", baseline) + cmd.Text("|| (").Text("if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit 7)") rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String()) diff --git a/java/sdk.go b/java/sdk.go index de7070eef..756a24deb 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -55,7 +55,7 @@ func defaultJavaLanguageVersion(ctx android.EarlyModuleContext, s android.SdkSpe return JAVA_VERSION_7 } else if sdk.FinalOrFutureInt() <= 29 { return JAVA_VERSION_8 - } else if ctx.Config().IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_11") { + } else if ctx.Config().TargetsJava11() { // Temporary experimental flag to be able to try and build with // java version 11 options. The flag, if used, just sets Java // 11 as the default version, leaving any components that diff --git a/java/sdk_library.go b/java/sdk_library.go index b8ab69abb..0bc8895fe 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1392,6 +1392,10 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext Srcs []string Javacflags []string } + Openjdk11 struct { + Srcs []string + Javacflags []string + } Dist struct { Targets []string Dest *string @@ -1418,6 +1422,8 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext } props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags + props.Openjdk11.Srcs = module.properties.Openjdk11.Srcs + props.Openjdk11.Javacflags = module.properties.Openjdk11.Javacflags // We compile the stubs for 1.8 in line with the main android.jar stubs, and potential // interop with older developer tools that don't support 1.9. props.Java_version = proptools.StringPtr("1.8") diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go index 024311e0e..2a80e560e 100644 --- a/mk2rbc/mk2rbc.go +++ b/mk2rbc/mk2rbc.go @@ -1629,6 +1629,13 @@ func (ctx *parseContext) maybeHandleAnnotation(cnode *mkparser.Comment) { return } if p, ok := maybeTrim(annotation, "include_top"); ok { + // Don't allow duplicate include tops, because then we will generate + // invalid starlark code. (duplicate keys in the _entry dictionary) + for _, top := range ctx.includeTops { + if top == p { + return + } + } ctx.includeTops = append(ctx.includeTops, p) return } diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go index 94c4fe6fa..2d768aeac 100644 --- a/mk2rbc/mk2rbc_test.go +++ b/mk2rbc/mk2rbc_test.go @@ -1049,7 +1049,7 @@ def init(g, handle): }.get("vendor/%s/cfg.mk" % g["MY_PATH"]) (_varmod, _varmod_init) = _entry if _entry else (None, None) if not _varmod_init: - rblf.mkerror("cannot") + rblf.mkerror("product.mk", "Cannot find %s" % ("vendor/%s/cfg.mk" % g["MY_PATH"])) rblf.inherit(handle, _varmod, _varmod_init) `, }, @@ -1073,7 +1073,41 @@ def init(g, handle): }.get("%s/cfg.mk" % g["MY_PATH"]) (_varmod, _varmod_init) = _entry if _entry else (None, None) if not _varmod_init: - rblf.mkerror("cannot") + rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"])) + rblf.inherit(handle, _varmod, _varmod_init) +`, + }, + { + desc: "Dynamic inherit with duplicated hint", + mkname: "product.mk", + in: ` +MY_PATH:=foo +#RBC# include_top vendor/foo1 +$(call inherit-product,$(MY_PATH)/cfg.mk) +#RBC# include_top vendor/foo1 +$(call inherit-product,$(MY_PATH)/cfg.mk) +`, + expected: `load("//build/make/core:product_config.rbc", "rblf") +load("//vendor/foo1:cfg.star|init", _cfg_init = "init") + +def init(g, handle): + cfg = rblf.cfg(handle) + g["MY_PATH"] = "foo" + #RBC# include_top vendor/foo1 + _entry = { + "vendor/foo1/cfg.mk": ("_cfg", _cfg_init), + }.get("%s/cfg.mk" % g["MY_PATH"]) + (_varmod, _varmod_init) = _entry if _entry else (None, None) + if not _varmod_init: + rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"])) + rblf.inherit(handle, _varmod, _varmod_init) + #RBC# include_top vendor/foo1 + _entry = { + "vendor/foo1/cfg.mk": ("_cfg", _cfg_init), + }.get("%s/cfg.mk" % g["MY_PATH"]) + (_varmod, _varmod_init) = _entry if _entry else (None, None) + if not _varmod_init: + rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"])) rblf.inherit(handle, _varmod, _varmod_init) `, }, diff --git a/mk2rbc/node.go b/mk2rbc/node.go index d38299d34..ebc57b23b 100644 --- a/mk2rbc/node.go +++ b/mk2rbc/node.go @@ -110,7 +110,9 @@ func (i inheritedDynamicModule) emitSelect(gctx *generationContext) { gctx.writef("if not %s:", i.entryName()) gctx.indentLevel++ gctx.newLine() - gctx.write(`rblf.mkerror("cannot")`) + gctx.write(`rblf.mkerror("`, gctx.starScript.mkFile, `", "Cannot find %s" % (`) + i.path.emit(gctx) + gctx.write("))") gctx.indentLevel-- } } diff --git a/sh/sh_binary.go b/sh/sh_binary.go index e1df8ac59..b1d1bb21e 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -511,8 +511,8 @@ func ShTestHostFactory() android.Module { type bazelShBinaryAttributes struct { Srcs bazel.LabelListAttribute - Filename string - Sub_dir string + Filename *string + Sub_dir *string // Bazel also supports the attributes below, but (so far) these are not required for Bionic // deps // data @@ -538,14 +538,14 @@ func (m *ShBinary) ConvertWithBp2build(ctx android.TopDownMutatorContext) { srcs := bazel.MakeLabelListAttribute( android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src})) - var filename string + var filename *string if m.properties.Filename != nil { - filename = *m.properties.Filename + filename = m.properties.Filename } - var subDir string + var subDir *string if m.properties.Sub_dir != nil { - subDir = *m.properties.Sub_dir + subDir = m.properties.Sub_dir } attrs := &bazelShBinaryAttributes{ |