bp2build converts java_genrule and java_genrule_host

Bp2build currently supports building genrules for cc modules, but does
not support building java_genrule* modules. This commit adds this
functionality.

Bug: 213480907
Test: go test ./bp2build
Change-Id: I473196c5bcf5582ba0c8faa65b5005f81ac973a4
This commit is contained in:
Sam Delmerico 2022-01-11 21:55:46 +00:00
parent 341f73550d
commit cd1b80f067
8 changed files with 476 additions and 405 deletions

View file

@ -468,9 +468,13 @@ var (
"libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
// go deps:
"apex-protos", // depends on unconverted modules: soong_zip
"apex-protos", // depends on soong_zip, a go binary
"robolectric_tzdata", // depends on soong_zip, a go binary
"host_bionic_linker_asm", // depends on extract_linker, a go binary.
"host_bionic_linker_script", // depends on extract_linker, a go binary.
// java deps
"bin2c_fastdeployagent", // depends on deployagent, a java binary
}
// Per-module denylist of cc_library modules to only generate the static

View file

@ -38,7 +38,6 @@ bootstrap_go_package {
"build_conversion_test.go",
"bzl_conversion_test.go",
"cc_binary_conversion_test.go",
"cc_genrule_conversion_test.go",
"cc_library_conversion_test.go",
"cc_library_headers_conversion_test.go",
"cc_library_shared_conversion_test.go",

View file

@ -1,235 +0,0 @@
// Copyright 2021 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package bp2build
import (
"testing"
"android/soong/android"
"android/soong/cc"
)
var otherCcGenruleBp = map[string]string{
"other/Android.bp": `cc_genrule {
name: "foo.tool",
out: ["foo_tool.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
}
cc_genrule {
name: "other.tool",
out: ["other_tool.out"],
srcs: ["other_tool.in"],
cmd: "cp $(in) $(out)",
}`,
}
func runCcGenruleTestCase(t *testing.T, tc bp2buildTestCase) {
t.Helper()
(&tc).moduleTypeUnderTest = "cc_genrule"
(&tc).moduleTypeUnderTestFactory = cc.GenRuleFactory
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
}
func TestCliVariableReplacement(t *testing.T) {
runCcGenruleTestCase(t, bp2buildTestCase{
description: "cc_genrule with command line variable replacements",
blueprint: `cc_genrule {
name: "foo.tool",
out: ["foo_tool.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
bazel_module: { bp2build_available: true },
}
cc_genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tool"],
cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(location :foo.tool) --genDir=$(RULEDIR) arg $(SRCS) $(OUTS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[":foo.tool"]`,
}),
makeBazelTarget("genrule", "foo.tool", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `["foo_tool.out"]`,
"srcs": `["foo_tool.in"]`,
}),
},
})
}
func TestUsingLocationsLabel(t *testing.T) {
runCcGenruleTestCase(t, bp2buildTestCase{
description: "cc_genrule using $(locations :label)",
blueprint: `cc_genrule {
name: "foo.tools",
out: ["foo_tool.out", "foo_tool2.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
bazel_module: { bp2build_available: true },
}
cc_genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tools"],
cmd: "$(locations :foo.tools) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations :foo.tools) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[":foo.tools"]`,
}),
makeBazelTarget("genrule", "foo.tools", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `[
"foo_tool.out",
"foo_tool2.out",
]`,
"srcs": `["foo_tool.in"]`,
}),
},
})
}
func TestUsingLocationsAbsoluteLabel(t *testing.T) {
runCcGenruleTestCase(t, bp2buildTestCase{
description: "cc_genrule using $(locations //absolute:label)",
blueprint: `cc_genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tool_files: [":foo.tool"],
cmd: "$(locations :foo.tool) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
filesystem: otherCcGenruleBp,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `["//other:foo.tool"]`,
}),
},
})
}
func TestSrcsUsingAbsoluteLabel(t *testing.T) {
runCcGenruleTestCase(t, bp2buildTestCase{
description: "cc_genrule srcs using $(locations //absolute:label)",
blueprint: `cc_genrule {
name: "foo",
out: ["foo.out"],
srcs: [":other.tool"],
tool_files: [":foo.tool"],
cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)",
bazel_module: { bp2build_available: true },
}`,
filesystem: otherCcGenruleBp,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)"`,
"outs": `["foo.out"]`,
"srcs": `["//other:other.tool"]`,
"tools": `["//other:foo.tool"]`,
}),
},
})
}
func TestLocationsLabelUsesFirstToolFile(t *testing.T) {
runCcGenruleTestCase(t, bp2buildTestCase{
description: "cc_genrule using $(location) label should substitute first tool label automatically",
blueprint: `cc_genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tool_files: [":foo.tool", ":other.tool"],
cmd: "$(location) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
filesystem: otherCcGenruleBp,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(location //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[
"//other:foo.tool",
"//other:other.tool",
]`,
}),
},
})
}
func TestLocationsLabelUsesFirstTool(t *testing.T) {
runCcGenruleTestCase(t, bp2buildTestCase{
description: "cc_genrule using $(locations) label should substitute first tool label automatically",
blueprint: `cc_genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tool", ":other.tool"],
cmd: "$(locations) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
filesystem: otherCcGenruleBp,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[
"//other:foo.tool",
"//other:other.tool",
]`,
}),
},
})
}
func TestWithoutToolsOrToolFiles(t *testing.T) {
runCcGenruleTestCase(t, bp2buildTestCase{
description: "cc_genrule without tools or tool_files can convert successfully",
blueprint: `cc_genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
cmd: "cp $(in) $(out)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
}),
},
})
}

View file

@ -16,7 +16,10 @@ package bp2build
import (
"android/soong/android"
"android/soong/cc"
"android/soong/genrule"
"android/soong/java"
"fmt"
"testing"
)
@ -31,58 +34,114 @@ func runGenruleTestCase(t *testing.T, tc bp2buildTestCase) {
runBp2BuildTestCase(t, registerGenruleModuleTypes, tc)
}
func TestGenruleBp2Build(t *testing.T) {
otherGenruleBp := map[string]string{
"other/Android.bp": `genrule {
func otherGenruleBp(genruleTarget string) map[string]string {
return map[string]string{
"other/Android.bp": fmt.Sprintf(`%s {
name: "foo.tool",
out: ["foo_tool.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
}
genrule {
%s {
name: "other.tool",
out: ["other_tool.out"],
srcs: ["other_tool.in"],
cmd: "cp $(in) $(out)",
}`,
}`, genruleTarget, genruleTarget),
}
}
func TestGenruleCliVariableReplacement(t *testing.T) {
testCases := []struct {
moduleType string
factory android.ModuleFactory
genDir string
}{
{
moduleType: "genrule",
factory: genrule.GenRuleFactory,
genDir: "$(GENDIR)",
},
{
moduleType: "cc_genrule",
factory: cc.GenRuleFactory,
genDir: "$(RULEDIR)",
},
{
moduleType: "java_genrule",
factory: java.GenRuleFactory,
genDir: "$(RULEDIR)",
},
{
moduleType: "java_genrule_host",
factory: java.GenRuleFactoryHost,
genDir: "$(RULEDIR)",
},
}
testCases := []bp2buildTestCase{
{
description: "genrule with command line variable replacements",
blueprint: `genrule {
bp := `%s {
name: "foo.tool",
out: ["foo_tool.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
bazel_module: { bp2build_available: true },
bazel_module: { bp2build_available: false },
}
genrule {
%s {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tool"],
cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(location :foo.tool) --genDir=$(GENDIR) arg $(SRCS) $(OUTS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[":foo.tool"]`,
}),
makeBazelTarget("genrule", "foo.tool", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `["foo_tool.out"]`,
"srcs": `["foo_tool.in"]`,
}),
},
}`
for _, tc := range testCases {
expectedBazelTargets := []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": fmt.Sprintf(`"$(location :foo.tool) --genDir=%s arg $(SRCS) $(OUTS)"`, tc.genDir),
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[":foo.tool"]`,
}),
}
t.Run(tc.moduleType, func(t *testing.T) {
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
bp2buildTestCase{
moduleTypeUnderTest: tc.moduleType,
moduleTypeUnderTestFactory: tc.factory,
blueprint: fmt.Sprintf(bp, tc.moduleType, tc.moduleType),
expectedBazelTargets: expectedBazelTargets,
})
})
}
}
func TestGenruleLocationsLabel(t *testing.T) {
testCases := []struct {
moduleType string
factory android.ModuleFactory
}{
{
moduleType: "genrule",
factory: genrule.GenRuleFactory,
},
{
description: "genrule using $(locations :label)",
blueprint: `genrule {
moduleType: "cc_genrule",
factory: cc.GenRuleFactory,
},
{
moduleType: "java_genrule",
factory: java.GenRuleFactory,
},
{
moduleType: "java_genrule_host",
factory: java.GenRuleFactoryHost,
},
}
bp := `%s {
name: "foo.tools",
out: ["foo_tool.out", "foo_tool2.out"],
srcs: ["foo_tool.in"],
@ -90,144 +149,322 @@ genrule {
bazel_module: { bp2build_available: true },
}
genrule {
%s {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tools"],
cmd: "$(locations :foo.tools) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations :foo.tools) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[":foo.tools"]`,
}),
makeBazelTarget("genrule", "foo.tools", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `[
}`
expectedBazelTargets :=
[]string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations :foo.tools) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[":foo.tools"]`,
}),
makeBazelTarget("genrule", "foo.tools", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `[
"foo_tool.out",
"foo_tool2.out",
]`,
"srcs": `["foo_tool.in"]`,
}),
},
"srcs": `["foo_tool.in"]`,
}),
}
for _, tc := range testCases {
t.Run(tc.moduleType, func(t *testing.T) {
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
bp2buildTestCase{
moduleTypeUnderTest: tc.moduleType,
moduleTypeUnderTestFactory: tc.factory,
blueprint: fmt.Sprintf(bp, tc.moduleType, tc.moduleType),
expectedBazelTargets: expectedBazelTargets,
})
})
}
}
func TestGenruleLocationsAbsoluteLabel(t *testing.T) {
testCases := []struct {
moduleType string
factory android.ModuleFactory
}{
{
moduleType: "genrule",
factory: genrule.GenRuleFactory,
},
{
description: "genrule using $(locations //absolute:label)",
blueprint: `genrule {
moduleType: "cc_genrule",
factory: cc.GenRuleFactory,
},
{
moduleType: "java_genrule",
factory: java.GenRuleFactory,
},
{
moduleType: "java_genrule_host",
factory: java.GenRuleFactoryHost,
},
}
bp := `%s {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tool_files: [":foo.tool"],
cmd: "$(locations :foo.tool) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `["//other:foo.tool"]`,
}),
},
filesystem: otherGenruleBp,
}`
expectedBazelTargets := []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `["//other:foo.tool"]`,
}),
}
for _, tc := range testCases {
t.Run(tc.moduleType, func(t *testing.T) {
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
bp2buildTestCase{
moduleTypeUnderTest: tc.moduleType,
moduleTypeUnderTestFactory: tc.factory,
blueprint: fmt.Sprintf(bp, tc.moduleType),
expectedBazelTargets: expectedBazelTargets,
filesystem: otherGenruleBp(tc.moduleType),
})
})
}
}
func TestGenruleSrcsLocationsAbsoluteLabel(t *testing.T) {
testCases := []struct {
moduleType string
factory android.ModuleFactory
}{
{
moduleType: "genrule",
factory: genrule.GenRuleFactory,
},
{
description: "genrule srcs using $(locations //absolute:label)",
blueprint: `genrule {
moduleType: "cc_genrule",
factory: cc.GenRuleFactory,
},
{
moduleType: "java_genrule",
factory: java.GenRuleFactory,
},
{
moduleType: "java_genrule_host",
factory: java.GenRuleFactoryHost,
},
}
bp := `%s {
name: "foo",
out: ["foo.out"],
srcs: [":other.tool"],
tool_files: [":foo.tool"],
cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)"`,
"outs": `["foo.out"]`,
"srcs": `["//other:other.tool"]`,
"tools": `["//other:foo.tool"]`,
}),
},
filesystem: otherGenruleBp,
}`
expectedBazelTargets := []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)"`,
"outs": `["foo.out"]`,
"srcs": `["//other:other.tool"]`,
"tools": `["//other:foo.tool"]`,
}),
}
for _, tc := range testCases {
t.Run(tc.moduleType, func(t *testing.T) {
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
bp2buildTestCase{
moduleTypeUnderTest: tc.moduleType,
moduleTypeUnderTestFactory: tc.factory,
blueprint: fmt.Sprintf(bp, tc.moduleType),
expectedBazelTargets: expectedBazelTargets,
filesystem: otherGenruleBp(tc.moduleType),
})
})
}
}
func TestGenruleLocationLabelShouldSubstituteFirstToolLabel(t *testing.T) {
testCases := []struct {
moduleType string
factory android.ModuleFactory
}{
{
moduleType: "genrule",
factory: genrule.GenRuleFactory,
},
{
description: "genrule using $(location) label should substitute first tool label automatically",
blueprint: `genrule {
moduleType: "cc_genrule",
factory: cc.GenRuleFactory,
},
{
moduleType: "java_genrule",
factory: java.GenRuleFactory,
},
{
moduleType: "java_genrule_host",
factory: java.GenRuleFactoryHost,
},
}
bp := `%s {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tool_files: [":foo.tool", ":other.tool"],
cmd: "$(location) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(location //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[
}`
expectedBazelTargets := []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(location //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[
"//other:foo.tool",
"//other:other.tool",
]`,
}),
},
filesystem: otherGenruleBp,
})}
for _, tc := range testCases {
t.Run(tc.moduleType, func(t *testing.T) {
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
bp2buildTestCase{
moduleTypeUnderTest: tc.moduleType,
moduleTypeUnderTestFactory: tc.factory,
blueprint: fmt.Sprintf(bp, tc.moduleType),
expectedBazelTargets: expectedBazelTargets,
filesystem: otherGenruleBp(tc.moduleType),
})
})
}
}
func TestGenruleLocationsLabelShouldSubstituteFirstToolLabel(t *testing.T) {
testCases := []struct {
moduleType string
factory android.ModuleFactory
}{
{
moduleType: "genrule",
factory: genrule.GenRuleFactory,
},
{
description: "genrule using $(locations) label should substitute first tool label automatically",
blueprint: `genrule {
moduleType: "cc_genrule",
factory: cc.GenRuleFactory,
},
{
moduleType: "java_genrule",
factory: java.GenRuleFactory,
},
{
moduleType: "java_genrule_host",
factory: java.GenRuleFactoryHost,
},
}
bp := `%s {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tool", ":other.tool"],
tool_files: [":foo.tool", ":other.tool"],
cmd: "$(locations) -s $(out) $(in)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[
}`
expectedBazelTargets := []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(SRCS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
"tools": `[
"//other:foo.tool",
"//other:other.tool",
]`,
}),
},
filesystem: otherGenruleBp,
})}
for _, tc := range testCases {
t.Run(tc.moduleType, func(t *testing.T) {
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
bp2buildTestCase{
moduleTypeUnderTest: tc.moduleType,
moduleTypeUnderTestFactory: tc.factory,
blueprint: fmt.Sprintf(bp, tc.moduleType),
expectedBazelTargets: expectedBazelTargets,
filesystem: otherGenruleBp(tc.moduleType),
})
})
}
}
func TestGenruleWithoutToolsOrToolFiles(t *testing.T) {
testCases := []struct {
moduleType string
factory android.ModuleFactory
}{
{
moduleType: "genrule",
factory: genrule.GenRuleFactory,
},
{
description: "genrule without tools or tool_files can convert successfully",
blueprint: `genrule {
moduleType: "cc_genrule",
factory: cc.GenRuleFactory,
},
{
moduleType: "java_genrule",
factory: java.GenRuleFactory,
},
{
moduleType: "java_genrule_host",
factory: java.GenRuleFactoryHost,
},
}
bp := `%s {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
cmd: "cp $(in) $(out)",
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
}),
},
},
}
}`
for _, testCase := range testCases {
t.Run(testCase.description, func(t *testing.T) {
runGenruleTestCase(t, testCase)
expectedBazelTargets := []string{
makeBazelTarget("genrule", "foo", attrNameToString{
"cmd": `"cp $(SRCS) $(OUTS)"`,
"outs": `["foo.out"]`,
"srcs": `["foo.in"]`,
})}
for _, tc := range testCases {
t.Run(tc.moduleType, func(t *testing.T) {
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
bp2buildTestCase{
moduleTypeUnderTest: tc.moduleType,
moduleTypeUnderTestFactory: tc.factory,
blueprint: fmt.Sprintf(bp, tc.moduleType),
expectedBazelTargets: expectedBazelTargets,
})
})
}
}
func TestBp2BuildInlinesDefaults(t *testing.T) {
func TestGenruleBp2BuildInlinesDefaults(t *testing.T) {
testCases := []bp2buildTestCase{
{
description: "genrule applies properties from a genrule_defaults dependency if not specified",

View file

@ -862,7 +862,7 @@ func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
cmd = strings.Replace(*m.properties.Cmd, "$(in)", "$(SRCS)", -1)
cmd = strings.Replace(cmd, "$(out)", "$(OUTS)", -1)
genDir := "$(GENDIR)"
if ctx.ModuleType() == "cc_genrule" {
if t := ctx.ModuleType(); t == "cc_genrule" || t == "java_genrule" || t == "java_genrule_host" {
genDir = "$(RULEDIR)"
}
cmd = strings.Replace(cmd, "$(genDir)", genDir, -1)

View file

@ -24,8 +24,8 @@ func init() {
}
func RegisterGenRuleBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_genrule", genRuleFactory)
ctx.RegisterModuleType("java_genrule_host", genRuleFactoryHost)
ctx.RegisterModuleType("java_genrule", GenRuleFactory)
ctx.RegisterModuleType("java_genrule_host", GenRuleFactoryHost)
}
// java_genrule is a genrule that can depend on other java_* objects.
@ -33,7 +33,7 @@ func RegisterGenRuleBuildComponents(ctx android.RegistrationContext) {
// By default a java_genrule has a single variant that will run against the device variant of its dependencies and
// produce an output that can be used as an input to a device java rule.
//
// Specifying `host_supported: true` will produce two variants, one that uses device dependencie sand one that uses
// Specifying `host_supported: true` will produce two variants, one that uses device dependencies and one that uses
// host dependencies. Each variant will run the command.
//
// Use a java_genrule instead of a genrule when it needs to depend on or be depended on by other java modules, unless
@ -44,7 +44,7 @@ func RegisterGenRuleBuildComponents(ctx android.RegistrationContext) {
// Use a java_genrule to package generated java resources:
//
// java_genrule {
// name: "generated_resources",
// name: "generated_resources",
// tools: [
// "generator",
// "soong_zip",
@ -60,11 +60,12 @@ func RegisterGenRuleBuildComponents(ctx android.RegistrationContext) {
// srcs: ["src/**/*.java"],
// static_libs: ["generated_resources"],
// }
func genRuleFactory() android.Module {
func GenRuleFactory() android.Module {
module := genrule.NewGenRule()
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitBazelModule(module)
return module
}
@ -73,11 +74,12 @@ func genRuleFactory() android.Module {
//
// A java_genrule_host has a single variant that will run against the host variant of its dependencies and
// produce an output that can be used as an input to a host java rule.
func genRuleFactoryHost() android.Module {
func GenRuleFactoryHost() android.Module {
module := genrule.NewGenRule()
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitBazelModule(module)
return module
}

118
java/genrule_test.go Normal file
View file

@ -0,0 +1,118 @@
// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package java
import (
"reflect"
"strings"
"testing"
"android/soong/android"
)
func testGenruleContext(config android.Config) *android.TestContext {
ctx := android.NewTestArchContext(config)
ctx.RegisterModuleType("java_genrule", GenRuleFactory)
ctx.Register()
return ctx
}
func TestGenruleCmd(t *testing.T) {
fs := map[string][]byte{
"tool": nil,
"foo": nil,
}
bp := `
java_genrule {
name: "gen",
tool_files: ["tool"],
cmd: "$(location tool) $(in) $(out)",
srcs: ["foo"],
out: ["out"],
}
`
config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
ctx := testGenruleContext(config)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
if errs == nil {
_, errs = ctx.PrepareBuildActions(config)
}
if errs != nil {
t.Fatal(errs)
}
gen := ctx.ModuleForTests("gen", "android_common").Output("out")
expected := []string{"foo"}
if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
t.Errorf(`want arm inputs %v, got %v`, expected, gen.Implicits.Strings())
}
}
func TestJarGenrules(t *testing.T) {
ctx, _ := testJava(t, `
java_library {
name: "foo",
srcs: ["a.java"],
}
java_genrule {
name: "jargen",
tool_files: ["b.java"],
cmd: "$(location b.java) $(in) $(out)",
out: ["jargen.jar"],
srcs: [":foo"],
}
java_library {
name: "bar",
static_libs: ["jargen"],
srcs: ["c.java"],
}
java_library {
name: "baz",
libs: ["jargen"],
srcs: ["c.java"],
}
`)
foo := ctx.ModuleForTests("foo", "android_common").Output("javac/foo.jar")
jargen := ctx.ModuleForTests("jargen", "android_common").Output("jargen.jar")
bar := ctx.ModuleForTests("bar", "android_common").Output("javac/bar.jar")
baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
if g, w := jargen.Implicits.Strings(), foo.Output.String(); !android.InList(w, g) {
t.Errorf("expected jargen inputs [%q], got %q", w, g)
}
if !strings.Contains(bar.Args["classpath"], jargen.Output.String()) {
t.Errorf("bar classpath %v does not contain %q", bar.Args["classpath"], jargen.Output.String())
}
if !strings.Contains(baz.Args["classpath"], jargen.Output.String()) {
t.Errorf("baz classpath %v does not contain %q", baz.Args["classpath"], jargen.Output.String())
}
if len(barCombined.Inputs) != 2 ||
barCombined.Inputs[0].String() != bar.Output.String() ||
barCombined.Inputs[1].String() != jargen.Output.String() {
t.Errorf("bar combined jar inputs %v is not [%q, %q]",
barCombined.Inputs.Strings(), bar.Output.String(), jargen.Output.String())
}
}

View file

@ -997,60 +997,6 @@ func TestSharding(t *testing.T) {
}
}
func TestJarGenrules(t *testing.T) {
ctx, _ := testJava(t, `
java_library {
name: "foo",
srcs: ["a.java"],
}
java_genrule {
name: "jargen",
tool_files: ["b.java"],
cmd: "$(location b.java) $(in) $(out)",
out: ["jargen.jar"],
srcs: [":foo"],
}
java_library {
name: "bar",
static_libs: ["jargen"],
srcs: ["c.java"],
}
java_library {
name: "baz",
libs: ["jargen"],
srcs: ["c.java"],
}
`)
foo := ctx.ModuleForTests("foo", "android_common").Output("javac/foo.jar")
jargen := ctx.ModuleForTests("jargen", "android_common").Output("jargen.jar")
bar := ctx.ModuleForTests("bar", "android_common").Output("javac/bar.jar")
baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
if g, w := jargen.Implicits.Strings(), foo.Output.String(); !android.InList(w, g) {
t.Errorf("expected jargen inputs [%q], got %q", w, g)
}
if !strings.Contains(bar.Args["classpath"], jargen.Output.String()) {
t.Errorf("bar classpath %v does not contain %q", bar.Args["classpath"], jargen.Output.String())
}
if !strings.Contains(baz.Args["classpath"], jargen.Output.String()) {
t.Errorf("baz classpath %v does not contain %q", baz.Args["classpath"], jargen.Output.String())
}
if len(barCombined.Inputs) != 2 ||
barCombined.Inputs[0].String() != bar.Output.String() ||
barCombined.Inputs[1].String() != jargen.Output.String() {
t.Errorf("bar combined jar inputs %v is not [%q, %q]",
barCombined.Inputs.Strings(), bar.Output.String(), jargen.Output.String())
}
}
func TestExcludeFileGroupInSrcs(t *testing.T) {
ctx, _ := testJava(t, `
java_library {