Partial bp2build conversion of blueprint_go_binary
This module type does not implement android.Module, and therefore we cannot write a conventional bp2build converter for this module type. Instead this has been special-cased inside bp2build/build_conversion.go. There is one major deviation between Soong and Bazel's go_binary/go_library. Soong collects the deps in the transitve closure and puts them on compile/link paths. Bazel OTOH, requires the direct imports to be listed in deps of the binary explicitly (AFAIK). Since bp2build cannot determine the list of direct imports from the list of transitive deps, put all the transitive deps in `deps` Test: unit tests Test: TH Bug: 284483729 Change-Id: I004aaf8607fef1697a0d9e7d018ad657b67778ac
This commit is contained in:
@@ -356,12 +356,23 @@ func generateBazelTargetsGoPackage(ctx *android.Context, g *bootstrap.GoPackage,
|
|||||||
ca := android.CommonAttributes{
|
ca := android.CommonAttributes{
|
||||||
Name: g.Name(),
|
Name: g.Name(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For this bootstrap_go_package dep chain,
|
||||||
|
// A --> B --> C ( ---> depends on)
|
||||||
|
// Soong provides the convenience of only listing B as deps of A even if a src file of A imports C
|
||||||
|
// Bazel OTOH
|
||||||
|
// 1. requires C to be listed in `deps` expllicity.
|
||||||
|
// 2. does not require C to be listed if src of A does not import C
|
||||||
|
//
|
||||||
|
// bp2build does not have sufficient info on whether C is a direct dep of A or not, so for now collect all transitive deps and add them to deps
|
||||||
|
transitiveDeps := transitiveGoDeps(g.Deps(), goModulesMap)
|
||||||
|
|
||||||
ga := goAttributes{
|
ga := goAttributes{
|
||||||
Importpath: bazel.StringAttribute{
|
Importpath: bazel.StringAttribute{
|
||||||
Value: proptools.StringPtr(g.GoPkgPath()),
|
Value: proptools.StringPtr(g.GoPkgPath()),
|
||||||
},
|
},
|
||||||
Srcs: goSrcLabels(g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs()),
|
Srcs: goSrcLabels(g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs()),
|
||||||
Deps: goDepLabels(g.Deps(), goModulesMap),
|
Deps: goDepLabels(transitiveDeps, goModulesMap),
|
||||||
Target_compatible_with: targetNotCompatibleWithAndroid(),
|
Target_compatible_with: targetNotCompatibleWithAndroid(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +415,55 @@ func createGoLibraryModuleMap(ctx *android.Context) nameToGoLibraryModule {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the deps in the transitive closure of a go target
|
||||||
|
func transitiveGoDeps(directDeps []string, goModulesMap nameToGoLibraryModule) []string {
|
||||||
|
allDeps := directDeps
|
||||||
|
i := 0
|
||||||
|
for i < len(allDeps) {
|
||||||
|
curr := allDeps[i]
|
||||||
|
allDeps = append(allDeps, goModulesMap[curr].Deps...)
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
allDeps = android.SortedUniqueStrings(allDeps)
|
||||||
|
return allDeps
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateBazelTargetsGoBinary(ctx *android.Context, g *bootstrap.GoBinary, goModulesMap nameToGoLibraryModule) ([]BazelTarget, []error) {
|
||||||
|
ca := android.CommonAttributes{
|
||||||
|
Name: g.Name(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// For this bootstrap_go_package dep chain,
|
||||||
|
// A --> B --> C ( ---> depends on)
|
||||||
|
// Soong provides the convenience of only listing B as deps of A even if a src file of A imports C
|
||||||
|
// Bazel OTOH
|
||||||
|
// 1. requires C to be listed in `deps` expllicity.
|
||||||
|
// 2. does not require C to be listed if src of A does not import C
|
||||||
|
//
|
||||||
|
// bp2build does not have sufficient info on whether C is a direct dep of A or not, so for now collect all transitive deps and add them to deps
|
||||||
|
transitiveDeps := transitiveGoDeps(g.Deps(), goModulesMap)
|
||||||
|
|
||||||
|
ga := goAttributes{
|
||||||
|
Srcs: goSrcLabels(g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs()),
|
||||||
|
Deps: goDepLabels(transitiveDeps, goModulesMap),
|
||||||
|
Target_compatible_with: targetNotCompatibleWithAndroid(),
|
||||||
|
}
|
||||||
|
|
||||||
|
bin := goBazelTarget{
|
||||||
|
targetName: g.Name(),
|
||||||
|
targetPackage: ctx.ModuleDir(g),
|
||||||
|
bazelRuleClass: "go_binary",
|
||||||
|
bazelRuleLoadLocation: "@io_bazel_rules_go//go:def.bzl",
|
||||||
|
bazelAttributes: []interface{}{&ca, &ga},
|
||||||
|
}
|
||||||
|
// TODO - b/284483729: Create go_test target from testSrcs
|
||||||
|
binTarget, err := generateBazelTarget(ctx, bin)
|
||||||
|
if err != nil {
|
||||||
|
return []BazelTarget{}, []error{err}
|
||||||
|
}
|
||||||
|
return []BazelTarget{binTarget}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (conversionResults, []error) {
|
func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (conversionResults, []error) {
|
||||||
buildFileToTargets := make(map[string]BazelTargets)
|
buildFileToTargets := make(map[string]BazelTargets)
|
||||||
|
|
||||||
@@ -496,8 +556,10 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
|
|||||||
targets, targetErrs = generateBazelTargetsGoPackage(bpCtx, glib, nameToGoLibMap)
|
targets, targetErrs = generateBazelTargetsGoPackage(bpCtx, glib, nameToGoLibMap)
|
||||||
errs = append(errs, targetErrs...)
|
errs = append(errs, targetErrs...)
|
||||||
metrics.IncrementRuleClassCount("go_library")
|
metrics.IncrementRuleClassCount("go_library")
|
||||||
} else if _, ok := m.(*bootstrap.GoBinary); ok {
|
} else if gbin, ok := m.(*bootstrap.GoBinary); ok {
|
||||||
// TODO - b/284483729: Create bazel targets for go binaries
|
targets, targetErrs = generateBazelTargetsGoBinary(bpCtx, gbin, nameToGoLibMap)
|
||||||
|
errs = append(errs, targetErrs...)
|
||||||
|
metrics.IncrementRuleClassCount("go_binary")
|
||||||
} else {
|
} else {
|
||||||
metrics.AddUnconvertedModule(m, moduleType, dir, android.UnconvertedReason{
|
metrics.AddUnconvertedModule(m, moduleType, dir, android.UnconvertedReason{
|
||||||
ReasonType: int(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED),
|
ReasonType: int(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED),
|
||||||
|
@@ -87,3 +87,40 @@ bootstrap_go_package {
|
|||||||
)},
|
)},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConvertGoBinaryWithTransitiveDeps(t *testing.T) {
|
||||||
|
bp := `
|
||||||
|
blueprint_go_binary {
|
||||||
|
name: "foo",
|
||||||
|
srcs: ["main.go"],
|
||||||
|
deps: ["bar"],
|
||||||
|
}
|
||||||
|
`
|
||||||
|
depBp := `
|
||||||
|
bootstrap_go_package {
|
||||||
|
name: "bar",
|
||||||
|
deps: ["baz"],
|
||||||
|
}
|
||||||
|
bootstrap_go_package {
|
||||||
|
name: "baz",
|
||||||
|
}
|
||||||
|
`
|
||||||
|
t.Parallel()
|
||||||
|
runGoTests(t, Bp2buildTestCase{
|
||||||
|
Description: "Convert blueprint_go_binary to go_binary",
|
||||||
|
Blueprint: bp,
|
||||||
|
Filesystem: map[string]string{
|
||||||
|
"bar/Android.bp": depBp, // Put dep in Android.bp to reduce boilerplate in ExpectedBazelTargets
|
||||||
|
},
|
||||||
|
ExpectedBazelTargets: []string{makeBazelTargetHostOrDevice("go_binary", "foo",
|
||||||
|
AttrNameToString{
|
||||||
|
"deps": `[
|
||||||
|
"//bar:bar",
|
||||||
|
"//bar:baz",
|
||||||
|
]`,
|
||||||
|
"srcs": `[":main.go"]`,
|
||||||
|
},
|
||||||
|
android.HostSupported,
|
||||||
|
)},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user