Merge "Direct Bazel builds from m."
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BazelTargetModuleProperties contain properties and metadata used for
|
// BazelTargetModuleProperties contain properties and metadata used for
|
||||||
@@ -33,6 +34,10 @@ type BazelTargetModuleProperties struct {
|
|||||||
|
|
||||||
const BazelTargetModuleNamePrefix = "__bp2build__"
|
const BazelTargetModuleNamePrefix = "__bp2build__"
|
||||||
|
|
||||||
|
func StripNamePrefix(moduleName string) string {
|
||||||
|
return strings.TrimPrefix(moduleName, BazelTargetModuleNamePrefix)
|
||||||
|
}
|
||||||
|
|
||||||
var productVariableSubstitutionPattern = regexp.MustCompile("%(d|s)")
|
var productVariableSubstitutionPattern = regexp.MustCompile("%(d|s)")
|
||||||
|
|
||||||
// Label is used to represent a Bazel compatible Label. Also stores the original
|
// Label is used to represent a Bazel compatible Label. Also stores the original
|
||||||
|
@@ -11,6 +11,7 @@ bootstrap_go_package {
|
|||||||
"build_conversion.go",
|
"build_conversion.go",
|
||||||
"bzl_conversion.go",
|
"bzl_conversion.go",
|
||||||
"configurability.go",
|
"configurability.go",
|
||||||
|
"compatibility.go",
|
||||||
"constants.go",
|
"constants.go",
|
||||||
"conversion.go",
|
"conversion.go",
|
||||||
"metrics.go",
|
"metrics.go",
|
||||||
|
@@ -29,12 +29,12 @@ func Codegen(ctx *CodegenContext) CodegenMetrics {
|
|||||||
bp2buildDir := android.PathForOutput(ctx, "bp2build")
|
bp2buildDir := android.PathForOutput(ctx, "bp2build")
|
||||||
android.RemoveAllOutputDir(bp2buildDir)
|
android.RemoveAllOutputDir(bp2buildDir)
|
||||||
|
|
||||||
buildToTargets, metrics := GenerateBazelTargets(ctx, true)
|
buildToTargets, metrics, compatLayer := GenerateBazelTargets(ctx, true)
|
||||||
bp2buildFiles := CreateBazelFiles(nil, buildToTargets, ctx.mode)
|
bp2buildFiles := CreateBazelFiles(nil, buildToTargets, ctx.mode)
|
||||||
writeFiles(ctx, bp2buildDir, bp2buildFiles)
|
writeFiles(ctx, bp2buildDir, bp2buildFiles)
|
||||||
|
|
||||||
soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
|
soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
|
||||||
writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles())
|
writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(compatLayer))
|
||||||
|
|
||||||
return metrics
|
return metrics
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ type BazelAttributes struct {
|
|||||||
|
|
||||||
type BazelTarget struct {
|
type BazelTarget struct {
|
||||||
name string
|
name string
|
||||||
|
packageName string
|
||||||
content string
|
content string
|
||||||
ruleClass string
|
ruleClass string
|
||||||
bzlLoadLocation string
|
bzlLoadLocation string
|
||||||
@@ -44,6 +45,16 @@ func (t BazelTarget) IsLoadedFromStarlark() bool {
|
|||||||
return t.bzlLoadLocation != ""
|
return t.bzlLoadLocation != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Label is the fully qualified Bazel label constructed from the BazelTarget's
|
||||||
|
// package name and target name.
|
||||||
|
func (t BazelTarget) Label() string {
|
||||||
|
if t.packageName == "." {
|
||||||
|
return "//:" + t.name
|
||||||
|
} else {
|
||||||
|
return "//" + t.packageName + ":" + t.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BazelTargets is a typedef for a slice of BazelTarget objects.
|
// BazelTargets is a typedef for a slice of BazelTarget objects.
|
||||||
type BazelTargets []BazelTarget
|
type BazelTargets []BazelTarget
|
||||||
|
|
||||||
@@ -213,7 +224,7 @@ func propsToAttributes(props map[string]string) string {
|
|||||||
return attributes
|
return attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[string]BazelTargets, CodegenMetrics) {
|
func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[string]BazelTargets, CodegenMetrics, CodegenCompatLayer) {
|
||||||
buildFileToTargets := make(map[string]BazelTargets)
|
buildFileToTargets := make(map[string]BazelTargets)
|
||||||
buildFileToAppend := make(map[string]bool)
|
buildFileToAppend := make(map[string]bool)
|
||||||
|
|
||||||
@@ -222,6 +233,10 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[str
|
|||||||
RuleClassCount: make(map[string]int),
|
RuleClassCount: make(map[string]int),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compatLayer := CodegenCompatLayer{
|
||||||
|
NameToLabelMap: make(map[string]string),
|
||||||
|
}
|
||||||
|
|
||||||
dirs := make(map[string]bool)
|
dirs := make(map[string]bool)
|
||||||
|
|
||||||
bpCtx := ctx.Context()
|
bpCtx := ctx.Context()
|
||||||
@@ -236,6 +251,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[str
|
|||||||
if b, ok := m.(android.Bazelable); ok && b.HasHandcraftedLabel() {
|
if b, ok := m.(android.Bazelable); ok && b.HasHandcraftedLabel() {
|
||||||
metrics.handCraftedTargetCount += 1
|
metrics.handCraftedTargetCount += 1
|
||||||
metrics.TotalModuleCount += 1
|
metrics.TotalModuleCount += 1
|
||||||
|
compatLayer.AddNameToLabelEntry(m.Name(), b.HandcraftedLabel())
|
||||||
pathToBuildFile := getBazelPackagePath(b)
|
pathToBuildFile := getBazelPackagePath(b)
|
||||||
// We are using the entire contents of handcrafted build file, so if multiple targets within
|
// We are using the entire contents of handcrafted build file, so if multiple targets within
|
||||||
// a package have handcrafted targets, we only want to include the contents one time.
|
// a package have handcrafted targets, we only want to include the contents one time.
|
||||||
@@ -253,6 +269,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[str
|
|||||||
} else if btm, ok := m.(android.BazelTargetModule); ok {
|
} else if btm, ok := m.(android.BazelTargetModule); ok {
|
||||||
t = generateBazelTarget(bpCtx, m, btm)
|
t = generateBazelTarget(bpCtx, m, btm)
|
||||||
metrics.RuleClassCount[t.ruleClass] += 1
|
metrics.RuleClassCount[t.ruleClass] += 1
|
||||||
|
compatLayer.AddNameToLabelEntry(m.Name(), t.Label())
|
||||||
} else {
|
} else {
|
||||||
metrics.TotalModuleCount += 1
|
metrics.TotalModuleCount += 1
|
||||||
return
|
return
|
||||||
@@ -283,7 +300,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildFileToTargets, metrics
|
return buildFileToTargets, metrics, compatLayer
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBazelPackagePath(b android.Bazelable) string {
|
func getBazelPackagePath(b android.Bazelable) string {
|
||||||
@@ -324,6 +341,7 @@ func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module, btm android.B
|
|||||||
targetName := targetNameForBp2Build(ctx, m)
|
targetName := targetNameForBp2Build(ctx, m)
|
||||||
return BazelTarget{
|
return BazelTarget{
|
||||||
name: targetName,
|
name: targetName,
|
||||||
|
packageName: ctx.ModuleDir(m),
|
||||||
ruleClass: ruleClass,
|
ruleClass: ruleClass,
|
||||||
bzlLoadLocation: bzlLoadLocation,
|
bzlLoadLocation: bzlLoadLocation,
|
||||||
content: fmt.Sprintf(
|
content: fmt.Sprintf(
|
||||||
|
@@ -1414,25 +1414,31 @@ filegroup {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "filegroup bazel_module.label and bp2build",
|
description: "filegroup bazel_module.label and bp2build in subdir",
|
||||||
moduleTypeUnderTest: "filegroup",
|
moduleTypeUnderTest: "filegroup",
|
||||||
moduleTypeUnderTestFactory: android.FileGroupFactory,
|
moduleTypeUnderTestFactory: android.FileGroupFactory,
|
||||||
moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
|
moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
|
||||||
bp: `filegroup {
|
dir: "other",
|
||||||
|
bp: ``,
|
||||||
|
fs: map[string]string{
|
||||||
|
"other/Android.bp": `filegroup {
|
||||||
name: "fg_foo",
|
name: "fg_foo",
|
||||||
bazel_module: {
|
bazel_module: {
|
||||||
label: "//other:fg_foo",
|
|
||||||
bp2build_available: true,
|
bp2build_available: true,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
filegroup {
|
||||||
|
name: "fg_bar",
|
||||||
|
bazel_module: {
|
||||||
|
label: "//other:fg_bar"
|
||||||
|
},
|
||||||
}`,
|
}`,
|
||||||
|
"other/BUILD.bazel": `// definition for fg_bar`,
|
||||||
|
},
|
||||||
expectedBazelTargets: []string{
|
expectedBazelTargets: []string{
|
||||||
`filegroup(
|
`filegroup(
|
||||||
name = "fg_foo",
|
name = "fg_foo",
|
||||||
)`,
|
)`, `// definition for fg_bar`,
|
||||||
`// BUILD file`,
|
|
||||||
},
|
|
||||||
fs: map[string]string{
|
|
||||||
"other/BUILD.bazel": `// BUILD file`,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
31
bp2build/compatibility.go
Normal file
31
bp2build/compatibility.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package bp2build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"android/soong/bazel"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Data from the code generation process that is used to improve compatibility
|
||||||
|
// between build systems.
|
||||||
|
type CodegenCompatLayer struct {
|
||||||
|
// A map from the original module name to the generated/handcrafted Bazel
|
||||||
|
// label for legacy build systems to be able to build a fully-qualified
|
||||||
|
// Bazel target from an unique module name.
|
||||||
|
NameToLabelMap map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log an entry of module name -> Bazel target label.
|
||||||
|
func (compatLayer CodegenCompatLayer) AddNameToLabelEntry(name, label string) {
|
||||||
|
// The module name may be prefixed with bazel.BazelTargetModuleNamePrefix if
|
||||||
|
// generated from bp2build.
|
||||||
|
name = bazel.StripNamePrefix(name)
|
||||||
|
if existingLabel, ok := compatLayer.NameToLabelMap[name]; ok {
|
||||||
|
panic(fmt.Errorf(
|
||||||
|
"Module '%s' maps to more than one Bazel target label: %s, %s. "+
|
||||||
|
"This shouldn't happen. It probably indicates a bug with the bp2build internals.",
|
||||||
|
name,
|
||||||
|
existingLabel,
|
||||||
|
label))
|
||||||
|
}
|
||||||
|
compatLayer.NameToLabelMap[name] = label
|
||||||
|
}
|
@@ -16,15 +16,31 @@ type BazelFile struct {
|
|||||||
Contents string
|
Contents string
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateSoongInjectionFiles() []BazelFile {
|
func CreateSoongInjectionFiles(compatLayer CodegenCompatLayer) []BazelFile {
|
||||||
var files []BazelFile
|
var files []BazelFile
|
||||||
|
|
||||||
files = append(files, newFile("cc_toolchain", "BUILD", "")) // Creates a //cc_toolchain package.
|
files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
|
||||||
files = append(files, newFile("cc_toolchain", "constants.bzl", config.BazelCcToolchainVars()))
|
files = append(files, newFile("cc_toolchain", "constants.bzl", config.BazelCcToolchainVars()))
|
||||||
|
|
||||||
|
files = append(files, newFile("module_name_to_label", GeneratedBuildFileName, nameToLabelAliases(compatLayer.NameToLabelMap)))
|
||||||
|
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func nameToLabelAliases(nameToLabelMap map[string]string) string {
|
||||||
|
ret := make([]string, len(nameToLabelMap))
|
||||||
|
|
||||||
|
for k, v := range nameToLabelMap {
|
||||||
|
// v is the fully qualified label rooted at '//'
|
||||||
|
ret = append(ret, fmt.Sprintf(
|
||||||
|
`alias(
|
||||||
|
name = "%s",
|
||||||
|
actual = "@%s",
|
||||||
|
)`, k, v))
|
||||||
|
}
|
||||||
|
return strings.Join(ret, "\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
func CreateBazelFiles(
|
func CreateBazelFiles(
|
||||||
ruleShims map[string]RuleShim,
|
ruleShims map[string]RuleShim,
|
||||||
buildToTargets map[string]BazelTargets,
|
buildToTargets map[string]BazelTargets,
|
||||||
|
@@ -80,17 +80,21 @@ func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
|
func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
|
||||||
files := CreateSoongInjectionFiles()
|
files := CreateSoongInjectionFiles(CodegenCompatLayer{})
|
||||||
|
|
||||||
expectedFilePaths := []bazelFilepath{
|
expectedFilePaths := []bazelFilepath{
|
||||||
{
|
{
|
||||||
dir: "cc_toolchain",
|
dir: "cc_toolchain",
|
||||||
basename: "BUILD",
|
basename: GeneratedBuildFileName,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dir: "cc_toolchain",
|
dir: "cc_toolchain",
|
||||||
basename: "constants.bzl",
|
basename: "constants.bzl",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
dir: "module_name_to_label",
|
||||||
|
basename: GeneratedBuildFileName,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(files) != len(expectedFilePaths) {
|
if len(files) != len(expectedFilePaths) {
|
||||||
@@ -104,7 +108,7 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
|
|||||||
t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
|
t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
|
||||||
}
|
}
|
||||||
|
|
||||||
if expectedFile.basename != "BUILD" && actualFile.Contents == "" {
|
if expectedFile.basename != GeneratedBuildFileName && actualFile.Contents == "" {
|
||||||
t.Errorf("Contents of %s unexpected empty.", actualFile)
|
t.Errorf("Contents of %s unexpected empty.", actualFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -213,6 +213,6 @@ func customBp2BuildMutatorFromStarlark(ctx android.TopDownMutatorContext) {
|
|||||||
// Helper method for tests to easily access the targets in a dir.
|
// Helper method for tests to easily access the targets in a dir.
|
||||||
func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) BazelTargets {
|
func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) BazelTargets {
|
||||||
// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
|
// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
|
||||||
buildFileToTargets, _ := GenerateBazelTargets(codegenCtx, false)
|
buildFileToTargets, _, _ := GenerateBazelTargets(codegenCtx, false)
|
||||||
return buildFileToTargets[dir]
|
return buildFileToTargets[dir]
|
||||||
}
|
}
|
||||||
|
@@ -25,9 +25,10 @@ import (
|
|||||||
func createBazelQueryView(ctx *bp2build.CodegenContext, bazelQueryViewDir string) error {
|
func createBazelQueryView(ctx *bp2build.CodegenContext, bazelQueryViewDir string) error {
|
||||||
ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
|
ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
|
||||||
|
|
||||||
// Ignore metrics reporting for queryview, since queryview is already a full-repo
|
// Ignore metrics reporting and compat layers for queryview, since queryview
|
||||||
// conversion and can use data from bazel query directly.
|
// is already a full-repo conversion and can use data from bazel query
|
||||||
buildToTargets, _ := bp2build.GenerateBazelTargets(ctx, true)
|
// directly.
|
||||||
|
buildToTargets, _, _ := bp2build.GenerateBazelTargets(ctx, true)
|
||||||
|
|
||||||
filesToWrite := bp2build.CreateBazelFiles(ruleShims, buildToTargets, bp2build.QueryView)
|
filesToWrite := bp2build.CreateBazelFiles(ruleShims, buildToTargets, bp2build.QueryView)
|
||||||
for _, f := range filesToWrite {
|
for _, f := range filesToWrite {
|
||||||
|
Reference in New Issue
Block a user