Loading bp2build/bp2build.go +2 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import ( // Codegen is the backend of bp2build. The code generator is responsible for // writing .bzl files that are equivalent to Android.bp files that are capable // of being built with Bazel. func Codegen(ctx *CodegenContext) CodegenMetrics { func Codegen(ctx *CodegenContext) *CodegenMetrics { // This directory stores BUILD files that could be eventually checked-in. bp2buildDir := android.PathForOutput(ctx, "bp2build") if err := android.RemoveAllOutputDir(bp2buildDir); err != nil { Loading @@ -48,7 +48,7 @@ func Codegen(ctx *CodegenContext) CodegenMetrics { soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName) writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(ctx.Config(), res.metrics)) return res.metrics return &res.metrics } // Get the output directory and create it if it doesn't exist. Loading bp2build/build_conversion.go +1 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import ( "android/soong/android" "android/soong/bazel" "android/soong/starlark_fmt" "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) Loading Loading @@ -245,12 +244,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers buildFileToTargets := make(map[string]BazelTargets) // Simple metrics tracking for bp2build metrics := CodegenMetrics{ ruleClassCount: make(map[string]uint64), convertedModulePathMap: make(map[string]string), convertedModuleTypeCount: make(map[string]uint64), totalModuleTypeCount: make(map[string]uint64), } metrics := CreateCodegenMetrics() dirs := make(map[string]bool) Loading bp2build/conversion.go +1 −5 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ func CreateSoongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []Baz files = append(files, newFile("apex_toolchain", GeneratedBuildFileName, "")) // Creates a //apex_toolchain package. files = append(files, newFile("apex_toolchain", "constants.bzl", apex.BazelApexToolchainVars())) files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.convertedModules, "\n"))) files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.Serialize().ConvertedModules, "\n"))) convertedModulePathMap, err := json.MarshalIndent(metrics.convertedModulePathMap, "", "\t") if err != nil { Loading @@ -55,10 +55,6 @@ func CreateSoongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []Baz return files } func convertedModules(convertedModules []string) string { return strings.Join(convertedModules, "\n") } func CreateBazelFiles( cfg android.Config, ruleShims map[string]RuleShim, Loading bp2build/conversion_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) { func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { testConfig := android.TestConfig("", make(map[string]string), "", make(map[string][]byte)) files := CreateSoongInjectionFiles(testConfig, CodegenMetrics{}) files := CreateSoongInjectionFiles(testConfig, CreateCodegenMetrics()) expectedFilePaths := []bazelFilepath{ { Loading bp2build/metrics.go +72 −51 Original line number Diff line number Diff line Loading @@ -9,25 +9,16 @@ import ( "android/soong/android" "android/soong/shared" "android/soong/ui/metrics/bp2build_metrics_proto" "google.golang.org/protobuf/proto" "github.com/google/blueprint" ) // Simple metrics struct to collect information about a Blueprint to BUILD // CodegenMetrics represents information about the Blueprint-to-BUILD // conversion process. // Use CreateCodegenMetrics() to get a properly initialized instance type CodegenMetrics struct { // Total number of Soong modules converted to generated targets generatedModuleCount uint64 // Total number of Soong modules converted to handcrafted targets handCraftedModuleCount uint64 // Total number of unconverted Soong modules unconvertedModuleCount uint64 // Counts of generated Bazel targets per Bazel rule class ruleClassCount map[string]uint64 serialized *bp2build_metrics_proto.Bp2BuildMetrics // List of modules with unconverted deps // NOTE: NOT in the .proto moduleWithUnconvertedDepsMsgs []string Loading @@ -36,40 +27,32 @@ type CodegenMetrics struct { // NOTE: NOT in the .proto moduleWithMissingDepsMsgs []string // List of converted modules convertedModules []string // Map of converted modules and paths to call // NOTE: NOT in the .proto convertedModulePathMap map[string]string } // Counts of converted modules by module type. convertedModuleTypeCount map[string]uint64 // Counts of total modules by module type. totalModuleTypeCount map[string]uint64 Events []*bp2build_metrics_proto.Event func CreateCodegenMetrics() CodegenMetrics { return CodegenMetrics{ serialized: &bp2build_metrics_proto.Bp2BuildMetrics{ RuleClassCount: make(map[string]uint64), ConvertedModuleTypeCount: make(map[string]uint64), TotalModuleTypeCount: make(map[string]uint64), }, convertedModulePathMap: make(map[string]string), } } // Serialize returns the protoized version of CodegenMetrics: bp2build_metrics_proto.Bp2BuildMetrics func (metrics *CodegenMetrics) Serialize() bp2build_metrics_proto.Bp2BuildMetrics { return bp2build_metrics_proto.Bp2BuildMetrics{ GeneratedModuleCount: metrics.generatedModuleCount, HandCraftedModuleCount: metrics.handCraftedModuleCount, UnconvertedModuleCount: metrics.unconvertedModuleCount, RuleClassCount: metrics.ruleClassCount, ConvertedModules: metrics.convertedModules, ConvertedModuleTypeCount: metrics.convertedModuleTypeCount, TotalModuleTypeCount: metrics.totalModuleTypeCount, Events: metrics.Events, } func (metrics *CodegenMetrics) Serialize() *bp2build_metrics_proto.Bp2BuildMetrics { return metrics.serialized } // Print the codegen metrics to stdout. func (metrics *CodegenMetrics) Print() { generatedTargetCount := uint64(0) for _, ruleClass := range android.SortedStringKeys(metrics.ruleClassCount) { count := metrics.ruleClassCount[ruleClass] for _, ruleClass := range android.SortedStringKeys(metrics.serialized.RuleClassCount) { count := metrics.serialized.RuleClassCount[ruleClass] fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count) generatedTargetCount += count } Loading @@ -80,9 +63,9 @@ func (metrics *CodegenMetrics) Print() { %d converted modules have missing deps: %s `, metrics.generatedModuleCount, metrics.serialized.GeneratedModuleCount, generatedTargetCount, metrics.handCraftedModuleCount, metrics.serialized.HandCraftedModuleCount, metrics.TotalModuleCount(), len(metrics.moduleWithUnconvertedDepsMsgs), strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t"), Loading Loading @@ -119,29 +102,67 @@ func (metrics *CodegenMetrics) Write(dir string) { fail(err, "Error outputting %s", metricsFile) } if _, err := os.Stat(metricsFile); err != nil { fail(err, "MISSING BP2BUILD METRICS OUTPUT: Failed to `stat` %s", metricsFile) if os.IsNotExist(err) { fail(err, "MISSING BP2BUILD METRICS OUTPUT: %s", metricsFile) } else { fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile) } } } // ReadCodegenMetrics loads CodegenMetrics from `dir` // returns a nil pointer if the file doesn't exist func ReadCodegenMetrics(dir string) *CodegenMetrics { metricsFile := filepath.Join(dir, bp2buildMetricsFilename) if _, err := os.Stat(metricsFile); err != nil { if os.IsNotExist(err) { return nil } else { fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile) panic("unreachable after fail") } } if buf, err := os.ReadFile(metricsFile); err != nil { fail(err, "FAILED TO READ BP2BUILD METRICS OUTPUT: %s", metricsFile) panic("unreachable after fail") } else { bp2BuildMetrics := bp2build_metrics_proto.Bp2BuildMetrics{ RuleClassCount: make(map[string]uint64), ConvertedModuleTypeCount: make(map[string]uint64), TotalModuleTypeCount: make(map[string]uint64), } if err := proto.Unmarshal(buf, &bp2BuildMetrics); err != nil { fail(err, "FAILED TO PARSE BP2BUILD METRICS OUTPUT: %s", metricsFile) } return &CodegenMetrics{ serialized: &bp2BuildMetrics, convertedModulePathMap: make(map[string]string), } } } func (metrics *CodegenMetrics) IncrementRuleClassCount(ruleClass string) { metrics.ruleClassCount[ruleClass] += 1 metrics.serialized.RuleClassCount[ruleClass] += 1 } func (metrics *CodegenMetrics) AddEvent(event *bp2build_metrics_proto.Event) { metrics.serialized.Events = append(metrics.serialized.Events, event) } func (metrics *CodegenMetrics) AddUnconvertedModule(moduleType string) { metrics.unconvertedModuleCount += 1 metrics.totalModuleTypeCount[moduleType] += 1 metrics.serialized.UnconvertedModuleCount += 1 metrics.serialized.TotalModuleTypeCount[moduleType] += 1 } func (metrics *CodegenMetrics) TotalModuleCount() uint64 { return metrics.handCraftedModuleCount + metrics.generatedModuleCount + metrics.unconvertedModuleCount return metrics.serialized.HandCraftedModuleCount + metrics.serialized.GeneratedModuleCount + metrics.serialized.UnconvertedModuleCount } // Dump serializes the metrics to the given filename func (metrics *CodegenMetrics) dump(filename string) (err error) { ser := metrics.Serialize() return shared.Save(&ser, filename) return shared.Save(ser, filename) } type ConversionType int Loading @@ -154,14 +175,14 @@ const ( func (metrics *CodegenMetrics) AddConvertedModule(m blueprint.Module, moduleType string, dir string, conversionType ConversionType) { // Undo prebuilt_ module name prefix modifications moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name()) metrics.convertedModules = append(metrics.convertedModules, moduleName) metrics.serialized.ConvertedModules = append(metrics.serialized.ConvertedModules, moduleName) metrics.convertedModulePathMap[moduleName] = "//" + dir metrics.convertedModuleTypeCount[moduleType] += 1 metrics.totalModuleTypeCount[moduleType] += 1 metrics.serialized.ConvertedModuleTypeCount[moduleType] += 1 metrics.serialized.TotalModuleTypeCount[moduleType] += 1 if conversionType == Handcrafted { metrics.handCraftedModuleCount += 1 metrics.serialized.HandCraftedModuleCount += 1 } else if conversionType == Generated { metrics.generatedModuleCount += 1 metrics.serialized.GeneratedModuleCount += 1 } } Loading
bp2build/bp2build.go +2 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import ( // Codegen is the backend of bp2build. The code generator is responsible for // writing .bzl files that are equivalent to Android.bp files that are capable // of being built with Bazel. func Codegen(ctx *CodegenContext) CodegenMetrics { func Codegen(ctx *CodegenContext) *CodegenMetrics { // This directory stores BUILD files that could be eventually checked-in. bp2buildDir := android.PathForOutput(ctx, "bp2build") if err := android.RemoveAllOutputDir(bp2buildDir); err != nil { Loading @@ -48,7 +48,7 @@ func Codegen(ctx *CodegenContext) CodegenMetrics { soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName) writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(ctx.Config(), res.metrics)) return res.metrics return &res.metrics } // Get the output directory and create it if it doesn't exist. Loading
bp2build/build_conversion.go +1 −7 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import ( "android/soong/android" "android/soong/bazel" "android/soong/starlark_fmt" "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) Loading Loading @@ -245,12 +244,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers buildFileToTargets := make(map[string]BazelTargets) // Simple metrics tracking for bp2build metrics := CodegenMetrics{ ruleClassCount: make(map[string]uint64), convertedModulePathMap: make(map[string]string), convertedModuleTypeCount: make(map[string]uint64), totalModuleTypeCount: make(map[string]uint64), } metrics := CreateCodegenMetrics() dirs := make(map[string]bool) Loading
bp2build/conversion.go +1 −5 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ func CreateSoongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []Baz files = append(files, newFile("apex_toolchain", GeneratedBuildFileName, "")) // Creates a //apex_toolchain package. files = append(files, newFile("apex_toolchain", "constants.bzl", apex.BazelApexToolchainVars())) files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.convertedModules, "\n"))) files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.Serialize().ConvertedModules, "\n"))) convertedModulePathMap, err := json.MarshalIndent(metrics.convertedModulePathMap, "", "\t") if err != nil { Loading @@ -55,10 +55,6 @@ func CreateSoongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []Baz return files } func convertedModules(convertedModules []string) string { return strings.Join(convertedModules, "\n") } func CreateBazelFiles( cfg android.Config, ruleShims map[string]RuleShim, Loading
bp2build/conversion_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) { func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { testConfig := android.TestConfig("", make(map[string]string), "", make(map[string][]byte)) files := CreateSoongInjectionFiles(testConfig, CodegenMetrics{}) files := CreateSoongInjectionFiles(testConfig, CreateCodegenMetrics()) expectedFilePaths := []bazelFilepath{ { Loading
bp2build/metrics.go +72 −51 Original line number Diff line number Diff line Loading @@ -9,25 +9,16 @@ import ( "android/soong/android" "android/soong/shared" "android/soong/ui/metrics/bp2build_metrics_proto" "google.golang.org/protobuf/proto" "github.com/google/blueprint" ) // Simple metrics struct to collect information about a Blueprint to BUILD // CodegenMetrics represents information about the Blueprint-to-BUILD // conversion process. // Use CreateCodegenMetrics() to get a properly initialized instance type CodegenMetrics struct { // Total number of Soong modules converted to generated targets generatedModuleCount uint64 // Total number of Soong modules converted to handcrafted targets handCraftedModuleCount uint64 // Total number of unconverted Soong modules unconvertedModuleCount uint64 // Counts of generated Bazel targets per Bazel rule class ruleClassCount map[string]uint64 serialized *bp2build_metrics_proto.Bp2BuildMetrics // List of modules with unconverted deps // NOTE: NOT in the .proto moduleWithUnconvertedDepsMsgs []string Loading @@ -36,40 +27,32 @@ type CodegenMetrics struct { // NOTE: NOT in the .proto moduleWithMissingDepsMsgs []string // List of converted modules convertedModules []string // Map of converted modules and paths to call // NOTE: NOT in the .proto convertedModulePathMap map[string]string } // Counts of converted modules by module type. convertedModuleTypeCount map[string]uint64 // Counts of total modules by module type. totalModuleTypeCount map[string]uint64 Events []*bp2build_metrics_proto.Event func CreateCodegenMetrics() CodegenMetrics { return CodegenMetrics{ serialized: &bp2build_metrics_proto.Bp2BuildMetrics{ RuleClassCount: make(map[string]uint64), ConvertedModuleTypeCount: make(map[string]uint64), TotalModuleTypeCount: make(map[string]uint64), }, convertedModulePathMap: make(map[string]string), } } // Serialize returns the protoized version of CodegenMetrics: bp2build_metrics_proto.Bp2BuildMetrics func (metrics *CodegenMetrics) Serialize() bp2build_metrics_proto.Bp2BuildMetrics { return bp2build_metrics_proto.Bp2BuildMetrics{ GeneratedModuleCount: metrics.generatedModuleCount, HandCraftedModuleCount: metrics.handCraftedModuleCount, UnconvertedModuleCount: metrics.unconvertedModuleCount, RuleClassCount: metrics.ruleClassCount, ConvertedModules: metrics.convertedModules, ConvertedModuleTypeCount: metrics.convertedModuleTypeCount, TotalModuleTypeCount: metrics.totalModuleTypeCount, Events: metrics.Events, } func (metrics *CodegenMetrics) Serialize() *bp2build_metrics_proto.Bp2BuildMetrics { return metrics.serialized } // Print the codegen metrics to stdout. func (metrics *CodegenMetrics) Print() { generatedTargetCount := uint64(0) for _, ruleClass := range android.SortedStringKeys(metrics.ruleClassCount) { count := metrics.ruleClassCount[ruleClass] for _, ruleClass := range android.SortedStringKeys(metrics.serialized.RuleClassCount) { count := metrics.serialized.RuleClassCount[ruleClass] fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count) generatedTargetCount += count } Loading @@ -80,9 +63,9 @@ func (metrics *CodegenMetrics) Print() { %d converted modules have missing deps: %s `, metrics.generatedModuleCount, metrics.serialized.GeneratedModuleCount, generatedTargetCount, metrics.handCraftedModuleCount, metrics.serialized.HandCraftedModuleCount, metrics.TotalModuleCount(), len(metrics.moduleWithUnconvertedDepsMsgs), strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t"), Loading Loading @@ -119,29 +102,67 @@ func (metrics *CodegenMetrics) Write(dir string) { fail(err, "Error outputting %s", metricsFile) } if _, err := os.Stat(metricsFile); err != nil { fail(err, "MISSING BP2BUILD METRICS OUTPUT: Failed to `stat` %s", metricsFile) if os.IsNotExist(err) { fail(err, "MISSING BP2BUILD METRICS OUTPUT: %s", metricsFile) } else { fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile) } } } // ReadCodegenMetrics loads CodegenMetrics from `dir` // returns a nil pointer if the file doesn't exist func ReadCodegenMetrics(dir string) *CodegenMetrics { metricsFile := filepath.Join(dir, bp2buildMetricsFilename) if _, err := os.Stat(metricsFile); err != nil { if os.IsNotExist(err) { return nil } else { fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile) panic("unreachable after fail") } } if buf, err := os.ReadFile(metricsFile); err != nil { fail(err, "FAILED TO READ BP2BUILD METRICS OUTPUT: %s", metricsFile) panic("unreachable after fail") } else { bp2BuildMetrics := bp2build_metrics_proto.Bp2BuildMetrics{ RuleClassCount: make(map[string]uint64), ConvertedModuleTypeCount: make(map[string]uint64), TotalModuleTypeCount: make(map[string]uint64), } if err := proto.Unmarshal(buf, &bp2BuildMetrics); err != nil { fail(err, "FAILED TO PARSE BP2BUILD METRICS OUTPUT: %s", metricsFile) } return &CodegenMetrics{ serialized: &bp2BuildMetrics, convertedModulePathMap: make(map[string]string), } } } func (metrics *CodegenMetrics) IncrementRuleClassCount(ruleClass string) { metrics.ruleClassCount[ruleClass] += 1 metrics.serialized.RuleClassCount[ruleClass] += 1 } func (metrics *CodegenMetrics) AddEvent(event *bp2build_metrics_proto.Event) { metrics.serialized.Events = append(metrics.serialized.Events, event) } func (metrics *CodegenMetrics) AddUnconvertedModule(moduleType string) { metrics.unconvertedModuleCount += 1 metrics.totalModuleTypeCount[moduleType] += 1 metrics.serialized.UnconvertedModuleCount += 1 metrics.serialized.TotalModuleTypeCount[moduleType] += 1 } func (metrics *CodegenMetrics) TotalModuleCount() uint64 { return metrics.handCraftedModuleCount + metrics.generatedModuleCount + metrics.unconvertedModuleCount return metrics.serialized.HandCraftedModuleCount + metrics.serialized.GeneratedModuleCount + metrics.serialized.UnconvertedModuleCount } // Dump serializes the metrics to the given filename func (metrics *CodegenMetrics) dump(filename string) (err error) { ser := metrics.Serialize() return shared.Save(&ser, filename) return shared.Save(ser, filename) } type ConversionType int Loading @@ -154,14 +175,14 @@ const ( func (metrics *CodegenMetrics) AddConvertedModule(m blueprint.Module, moduleType string, dir string, conversionType ConversionType) { // Undo prebuilt_ module name prefix modifications moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name()) metrics.convertedModules = append(metrics.convertedModules, moduleName) metrics.serialized.ConvertedModules = append(metrics.serialized.ConvertedModules, moduleName) metrics.convertedModulePathMap[moduleName] = "//" + dir metrics.convertedModuleTypeCount[moduleType] += 1 metrics.totalModuleTypeCount[moduleType] += 1 metrics.serialized.ConvertedModuleTypeCount[moduleType] += 1 metrics.serialized.TotalModuleTypeCount[moduleType] += 1 if conversionType == Handcrafted { metrics.handCraftedModuleCount += 1 metrics.serialized.HandCraftedModuleCount += 1 } else if conversionType == Generated { metrics.generatedModuleCount += 1 metrics.serialized.GeneratedModuleCount += 1 } }