diff --git a/bp2build/Android.bp b/bp2build/Android.bp index 800757446..2bbe4b53c 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -11,6 +11,7 @@ bootstrap_go_package { deps: [ "soong-android", "soong-bazel", + "soong-genrule", ], testSrcs: [ "build_conversion_test.go", diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index 2df72bda6..e4edc3ea2 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -16,6 +16,7 @@ package bp2build import ( "android/soong/android" + "android/soong/genrule" "testing" ) @@ -300,6 +301,54 @@ func TestModuleTypeBp2Build(t *testing.T) { "a", "b", ], +)`, + }, + { + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + bp: `genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tool_files: [":foo.tool"], + cmd: "$(location :foo.tool) arg $(in) $(out)", +}`, + expectedBazelTarget: `genrule( + name = "foo", + cmd = "$(location :foo.tool) arg $(SRCS) $(OUTS)", + outs = [ + "foo.out", + ], + srcs = [ + "foo.in", + ], + tools = [ + ":foo.tool", + ], +)`, + }, + { + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + bp: `genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tools: [":foo.tool"], + cmd: "$(location :foo.tool) --out-dir=$(genDir) $(in)", +}`, + expectedBazelTarget: `genrule( + name = "foo", + cmd = "$(location :foo.tool) --out-dir=$(GENDIR) $(SRCS)", + outs = [ + "foo.out", + ], + srcs = [ + "foo.in", + ], + tools = [ + ":foo.tool", + ], )`, }, } diff --git a/genrule/genrule.go b/genrule/genrule.go index 8df32f2f5..1f47deca4 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -46,6 +46,8 @@ func RegisterGenruleBuildComponents(ctx android.RegistrationContext) { ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel() }) + + android.RegisterBp2BuildMutator("genrule", bp2buildMutator) } var ( @@ -772,6 +774,70 @@ type genRuleProperties struct { Out []string `android:"arch_variant"` } +type bazelGenruleAttributes struct { + Name *string + Srcs []string + Outs []string + Tools []string + Cmd string +} + +type bazelGenrule struct { + android.BazelTargetModuleBase + bazelGenruleAttributes +} + +func BazelGenruleFactory() android.Module { + module := &bazelGenrule{} + module.AddProperties(&module.bazelGenruleAttributes) + android.InitBazelTargetModule(module) + return module +} + +func bp2buildMutator(ctx android.TopDownMutatorContext) { + if m, ok := ctx.Module().(*Module); ok { + name := "__bp2build__" + m.Name() + // 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) + } + + // 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 + } + } + + // Bazel only has the "tools" attribute. + tools := append(m.properties.Tools, m.properties.Tool_files...) + + // 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", + }) + } +} + +func (m *bazelGenrule) Name() string { + return m.BaseModuleName() +} + +func (m *bazelGenrule) GenerateAndroidBuildActions(ctx android.ModuleContext) {} + var Bool = proptools.Bool var String = proptools.String