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
This commit is contained in:
parent
aef038aac1
commit
356f7d45c1
27 changed files with 734 additions and 154 deletions
|
@ -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()
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
110
android/paths.go
110
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
8
cc/cc.go
8
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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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...)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -785,7 +785,7 @@ var (
|
|||
)
|
||||
|
||||
type autoDeppable interface {
|
||||
autoDep(ctx BaseModuleContext) autoDep
|
||||
autoDep(ctx android.BottomUpMutatorContext) autoDep
|
||||
}
|
||||
|
||||
func (mod *Module) begin(ctx BaseModuleContext) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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...),
|
||||
|
|
Loading…
Reference in a new issue