diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 5b77ba97d..9dc5878ee 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -340,6 +340,7 @@ var ( "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, "prebuilts/gradle-plugin": Bp2BuildDefaultTrueRecursively, "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, + "prebuilts/module_sdk": Bp2BuildDefaultTrueRecursively, "prebuilts/sdk": Bp2BuildDefaultTrue, "prebuilts/sdk/current/androidx": Bp2BuildDefaultTrue, "prebuilts/sdk/current/androidx-legacy": Bp2BuildDefaultTrue, diff --git a/android/bazel_paths.go b/android/bazel_paths.go index 86829ce29..c0eabdd4a 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -487,6 +487,9 @@ func bp2buildModuleLabel(ctx BazelConversionContext, module blueprint.Module) st if moduleDir == Bp2BuildTopLevel { moduleDir = "" } + if a, ok := module.(Module); ok && IsModulePrebuilt(a) { + moduleName = RemoveOptionalPrebuiltPrefix(moduleName) + } return fmt.Sprintf("//%s:%s", moduleDir, moduleName) } diff --git a/android/config.go b/android/config.go index 445c6cddc..a70fad0c5 100644 --- a/android/config.go +++ b/android/config.go @@ -2073,6 +2073,11 @@ func (c *config) GetApiLibraries() map[string]struct{} { return c.apiLibraries } +// Bp2buildMode indicates whether the config is for bp2build mode of Soong +func (c *config) Bp2buildMode() bool { + return c.BuildMode == Bp2build +} + func (c *deviceConfig) CheckVendorSeappViolations() bool { return Bool(c.config.productVariables.CheckVendorSeappViolations) } diff --git a/android/module.go b/android/module.go index f4b51ea6d..f48af4a03 100644 --- a/android/module.go +++ b/android/module.go @@ -3100,11 +3100,21 @@ func (b *baseModuleContext) ModuleFromName(name string) (blueprint.Module, bool) if !b.isBazelConversionMode() { panic("cannot call ModuleFromName if not in bazel conversion mode") } + var m blueprint.Module + var ok bool if moduleName, _ := SrcIsModuleWithTag(name); moduleName != "" { - return b.bp.ModuleFromName(moduleName) + m, ok = b.bp.ModuleFromName(moduleName) } else { - return b.bp.ModuleFromName(name) + m, ok = b.bp.ModuleFromName(name) } + if !ok { + return m, ok + } + // If this module is not preferred, tried to get the prebuilt version instead + if a, aOk := m.(Module); aOk && !IsModulePrebuilt(a) && !IsModulePreferred(a) { + return b.ModuleFromName("prebuilt_" + name) + } + return m, ok } func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) { diff --git a/android/mutator.go b/android/mutator.go index 41477b8ed..e185cce38 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -55,6 +55,7 @@ func registerMutatorsForBazelConversion(ctx *Context, bp2buildMutators []Registe // TODO(b/165114590): this is required to resolve deps that are only prebuilts, but we should // evaluate the impact on conversion. RegisterPrebuiltsPreArchMutators, + RegisterPrebuiltsPostDepsMutators, }, bp2buildMutators...) diff --git a/android/prebuilt.go b/android/prebuilt.go index 95b772d41..e7b79796e 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -483,20 +483,55 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) { // usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt // will be used if it is marked "prefer" or if the source module is disabled. func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module, prebuilt Module) bool { - if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 { - return false - } + if !ctx.Config().Bp2buildMode() { + if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 { + return false + } - // Skip prebuilt modules under unexported namespaces so that we won't - // end up shadowing non-prebuilt module when prebuilt module under same - // name happens to have a `Prefer` property set to true. - if ctx.Config().KatiEnabled() && !prebuilt.ExportedToMake() { - return false + // Skip prebuilt modules under unexported namespaces so that we won't + // end up shadowing non-prebuilt module when prebuilt module under same + // name happens to have a `Prefer` property set to true. + if ctx.Config().KatiEnabled() && !prebuilt.ExportedToMake() { + return false + } } // If source is not available or is disabled then always use the prebuilt. if source == nil || !source.Enabled() { - return true + // If in bp2build mode, we need to check product variables & Soong config variables, which may + // have overridden the "enabled" property but have not been merged into the property value as + // they would in a non-bp2build mode invocation + if ctx.Config().Bp2buildMode() && source != nil { + productVariableProps, errs := ProductVariableProperties(ctx, source) + if productConfigProps, exists := productVariableProps["Enabled"]; len(errs) == 0 && exists && len(productConfigProps) == 1 { + var prop ProductConfigOrSoongConfigProperty + var value bool + for p, v := range productConfigProps { + prop = p + actual, ok := v.(*bool) + if ok { + value = proptools.Bool(actual) + } + } + if scv, ok := prop.(SoongConfigProperty); ok { + // If the product config var is enabled but the value of enabled is false still, the + // prebuilt is preferred. Otherwise, check if the prebulit is explicitly preferred + if ctx.Config().VendorConfig(scv.namespace).Bool(strings.ToLower(scv.name)) && !value { + return true + } + } else { + // TODO: b/300998219 - handle product vars + // We don't handle product variables yet, so return based on the non-product specific + // value of enabled + return true + } + } else { + // No "enabled" property override, return true since this module isn't enabled + return true + } + } else { + return true + } } // If the use_source_config_var property is set then it overrides the prefer property setting. diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go index bf3351ad8..fde4c973e 100644 --- a/bp2build/cc_library_headers_conversion_test.go +++ b/bp2build/cc_library_headers_conversion_test.go @@ -58,6 +58,7 @@ func TestCcLibraryHeadersLoadStatement(t *testing.T) { func registerCcLibraryHeadersModuleTypes(ctx android.RegistrationContext) { cc.RegisterCCBuildComponents(ctx) cc.RegisterLibraryHeadersBuildComponents(ctx) + ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory) } func runCcLibraryHeadersTestCase(t *testing.T, tc Bp2buildTestCase) { @@ -417,3 +418,67 @@ cc_prebuilt_library_headers { }, }) } + +func TestPrebuiltCcLibraryHeadersPreferredRdepUpdated(t *testing.T) { + runCcLibraryHeadersTestCase(t, Bp2buildTestCase{ + Description: "cc_library_headers prebuilt preferred is used as rdep", + StubbedBuildDefinitions: []string{"foo_export"}, + Filesystem: map[string]string{ + "foo/bar/Android.bp": simpleModule("cc_library_headers", "foo_headers"), + }, + Blueprint: soongCcLibraryHeadersPreamble + ` +cc_prebuilt_library_headers { + name: "foo_headers", + whole_static_libs: ["foo_export"], + bazel_module: { bp2build_available: true }, + prefer: true, +} + +cc_library_shared { + name: "foo", + header_libs: ["foo_headers"], + include_build_directory: false, +} +` + simpleModule("cc_library_headers", "foo_export"), + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{ + "deps": `[":foo_export"]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "implementation_deps": `[":foo_headers"]`, + }), + }, + }) +} + +func TestPrebuiltCcLibraryHeadersRdepUpdated(t *testing.T) { + runCcLibraryHeadersTestCase(t, Bp2buildTestCase{ + Description: "cc_library_headers not preferred is not used for rdep", + StubbedBuildDefinitions: []string{"foo_export"}, + Filesystem: map[string]string{ + "foo/bar/Android.bp": simpleModule("cc_library_headers", "foo_headers"), + }, + Blueprint: soongCcLibraryHeadersPreamble + ` +cc_prebuilt_library_headers { + name: "foo_headers", + whole_static_libs: ["foo_export"], + bazel_module: { bp2build_available: true }, + prefer: false, +} + +cc_library_shared { + name: "foo", + header_libs: ["foo_headers"], + include_build_directory: false, +} +` + simpleModule("cc_library_headers", "foo_export"), + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{ + "deps": `[":foo_export"]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "implementation_deps": `["//foo/bar:foo_headers"]`, + }), + }, + }) +}