From 356f7d45c19ff8b862ff4d5db7384e87c2b052f9 Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Tue, 26 Jan 2021 09:18:53 -0500 Subject: [PATCH] bp2build: convert paths/module refs to Bazel label This currently expands all globs, still need to support converting glob syntax. Test: go build_conversion_test Test: GENERATE_BAZEL_FILES=true m nothing Test: m nothing Bug: 165114590 Change-Id: If7b26e8e663d17566fad9614ca87a8da1f095284 --- android/arch.go | 4 +- android/filegroup.go | 21 +- android/module.go | 13 +- android/mutator.go | 111 +++++++-- android/paths.go | 110 +++++++++ android/register.go | 2 +- android/testing.go | 23 +- apex/apex.go | 2 + apex/deapexer.go | 11 +- apex/prebuilt.go | 11 +- bazel/properties.go | 23 ++ bp2build/build_conversion.go | 10 +- bp2build/build_conversion_test.go | 364 ++++++++++++++++++++++++++---- cc/binary.go | 2 +- cc/cc.go | 8 +- cc/config/toolchain.go | 34 ++- cc/linker.go | 4 +- genrule/genrule.go | 103 +++++---- java/java.go | 5 +- java/proto.go | 2 +- rust/binary.go | 2 +- rust/fuzz.go | 2 +- rust/library.go | 6 +- rust/proc_macro.go | 2 +- rust/rust.go | 2 +- rust/test.go | 2 +- sh/sh_binary.go | 9 +- 27 files changed, 734 insertions(+), 154 deletions(-) diff --git a/android/arch.go b/android/arch.go index baee9be26..90e0485fd 100644 --- a/android/arch.go +++ b/android/arch.go @@ -436,7 +436,7 @@ func osMutator(bpctx blueprint.BottomUpMutatorContext) { // blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext // filters out non-Soong modules. Now that we've handled them, create a // normal android.BottomUpMutatorContext. - mctx := bottomUpMutatorContextFactory(bpctx, module, false) + mctx := bottomUpMutatorContextFactory(bpctx, module, false, false) base := module.base() @@ -576,7 +576,7 @@ func archMutator(bpctx blueprint.BottomUpMutatorContext) { // blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext // filters out non-Soong modules. Now that we've handled them, create a // normal android.BottomUpMutatorContext. - mctx := bottomUpMutatorContextFactory(bpctx, module, false) + mctx := bottomUpMutatorContextFactory(bpctx, module, false, false) base := module.base() diff --git a/android/filegroup.go b/android/filegroup.go index 3d1bbc533..7a6cc4ffc 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -29,7 +29,7 @@ func init() { // https://docs.bazel.build/versions/master/be/general.html#filegroup type bazelFilegroupAttributes struct { Name *string - Srcs []string + Srcs bazel.LabelList } type bazelFilegroup struct { @@ -52,15 +52,18 @@ func (bfg *bazelFilegroup) GenerateAndroidBuildActions(ctx ModuleContext) {} // TODO: Create helper functions to avoid this boilerplate. func FilegroupBp2Build(ctx TopDownMutatorContext) { - if m, ok := ctx.Module().(*fileGroup); ok { - name := "__bp2build__" + m.base().BaseModuleName() - ctx.CreateModule(BazelFileGroupFactory, &bazelFilegroupAttributes{ - Name: proptools.StringPtr(name), - Srcs: m.properties.Srcs, - }, &bazel.BazelTargetModuleProperties{ - Rule_class: "filegroup", - }) + fg, ok := ctx.Module().(*fileGroup) + if !ok { + return } + + name := "__bp2build__" + fg.base().BaseModuleName() + ctx.CreateModule(BazelFileGroupFactory, &bazelFilegroupAttributes{ + Name: proptools.StringPtr(name), + Srcs: BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs), + }, &bazel.BazelTargetModuleProperties{ + Rule_class: "filegroup", + }) } type fileGroupProperties struct { diff --git a/android/module.go b/android/module.go index dcc2b8459..1409d44b1 100644 --- a/android/module.go +++ b/android/module.go @@ -2220,10 +2220,17 @@ func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.Depe } var deps []dep b.VisitDirectDepsBlueprint(func(module blueprint.Module) { - if aModule, _ := module.(Module); aModule != nil && aModule.base().BaseModuleName() == name { - returnedTag := b.bp.OtherModuleDependencyTag(aModule) + if aModule, _ := module.(Module); aModule != nil { + if aModule.base().BaseModuleName() == name { + returnedTag := b.bp.OtherModuleDependencyTag(aModule) + if tag == nil || returnedTag == tag { + deps = append(deps, dep{aModule, returnedTag}) + } + } + } else if b.bp.OtherModuleName(module) == name { + returnedTag := b.bp.OtherModuleDependencyTag(module) if tag == nil || returnedTag == tag { - deps = append(deps, dep{aModule, returnedTag}) + deps = append(deps, dep{module, returnedTag}) } } }) diff --git a/android/mutator.go b/android/mutator.go index 6b19dc568..15be65f9a 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -45,14 +45,30 @@ func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) { } // RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing. -func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, bp2buildMutators []RegisterMutatorFunc) { - mctx := ®isterMutatorsContext{} - - sharedMutators := []RegisterMutatorFunc{ - RegisterDefaultsPreArchMutators, +func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) { + mctx := ®isterMutatorsContext{ + bazelConversionMode: true, } - for _, f := range sharedMutators { + bp2buildPreArchMutators = append([]RegisterMutatorFunc{ + RegisterNamespaceMutator, + RegisterDefaultsPreArchMutators, + // TODO(b/165114590): this is required to resolve deps that are only prebuilts, but we should + // evaluate the impact on conversion. + RegisterPrebuiltsPreArchMutators, + }, + preArchMutators...) + + for _, f := range bp2buildPreArchMutators { + f(mctx) + } + + bp2buildDepsMutators = append([]RegisterMutatorFunc{ + registerDepsMutatorBp2Build, + registerPathDepsMutator, + }, depsMutators...) + + for _, f := range bp2buildDepsMutators { f(mctx) } @@ -77,7 +93,7 @@ func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalD register(preDeps) - mctx.BottomUp("deps", depsMutator).Parallel() + register([]RegisterMutatorFunc{registerDepsMutator}) register(postDeps) @@ -88,8 +104,9 @@ func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalD } type registerMutatorsContext struct { - mutators []*mutator - finalPhase bool + mutators []*mutator + finalPhase bool + bazelConversionMode bool } type RegisterMutatorsContext interface { @@ -211,6 +228,8 @@ func FinalDepsMutators(f RegisterMutatorFunc) { finalDeps = append(finalDeps, f) } +var bp2buildPreArchMutators = []RegisterMutatorFunc{} +var bp2buildDepsMutators = []RegisterMutatorFunc{} var bp2buildMutators = []RegisterMutatorFunc{} // RegisterBp2BuildMutator registers specially crafted mutators for @@ -219,13 +238,24 @@ var bp2buildMutators = []RegisterMutatorFunc{} // // TODO(b/178068862): bring this into TestContext. func RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) { - mutatorName := moduleType + "_bp2build" f := func(ctx RegisterMutatorsContext) { - ctx.TopDown(mutatorName, m) + ctx.TopDown(moduleType, m) } bp2buildMutators = append(bp2buildMutators, f) } +// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules +// into Bazel BUILD targets that should run prior to deps and conversion. +func PreArchBp2BuildMutators(f RegisterMutatorFunc) { + bp2buildPreArchMutators = append(bp2buildPreArchMutators, f) +} + +// DepsBp2BuildMutators adds mutators to be register for converting Android Blueprint modules into +// Bazel BUILD targets that should run prior to conversion to resolve dependencies. +func DepsBp2BuildMutators(f RegisterMutatorFunc) { + bp2buildDepsMutators = append(bp2buildDepsMutators, f) +} + type BaseMutatorContext interface { BaseModuleContext @@ -370,32 +400,38 @@ type BottomUpMutatorContext interface { // variant of the current module. The value should not be modified after being passed to // SetVariationProvider. SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{}) + + // BazelConversionMode returns whether this mutator is being run as part of Bazel Conversion. + BazelConversionMode() bool } type bottomUpMutatorContext struct { bp blueprint.BottomUpMutatorContext baseModuleContext - finalPhase bool + finalPhase bool + bazelConversionMode bool } func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module, - finalPhase bool) BottomUpMutatorContext { + finalPhase, bazelConversionMode bool) BottomUpMutatorContext { return &bottomUpMutatorContext{ - bp: ctx, - baseModuleContext: a.base().baseModuleContextFactory(ctx), - finalPhase: finalPhase, + bp: ctx, + baseModuleContext: a.base().baseModuleContextFactory(ctx), + finalPhase: finalPhase, + bazelConversionMode: bazelConversionMode, } } func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle { finalPhase := x.finalPhase + bazelConversionMode := x.bazelConversionMode f := func(ctx blueprint.BottomUpMutatorContext) { if a, ok := ctx.Module().(Module); ok { - m(bottomUpMutatorContextFactory(ctx, a, finalPhase)) + m(bottomUpMutatorContextFactory(ctx, a, finalPhase, bazelConversionMode)) } } - mutator := &mutator{name: name, bottomUpMutator: f} + mutator := &mutator{name: x.mutatorName(name), bottomUpMutator: f} x.mutators = append(x.mutators, mutator) return mutator } @@ -406,6 +442,13 @@ func (x *registerMutatorsContext) BottomUpBlueprint(name string, m blueprint.Bot return mutator } +func (x *registerMutatorsContext) mutatorName(name string) string { + if x.bazelConversionMode { + return name + "_bp2build" + } + return name +} + func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle { f := func(ctx blueprint.TopDownMutatorContext) { if a, ok := ctx.Module().(Module); ok { @@ -416,7 +459,7 @@ func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) Mutator m(actx) } } - mutator := &mutator{name: name, topDownMutator: f} + mutator := &mutator{name: x.mutatorName(name), topDownMutator: f} x.mutators = append(x.mutators, mutator) return mutator } @@ -449,6 +492,16 @@ func depsMutator(ctx BottomUpMutatorContext) { } } +func registerDepsMutator(ctx RegisterMutatorsContext) { + ctx.BottomUp("deps", depsMutator).Parallel() +} + +func registerDepsMutatorBp2Build(ctx RegisterMutatorsContext) { + // TODO(b/179313531): Consider a separate mutator that only runs depsMutator for modules that are + // being converted to build targets. + ctx.BottomUp("deps", depsMutator).Parallel() +} + func (t *topDownMutatorContext) AppendProperties(props ...interface{}) { for _, p := range props { err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties, @@ -576,12 +629,28 @@ func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module { + if b.bazelConversionMode { + _, noSelfDeps := RemoveFromList(b.ModuleName(), names) + if len(noSelfDeps) == 0 { + return []blueprint.Module(nil) + } + // In Bazel conversion mode, mutators should not have created any variants. So, when adding a + // dependency, the variations would not exist and the dependency could not be added, by + // specifying no variations, we will allow adding the dependency to succeed. + return b.bp.AddFarVariationDependencies(nil, tag, noSelfDeps...) + } return b.bp.AddVariationDependencies(variations, tag, names...) } func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module { + if b.bazelConversionMode { + // In Bazel conversion mode, mutators should not have created any variants. So, when adding a + // dependency, the variations would not exist and the dependency could not be added, by + // specifying no variations, we will allow adding the dependency to succeed. + return b.bp.AddFarVariationDependencies(nil, tag, names...) + } return b.bp.AddFarVariationDependencies(variations, tag, names...) } @@ -609,3 +678,7 @@ func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVaria func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{}) { b.bp.SetVariationProvider(module, provider, value) } + +func (b *bottomUpMutatorContext) BazelConversionMode() bool { + return b.bazelConversionMode +} diff --git a/android/paths.go b/android/paths.go index 810695830..44221be70 100644 --- a/android/paths.go +++ b/android/paths.go @@ -15,6 +15,7 @@ package android import ( + "android/soong/bazel" "fmt" "io/ioutil" "os" @@ -331,6 +332,115 @@ func PathsForModuleSrcExcludes(ctx ModuleMissingDepsPathContext, paths, excludes return ret } +// A subset of the ModuleContext methods which are sufficient to resolve references to paths/deps in +// order to form a Bazel-compatible label for conversion. +type BazelConversionPathContext interface { + EarlyModulePathContext + + GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) + OtherModuleName(m blueprint.Module) string + OtherModuleDir(m blueprint.Module) string +} + +// BazelLabelForModuleDeps returns a Bazel-compatible label for the requested modules which +// correspond to dependencies on the module within the given ctx. +func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList { + var labels bazel.LabelList + for _, module := range modules { + bpText := module + if m := SrcIsModule(module); m == "" { + module = ":" + module + } + if m, t := SrcIsModuleWithTag(module); m != "" { + l := getOtherModuleLabel(ctx, m, t) + l.Bp_text = bpText + labels.Includes = append(labels.Includes, l) + } else { + ctx.ModuleErrorf("%q, is not a module reference", module) + } + } + return labels +} + +// BazelLabelForModuleSrc returns bazel.LabelList with paths rooted from the module's local source +// directory. It expands globs, and resolves references to modules using the ":name" syntax to +// bazel-compatible labels. Properties passed as the paths or excludes argument must have been +// annotated with struct tag `android:"path"` so that dependencies on other modules will have +// already been handled by the path_properties mutator. +func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList { + return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil)) +} + +// BazelLabelForModuleSrcExcludes returns bazel.LabelList with paths rooted from the module's local +// source directory, excluding labels included in the excludes argument. It expands globs, and +// resolves references to modules using the ":name" syntax to bazel-compatible labels. Properties +// passed as the paths or excludes argument must have been annotated with struct tag +// `android:"path"` so that dependencies on other modules will have already been handled by the +// path_properties mutator. +func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList { + excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil)) + excluded := make([]string, 0, len(excludeLabels.Includes)) + for _, e := range excludeLabels.Includes { + excluded = append(excluded, e.Label) + } + labels := expandSrcsForBazel(ctx, paths, excluded) + labels.Excludes = excludeLabels.Includes + return labels +} + +// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local +// source directory, excluding labels included in the excludes argument. It expands globs, and +// resolves references to modules using the ":name" syntax to bazel-compatible labels. Properties +// passed as the paths or excludes argument must have been annotated with struct tag +// `android:"path"` so that dependencies on other modules will have already been handled by the +// path_properties mutator. +func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes []string) bazel.LabelList { + labels := bazel.LabelList{ + Includes: []bazel.Label{}, + } + for _, p := range paths { + if m, tag := SrcIsModuleWithTag(p); m != "" { + l := getOtherModuleLabel(ctx, m, tag) + if !InList(l.Label, expandedExcludes) { + l.Bp_text = fmt.Sprintf(":%s", m) + labels.Includes = append(labels.Includes, l) + } + } else { + var expandedPaths []bazel.Label + if pathtools.IsGlob(p) { + globbedPaths := GlobFiles(ctx, pathForModuleSrc(ctx, p).String(), expandedExcludes) + globbedPaths = PathsWithModuleSrcSubDir(ctx, globbedPaths, "") + for _, path := range globbedPaths { + s := path.Rel() + expandedPaths = append(expandedPaths, bazel.Label{Label: s}) + } + } else { + if !InList(p, expandedExcludes) { + expandedPaths = append(expandedPaths, bazel.Label{Label: p}) + } + } + labels.Includes = append(labels.Includes, expandedPaths...) + } + } + return labels +} + +// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the +// module. The label will be relative to the current directory if appropriate. The dependency must +// already be resolved by either deps mutator or path deps mutator. +func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string) bazel.Label { + m, _ := ctx.GetDirectDep(dep) + // TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets. + otherModuleName := ctx.OtherModuleName(m) + var label bazel.Label + if otherDir, dir := ctx.OtherModuleDir(m), ctx.ModuleDir(); otherDir != dir { + label.Label = fmt.Sprintf("//%s:%s", otherDir, otherModuleName) + } else { + label.Label = fmt.Sprintf(":%s", otherModuleName) + } + return label +} + // OutputPaths is a slice of OutputPath objects, with helpers to operate on the collection. type OutputPaths []OutputPath diff --git a/android/register.go b/android/register.go index 02fc97e2b..18c743f19 100644 --- a/android/register.go +++ b/android/register.go @@ -115,7 +115,7 @@ func (ctx *Context) RegisterForBazelConversion() { ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory)) } - RegisterMutatorsForBazelConversion(ctx.Context, bp2buildMutators) + RegisterMutatorsForBazelConversion(ctx.Context, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators) } // Register the pipeline of singletons, module types, and mutators for diff --git a/android/testing.go b/android/testing.go index 5640c2981..de338bf60 100644 --- a/android/testing.go +++ b/android/testing.go @@ -56,9 +56,9 @@ func NewTestArchContext(config Config) *TestContext { type TestContext struct { *Context - preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc - bp2buildMutators []RegisterMutatorFunc - NameResolver *NameResolver + preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc + bp2buildPreArch, bp2buildDeps, bp2buildMutators []RegisterMutatorFunc + NameResolver *NameResolver } func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) { @@ -85,13 +85,24 @@ func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) { // RegisterBp2BuildMutator registers a BazelTargetModule mutator for converting a module // type to the equivalent Bazel target. func (ctx *TestContext) RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) { - mutatorName := moduleType + "_bp2build" f := func(ctx RegisterMutatorsContext) { - ctx.TopDown(mutatorName, m) + ctx.TopDown(moduleType, m) } ctx.bp2buildMutators = append(ctx.bp2buildMutators, f) } +// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules +// into Bazel BUILD targets that should run prior to deps and conversion. +func (ctx *TestContext) PreArchBp2BuildMutators(f RegisterMutatorFunc) { + ctx.bp2buildPreArch = append(ctx.bp2buildPreArch, f) +} + +// DepsBp2BuildMutators adds mutators to be register for converting Android Blueprint modules into +// Bazel BUILD targets that should run prior to conversion to resolve dependencies. +func (ctx *TestContext) DepsBp2BuildMutators(f RegisterMutatorFunc) { + ctx.bp2buildDeps = append(ctx.bp2buildDeps, f) +} + func (ctx *TestContext) Register() { registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps) @@ -100,7 +111,7 @@ func (ctx *TestContext) Register() { // RegisterForBazelConversion prepares a test context for bp2build conversion. func (ctx *TestContext) RegisterForBazelConversion() { - RegisterMutatorsForBazelConversion(ctx.Context.Context, ctx.bp2buildMutators) + RegisterMutatorsForBazelConversion(ctx.Context.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators) } func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) { diff --git a/apex/apex.go b/apex/apex.go index c89704249..724a50b00 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -54,6 +54,8 @@ func init() { func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { ctx.TopDown("apex_vndk", apexVndkMutator).Parallel() ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel() + ctx.BottomUp("prebuilt_apex_select_source", prebuiltSelectSourceMutator).Parallel() + ctx.BottomUp("deapexer_select_source", deapexerSelectSourceMutator).Parallel() } func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { diff --git a/apex/deapexer.go b/apex/deapexer.go index 651cadfe7..8f4a28569 100644 --- a/apex/deapexer.go +++ b/apex/deapexer.go @@ -78,12 +78,17 @@ func (p *Deapexer) Name() string { return p.prebuilt.Name(p.ModuleBase.Name()) } -func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) { - if err := p.apexFileProperties.selectSource(ctx); err != nil { - ctx.ModuleErrorf("%s", err) +func deapexerSelectSourceMutator(ctx android.BottomUpMutatorContext) { + p, ok := ctx.Module().(*Deapexer) + if !ok { return } + if err := p.apexFileProperties.selectSource(ctx); err != nil { + ctx.ModuleErrorf("%s", err) + } +} +func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) { // Add dependencies from the java modules to which this exports files from the `.apex` file onto // this module so that they can access the `DeapexerInfo` object that this provides. for _, lib := range p.properties.Exported_java_libs { diff --git a/apex/prebuilt.go b/apex/prebuilt.go index c72a9ebfc..314995205 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -250,12 +250,17 @@ func prebuiltApexExportedModuleName(ctx android.BottomUpMutatorContext, name str return name } -func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { - if err := p.properties.selectSource(ctx); err != nil { - ctx.ModuleErrorf("%s", err) +func prebuiltSelectSourceMutator(ctx android.BottomUpMutatorContext) { + p, ok := ctx.Module().(*Prebuilt) + if !ok { return } + if err := p.properties.selectSource(ctx); err != nil { + ctx.ModuleErrorf("%s", err) + } +} +func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { // Add dependencies onto the java modules that represent the java libraries that are provided by // and exported from this prebuilt apex. for _, lib := range p.properties.Exported_java_libs { diff --git a/bazel/properties.go b/bazel/properties.go index 79956e1ec..5b98d159d 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -35,3 +35,26 @@ type BazelTargetModuleProperties struct { // The target label for the bzl file containing the definition of the rule class. Bzl_load_location string } + +// Label is used to represent a Bazel compatible Label. Also stores the original bp text to support +// string replacement. +type Label struct { + Bp_text string + Label string +} + +// LabelList is used to represent a list of Bazel labels. +type LabelList struct { + Includes []Label + Excludes []Label +} + +// Append appends the fields of other labelList to the corresponding fields of ll. +func (ll *LabelList) Append(other LabelList) { + if len(ll.Includes) > 0 || len(other.Includes) > 0 { + ll.Includes = append(ll.Includes, other.Includes...) + } + if len(ll.Excludes) > 0 || len(other.Excludes) > 0 { + ll.Excludes = append(other.Excludes, other.Excludes...) + } +} diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go index 1fa3e064a..2c293eae7 100644 --- a/bp2build/build_conversion.go +++ b/bp2build/build_conversion.go @@ -16,6 +16,7 @@ package bp2build import ( "android/soong/android" + "android/soong/bazel" "fmt" "reflect" "strconv" @@ -177,7 +178,7 @@ func GenerateBazelTargets(ctx bpToBuildContext, codegenMode CodegenMode) map[str panic(fmt.Errorf("Unknown code-generation mode: %s", codegenMode)) } - buildFileToTargets[ctx.ModuleDir(m)] = append(buildFileToTargets[dir], t) + buildFileToTargets[dir] = append(buildFileToTargets[dir], t) }) return buildFileToTargets } @@ -349,6 +350,13 @@ func prettyPrint(propertyValue reflect.Value, indent int) (string, error) { ret += makeIndent(indent) ret += "]" case reflect.Struct: + if labels, ok := propertyValue.Interface().(bazel.LabelList); ok { + // TODO(b/165114590): convert glob syntax + return prettyPrint(reflect.ValueOf(labels.Includes), indent) + } else if label, ok := propertyValue.Interface().(bazel.Label); ok { + return fmt.Sprintf("%q", label.Label), nil + } + ret = "{\n" // Sort and print the struct props by the key. structProps := extractStructProperties(propertyValue, indent) diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index df7dd173e..081b0e564 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -17,6 +17,7 @@ package bp2build import ( "android/soong/android" "android/soong/genrule" + "strings" "testing" ) @@ -248,22 +249,26 @@ func TestGenerateBazelTargetModules(t *testing.T) { ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) - android.FailIfErrored(t, errs) + if Errored(t, "", errs) { + continue + } _, errs = ctx.ResolveDependencies(config) - android.FailIfErrored(t, errs) + if Errored(t, "", errs) { + continue + } bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { - t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount) - } - - actualBazelTarget := bazelTargets[0] - if actualBazelTarget.content != testCase.expectedBazelTarget { - t.Errorf( - "Expected generated Bazel target to be '%s', got '%s'", - testCase.expectedBazelTarget, - actualBazelTarget.content, - ) + t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount) + } else { + actualBazelTarget := bazelTargets[0] + if actualBazelTarget.content != testCase.expectedBazelTarget { + t.Errorf( + "Expected generated Bazel target to be '%s', got '%s'", + testCase.expectedBazelTarget, + actualBazelTarget.content, + ) + } } } } @@ -434,13 +439,32 @@ load("//build/bazel/rules:rules.bzl", "my_library")`, } func TestModuleTypeBp2Build(t *testing.T) { + otherGenruleBp := map[string]string{ + "other/Android.bp": `genrule { + name: "foo.tool", + out: ["foo_tool.out"], + srcs: ["foo_tool.in"], + cmd: "cp $(in) $(out)", +} +genrule { + name: "other.tool", + out: ["other_tool.out"], + srcs: ["other_tool.in"], + cmd: "cp $(in) $(out)", +}`, + } + testCases := []struct { + description string moduleTypeUnderTest string moduleTypeUnderTestFactory android.ModuleFactory moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext) + preArchMutators []android.RegisterMutatorFunc + depsMutators []android.RegisterMutatorFunc bp string - expectedBazelTarget string - description string + expectedBazelTargets []string + fs map[string]string + dir string }{ { description: "filegroup with no srcs", @@ -448,14 +472,16 @@ func TestModuleTypeBp2Build(t *testing.T) { moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, bp: `filegroup { - name: "foo", - srcs: [], + name: "fg_foo", + srcs: [], }`, - expectedBazelTarget: `filegroup( - name = "foo", + expectedBazelTargets: []string{ + `filegroup( + name = "fg_foo", srcs = [ ], )`, + }, }, { description: "filegroup with srcs", @@ -463,30 +489,140 @@ func TestModuleTypeBp2Build(t *testing.T) { moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, bp: `filegroup { - name: "foo", - srcs: ["a", "b"], + name: "fg_foo", + srcs: ["a", "b"], }`, - expectedBazelTarget: `filegroup( - name = "foo", + expectedBazelTargets: []string{`filegroup( + name = "fg_foo", srcs = [ "a", "b", ], )`, + }, + }, + { + description: "filegroup with excludes srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + bp: `filegroup { + name: "fg_foo", + srcs: ["a", "b"], + exclude_srcs: ["a"], +}`, + expectedBazelTargets: []string{`filegroup( + name = "fg_foo", + srcs = [ + "b", + ], +)`, + }, + }, + { + description: "filegroup with glob", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + bp: `filegroup { + name: "foo", + srcs: ["**/*.txt"], +}`, + expectedBazelTargets: []string{`filegroup( + name = "foo", + srcs = [ + "other/a.txt", + "other/b.txt", + "other/subdir/a.txt", + ], +)`, + }, + fs: map[string]string{ + "other/a.txt": "", + "other/b.txt": "", + "other/subdir/a.txt": "", + "other/file": "", + }, + }, + { + description: "filegroup with glob in subdir", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + bp: `filegroup { + name: "foo", + srcs: ["a.txt"], +}`, + dir: "other", + expectedBazelTargets: []string{`filegroup( + name = "fg_foo", + srcs = [ + "a.txt", + "b.txt", + "subdir/a.txt", + ], +)`, + }, + fs: map[string]string{ + "other/Android.bp": `filegroup { + name: "fg_foo", + srcs: ["**/*.txt"], +}`, + "other/a.txt": "", + "other/b.txt": "", + "other/subdir/a.txt": "", + "other/file": "", + }, + }, + { + description: "depends_on_other_dir_module", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + bp: `filegroup { + name: "foobar", + srcs: [ + ":foo", + "c", + ], +}`, + expectedBazelTargets: []string{`filegroup( + name = "foobar", + srcs = [ + "//other:foo", + "c", + ], +)`, + }, + fs: map[string]string{ + "other/Android.bp": `filegroup { + name: "foo", + srcs: ["a", "b"], +}`, + }, }, { description: "genrule with command line variable replacements", moduleTypeUnderTest: "genrule", moduleTypeUnderTestFactory: genrule.GenRuleFactory, moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps}, bp: `genrule { + name: "foo.tool", + out: ["foo_tool.out"], + srcs: ["foo_tool.in"], + cmd: "cp $(in) $(out)", +} + +genrule { name: "foo", out: ["foo.out"], srcs: ["foo.in"], tools: [":foo.tool"], cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)", }`, - expectedBazelTarget: `genrule( + expectedBazelTargets: []string{ + `genrule( name = "foo", cmd = "$(location :foo.tool) --genDir=$(GENDIR) arg $(SRCS) $(OUTS)", outs = [ @@ -499,20 +635,39 @@ func TestModuleTypeBp2Build(t *testing.T) { ":foo.tool", ], )`, + `genrule( + name = "foo.tool", + cmd = "cp $(SRCS) $(OUTS)", + outs = [ + "foo_tool.out", + ], + srcs = [ + "foo_tool.in", + ], +)`, + }, }, { description: "genrule using $(locations :label)", moduleTypeUnderTest: "genrule", moduleTypeUnderTestFactory: genrule.GenRuleFactory, moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps}, bp: `genrule { + name: "foo.tools", + out: ["foo_tool.out", "foo_tool2.out"], + srcs: ["foo_tool.in"], + cmd: "cp $(in) $(out)", + } + +genrule { name: "foo", out: ["foo.out"], srcs: ["foo.in"], tools: [":foo.tools"], cmd: "$(locations :foo.tools) -s $(out) $(in)", }`, - expectedBazelTarget: `genrule( + expectedBazelTargets: []string{`genrule( name = "foo", cmd = "$(locations :foo.tools) -s $(OUTS) $(SRCS)", outs = [ @@ -525,12 +680,83 @@ func TestModuleTypeBp2Build(t *testing.T) { ":foo.tools", ], )`, + `genrule( + name = "foo.tools", + cmd = "cp $(SRCS) $(OUTS)", + outs = [ + "foo_tool.out", + "foo_tool2.out", + ], + srcs = [ + "foo_tool.in", + ], +)`, + }, + }, + { + description: "genrule using $(locations //absolute:label)", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps}, + bp: `genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tool_files: [":foo.tool"], + cmd: "$(locations :foo.tool) -s $(out) $(in)", +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)", + outs = [ + "foo.out", + ], + srcs = [ + "foo.in", + ], + tools = [ + "//other:foo.tool", + ], +)`, + }, + fs: otherGenruleBp, + }, + { + description: "genrule srcs using $(locations //absolute:label)", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps}, + bp: `genrule { + name: "foo", + out: ["foo.out"], + srcs: [":other.tool"], + tool_files: [":foo.tool"], + cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)", +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)", + outs = [ + "foo.out", + ], + srcs = [ + "//other:other.tool", + ], + tools = [ + "//other:foo.tool", + ], +)`, + }, + fs: otherGenruleBp, }, { description: "genrule using $(location) label should substitute first tool label automatically", moduleTypeUnderTest: "genrule", moduleTypeUnderTestFactory: genrule.GenRuleFactory, moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps}, bp: `genrule { name: "foo", out: ["foo.out"], @@ -538,9 +764,9 @@ func TestModuleTypeBp2Build(t *testing.T) { tool_files: [":foo.tool", ":other.tool"], cmd: "$(location) -s $(out) $(in)", }`, - expectedBazelTarget: `genrule( + expectedBazelTargets: []string{`genrule( name = "foo", - cmd = "$(location :foo.tool) -s $(OUTS) $(SRCS)", + cmd = "$(location //other:foo.tool) -s $(OUTS) $(SRCS)", outs = [ "foo.out", ], @@ -548,16 +774,19 @@ func TestModuleTypeBp2Build(t *testing.T) { "foo.in", ], tools = [ - ":foo.tool", - ":other.tool", + "//other:foo.tool", + "//other:other.tool", ], )`, + }, + fs: otherGenruleBp, }, { description: "genrule using $(locations) label should substitute first tool label automatically", moduleTypeUnderTest: "genrule", moduleTypeUnderTestFactory: genrule.GenRuleFactory, moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps}, bp: `genrule { name: "foo", out: ["foo.out"], @@ -565,9 +794,9 @@ func TestModuleTypeBp2Build(t *testing.T) { tools: [":foo.tool", ":other.tool"], cmd: "$(locations) -s $(out) $(in)", }`, - expectedBazelTarget: `genrule( + expectedBazelTargets: []string{`genrule( name = "foo", - cmd = "$(locations :foo.tool) -s $(OUTS) $(SRCS)", + cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)", outs = [ "foo.out", ], @@ -575,23 +804,26 @@ func TestModuleTypeBp2Build(t *testing.T) { "foo.in", ], tools = [ - ":foo.tool", - ":other.tool", + "//other:foo.tool", + "//other:other.tool", ], )`, + }, + fs: otherGenruleBp, }, { description: "genrule without tools or tool_files can convert successfully", moduleTypeUnderTest: "genrule", moduleTypeUnderTestFactory: genrule.GenRuleFactory, moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps}, bp: `genrule { name: "foo", out: ["foo.out"], srcs: ["foo.in"], cmd: "cp $(in) $(out)", }`, - expectedBazelTarget: `genrule( + expectedBazelTargets: []string{`genrule( name = "foo", cmd = "cp $(SRCS) $(OUTS)", outs = [ @@ -601,39 +833,73 @@ func TestModuleTypeBp2Build(t *testing.T) { "foo.in", ], )`, + }, }, } dir := "." for _, testCase := range testCases { - config := android.TestConfig(buildDir, nil, testCase.bp, nil) + fs := make(map[string][]byte) + toParse := []string{ + "Android.bp", + } + for f, content := range testCase.fs { + if strings.HasSuffix(f, "Android.bp") { + toParse = append(toParse, f) + } + fs[f] = []byte(content) + } + config := android.TestConfig(buildDir, nil, testCase.bp, fs) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) + for _, m := range testCase.depsMutators { + ctx.DepsBp2BuildMutators(m) + } ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() - _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) - android.FailIfErrored(t, errs) + _, errs := ctx.ParseFileList(dir, toParse) + if Errored(t, testCase.description, errs) { + continue + } _, errs = ctx.ResolveDependencies(config) - android.FailIfErrored(t, errs) - - bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] - if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { - t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount) + if Errored(t, testCase.description, errs) { + continue } - actualBazelTarget := bazelTargets[0] - if actualBazelTarget.content != testCase.expectedBazelTarget { - t.Errorf( - "%s: Expected generated Bazel target to be '%s', got '%s'", - testCase.description, - testCase.expectedBazelTarget, - actualBazelTarget.content, - ) + checkDir := dir + if testCase.dir != "" { + checkDir = testCase.dir + } + bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir] + if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { + t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount) + } else { + for i, target := range bazelTargets { + if w, g := testCase.expectedBazelTargets[i], target.content; w != g { + t.Errorf( + "%s: Expected generated Bazel target to be '%s', got '%s'", + testCase.description, + w, + g, + ) + } + } } } } +func Errored(t *testing.T, desc string, errs []error) bool { + t.Helper() + if len(errs) > 0 { + for _, err := range errs { + t.Errorf("%s: %s", desc, err) + } + return true + } + return false +} + type bp2buildMutator = func(android.TopDownMutatorContext) func TestBp2BuildInlinesDefaults(t *testing.T) { diff --git a/cc/binary.go b/cc/binary.go index 71c865b96..999b82c24 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -182,7 +182,7 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { } } - if !binary.static() && inList("libc", deps.StaticLibs) { + if !binary.static() && inList("libc", deps.StaticLibs) && !ctx.BazelConversionMode() { ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" + "from static libs or set static_executable: true") } diff --git a/cc/cc.go b/cc/cc.go index d282b6e35..55661c856 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1741,7 +1741,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { func (c *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { if c.cachedToolchain == nil { - c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch()) + c.cachedToolchain = config.FindToolchainWithContext(ctx) } return c.cachedToolchain } @@ -1833,6 +1833,12 @@ func (c *Module) deps(ctx DepsContext) Deps { deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs) deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs) + // In Bazel conversion mode, we dependency and build validations will occur in Bazel, so there is + // no need to do so in Soong. + if ctx.BazelConversionMode() { + return deps + } + for _, lib := range deps.ReexportSharedLibHeaders { if !inList(lib, deps.SharedLibs) { ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib) diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go index db9092db0..59c042230 100644 --- a/cc/config/toolchain.go +++ b/cc/config/toolchain.go @@ -32,12 +32,42 @@ func registerToolchainFactory(os android.OsType, arch android.ArchType, factory toolchainFactories[os][arch] = factory } +type toolchainContext interface { + Os() android.OsType + Arch() android.Arch +} + +type conversionContext interface { + BazelConversionMode() bool +} + +func FindToolchainWithContext(ctx toolchainContext) Toolchain { + t, err := findToolchain(ctx.Os(), ctx.Arch()) + if err != nil { + if c, ok := ctx.(conversionContext); ok && c.BazelConversionMode() { + // TODO(b/179123288): determine conversion for toolchain + return &toolchainX86_64{} + } else { + panic(err) + } + } + return t +} + func FindToolchain(os android.OsType, arch android.Arch) Toolchain { + t, err := findToolchain(os, arch) + if err != nil { + panic(err) + } + return t +} + +func findToolchain(os android.OsType, arch android.Arch) (Toolchain, error) { factory := toolchainFactories[os][arch.ArchType] if factory == nil { - panic(fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String())) + return nil, fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String()) } - return factory(arch) + return factory(arch), nil } type Toolchain interface { diff --git a/cc/linker.go b/cc/linker.go index ff07224ae..6d0d4160b 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -328,7 +328,9 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { } deps.SystemSharedLibs = linker.Properties.System_shared_libs - if deps.SystemSharedLibs == nil { + // In Bazel conversion mode, variations have not been specified, so SystemSharedLibs may + // inaccuarately appear unset, which can cause issues with circular dependencies. + if deps.SystemSharedLibs == nil && !ctx.BazelConversionMode() { // Provide a default system_shared_libs if it is unspecified. Note: If an // empty list [] is specified, it implies that the module declines the // default system_shared_libs. diff --git a/genrule/genrule.go b/genrule/genrule.go index ddfb4596b..62aa7f834 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -47,9 +47,14 @@ func RegisterGenruleBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel() }) + android.DepsBp2BuildMutators(RegisterGenruleBp2BuildDeps) android.RegisterBp2BuildMutator("genrule", GenruleBp2Build) } +func RegisterGenruleBp2BuildDeps(ctx android.RegisterMutatorsContext) { + ctx.BottomUp("genrule_tool_deps", toolDepsMutator) +} + var ( pctx = android.NewPackageContext("android/soong/genrule") @@ -776,9 +781,9 @@ type genRuleProperties struct { type bazelGenruleAttributes struct { Name *string - Srcs []string + Srcs bazel.LabelList Outs []string - Tools []string + Tools bazel.LabelList Cmd string } @@ -795,45 +800,63 @@ func BazelGenruleFactory() android.Module { } func GenruleBp2Build(ctx android.TopDownMutatorContext) { - if m, ok := ctx.Module().(*Module); ok { - name := "__bp2build__" + m.Name() - // Bazel only has the "tools" attribute. - tools := append(m.properties.Tools, m.properties.Tool_files...) - - // Replace in and out variables with $< and $@ - var cmd string - if m.properties.Cmd != nil { - cmd = strings.Replace(*m.properties.Cmd, "$(in)", "$(SRCS)", -1) - cmd = strings.Replace(cmd, "$(out)", "$(OUTS)", -1) - cmd = strings.Replace(cmd, "$(genDir)", "$(GENDIR)", -1) - if len(tools) > 0 { - cmd = strings.Replace(cmd, "$(location)", fmt.Sprintf("$(location %s)", tools[0]), -1) - cmd = strings.Replace(cmd, "$(locations)", fmt.Sprintf("$(locations %s)", tools[0]), -1) - } - } - - // The Out prop is not in an immediately accessible field - // in the Module struct, so use GetProperties and cast it - // to the known struct prop. - var outs []string - for _, propIntf := range m.GetProperties() { - if props, ok := propIntf.(*genRuleProperties); ok { - outs = props.Out - break - } - } - - // Create the BazelTargetModule. - ctx.CreateModule(BazelGenruleFactory, &bazelGenruleAttributes{ - Name: proptools.StringPtr(name), - Srcs: m.properties.Srcs, - Outs: outs, - Cmd: cmd, - Tools: tools, - }, &bazel.BazelTargetModuleProperties{ - Rule_class: "genrule", - }) + m, ok := ctx.Module().(*Module) + if !ok { + return } + name := "__bp2build__" + m.Name() + // Bazel only has the "tools" attribute. + tools := android.BazelLabelForModuleDeps(ctx, m.properties.Tools) + tool_files := android.BazelLabelForModuleSrc(ctx, m.properties.Tool_files) + tools.Append(tool_files) + + srcs := android.BazelLabelForModuleSrc(ctx, m.properties.Srcs) + + var allReplacements bazel.LabelList + allReplacements.Append(tools) + allReplacements.Append(srcs) + + // Replace in and out variables with $< and $@ + var cmd string + if m.properties.Cmd != nil { + cmd = strings.Replace(*m.properties.Cmd, "$(in)", "$(SRCS)", -1) + cmd = strings.Replace(cmd, "$(out)", "$(OUTS)", -1) + cmd = strings.Replace(cmd, "$(genDir)", "$(GENDIR)", -1) + if len(tools.Includes) > 0 { + cmd = strings.Replace(cmd, "$(location)", fmt.Sprintf("$(location %s)", tools.Includes[0].Label), -1) + cmd = strings.Replace(cmd, "$(locations)", fmt.Sprintf("$(locations %s)", tools.Includes[0].Label), -1) + } + for _, l := range allReplacements.Includes { + bpLoc := fmt.Sprintf("$(location %s)", l.Bp_text) + bpLocs := fmt.Sprintf("$(locations %s)", l.Bp_text) + bazelLoc := fmt.Sprintf("$(location %s)", l.Label) + bazelLocs := fmt.Sprintf("$(locations %s)", l.Label) + cmd = strings.Replace(cmd, bpLoc, bazelLoc, -1) + cmd = strings.Replace(cmd, bpLocs, bazelLocs, -1) + } + } + + // The Out prop is not in an immediately accessible field + // in the Module struct, so use GetProperties and cast it + // to the known struct prop. + var outs []string + for _, propIntf := range m.GetProperties() { + if props, ok := propIntf.(*genRuleProperties); ok { + outs = props.Out + break + } + } + + // Create the BazelTargetModule. + ctx.CreateModule(BazelGenruleFactory, &bazelGenruleAttributes{ + Name: proptools.StringPtr(name), + Srcs: srcs, + Outs: outs, + Cmd: cmd, + Tools: tools, + }, &bazel.BazelTargetModuleProperties{ + Rule_class: "genrule", + }) } func (m *bazelGenrule) Name() string { diff --git a/java/java.go b/java/java.go index d49b64f66..b5e49afed 100644 --- a/java/java.go +++ b/java/java.go @@ -2687,9 +2687,10 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { } func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { - if ctx.Arch().ArchType == android.Common { + if ctx.Arch().ArchType == android.Common || ctx.BazelConversionMode() { j.deps(ctx) - } else { + } + if ctx.Arch().ArchType != android.Common || ctx.BazelConversionMode() { // These dependencies ensure the host installation rules will install the jar file and // the jni libraries when the wrapper is installed. ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) diff --git a/java/proto.go b/java/proto.go index dc5519f41..652a4daec 100644 --- a/java/proto.go +++ b/java/proto.go @@ -82,7 +82,7 @@ func protoDeps(ctx android.BottomUpMutatorContext, p *android.ProtoProperties) { case "lite", "": ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-lite") case "full": - if ctx.Host() { + if ctx.Host() || ctx.BazelConversionMode() { ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-full") } else { ctx.PropertyErrorf("proto.type", "full java protos only supported on the host") diff --git a/rust/binary.go b/rust/binary.go index 2963a37af..0334accef 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -132,7 +132,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path return outputFile } -func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep { +func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { // Binaries default to dylib dependencies for device, rlib for host. if binary.preferRlib() { return rlibAutoDep diff --git a/rust/fuzz.go b/rust/fuzz.go index da8f209fc..6035e68ab 100644 --- a/rust/fuzz.go +++ b/rust/fuzz.go @@ -91,6 +91,6 @@ func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage { return RlibLinkage } -func (fuzzer *fuzzDecorator) autoDep(ctx BaseModuleContext) autoDep { +func (fuzzer *fuzzDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { return rlibAutoDep } diff --git a/rust/library.go b/rust/library.go index 643328564..b5749a2de 100644 --- a/rust/library.go +++ b/rust/library.go @@ -219,13 +219,17 @@ func (library *libraryDecorator) setSource() { library.MutatedProperties.VariantIsSource = true } -func (library *libraryDecorator) autoDep(ctx BaseModuleContext) autoDep { +func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { if library.preferRlib() { return rlibAutoDep } else if library.rlib() || library.static() { return rlibAutoDep } else if library.dylib() || library.shared() { return dylibAutoDep + } else if ctx.BazelConversionMode() { + // In Bazel conversion mode, we are currently ignoring the deptag, so we just need to supply a + // compatible tag in order to add the dependency. + return rlibAutoDep } else { panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName())) } diff --git a/rust/proc_macro.go b/rust/proc_macro.go index f753e7f43..115045ac6 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -79,6 +79,6 @@ func (procMacro *procMacroDecorator) getStem(ctx ModuleContext) string { return stem + String(procMacro.baseCompiler.Properties.Suffix) } -func (procMacro *procMacroDecorator) autoDep(ctx BaseModuleContext) autoDep { +func (procMacro *procMacroDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { return rlibAutoDep } diff --git a/rust/rust.go b/rust/rust.go index 2ef9daf0d..504b7a9bd 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -785,7 +785,7 @@ var ( ) type autoDeppable interface { - autoDep(ctx BaseModuleContext) autoDep + autoDep(ctx android.BottomUpMutatorContext) autoDep } func (mod *Module) begin(ctx BaseModuleContext) { diff --git a/rust/test.go b/rust/test.go index 92b486070..3fa5f954a 100644 --- a/rust/test.go +++ b/rust/test.go @@ -141,7 +141,7 @@ func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { return flags } -func (test *testDecorator) autoDep(ctx BaseModuleContext) autoDep { +func (test *testDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { return rlibAutoDep } diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 18749b533..66e493bf1 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -154,9 +154,6 @@ func (s *ShBinary) HostToolPath() android.OptionalPath { } func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) { - if s.properties.Src == nil { - ctx.PropertyErrorf("src", "missing prebuilt source file") - } } func (s *ShBinary) OutputFile() android.OutputPath { @@ -203,6 +200,10 @@ func (s *ShBinary) SetImageVariation(ctx android.BaseModuleContext, variation st } func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) { + if s.properties.Src == nil { + ctx.PropertyErrorf("src", "missing prebuilt source file") + } + s.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(s.properties.Src)) filename := proptools.String(s.properties.Filename) filenameFromSrc := proptools.Bool(s.properties.Filename_from_src) @@ -275,7 +276,7 @@ func (s *ShTest) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddFarVariationDependencies(ctx.Target().Variations(), shTestDataBinsTag, s.testProperties.Data_bins...) ctx.AddFarVariationDependencies(append(ctx.Target().Variations(), sharedLibVariations...), shTestDataLibsTag, s.testProperties.Data_libs...) - if ctx.Target().Os.Class == android.Host && len(ctx.Config().Targets[android.Android]) > 0 { + if (ctx.Target().Os.Class == android.Host || ctx.BazelConversionMode()) && len(ctx.Config().Targets[android.Android]) > 0 { deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() ctx.AddFarVariationDependencies(deviceVariations, shTestDataDeviceBinsTag, s.testProperties.Data_device_bins...) ctx.AddFarVariationDependencies(append(deviceVariations, sharedLibVariations...),