From 6d48aad0ffec3c06e456ad0ba9f5013c4ce3c6c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thi=C3=A9baud=20Weksteen?= Date: Wed, 10 Feb 2021 14:06:12 +0100 Subject: [PATCH] Add bloaty package This package can be used by other binary generator to gather the section sizes at build time. It uses bloaty_merger to export all the measured data into a single proto file. Bug: 172339742 Test: m out/soong/binary_sizes.pb Change-Id: I0ca87cdb2fb8b77226e79d9dcd762abe64aeea51 --- bloaty/Android.bp | 13 +++++++ bloaty/bloaty.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 bloaty/bloaty.go diff --git a/bloaty/Android.bp b/bloaty/Android.bp index 0c4f60387..b1f1e398b 100644 --- a/bloaty/Android.bp +++ b/bloaty/Android.bp @@ -1,3 +1,16 @@ +bootstrap_go_package { + name: "soong-bloaty", + pkgPath: "android/soong/bloaty", + deps: [ + "blueprint", + "soong-android", + ], + srcs: [ + "bloaty.go", + ], + pluginFor: ["soong_build"], +} + python_test_host { name: "bloaty_merger_test", srcs: [ diff --git a/bloaty/bloaty.go b/bloaty/bloaty.go new file mode 100644 index 000000000..0bff8aac7 --- /dev/null +++ b/bloaty/bloaty.go @@ -0,0 +1,92 @@ +// 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 bloaty implements a singleton that measures binary (e.g. ELF +// executable, shared library or Rust rlib) section sizes at build time. +package bloaty + +import ( + "android/soong/android" + + "github.com/google/blueprint" +) + +const bloatyDescriptorExt = "bloaty.csv" + +var ( + fileSizeMeasurerKey blueprint.ProviderKey + pctx = android.NewPackageContext("android/soong/bloaty") + + // bloaty is used to measure a binary section sizes. + bloaty = pctx.AndroidStaticRule("bloaty", + blueprint.RuleParams{ + Command: "${bloaty} -n 0 --csv ${in} > ${out}", + CommandDeps: []string{"${bloaty}"}, + }) + + // The bloaty merger script is used to combine the outputs from bloaty + // into a single protobuf. + bloatyMerger = pctx.AndroidStaticRule("bloatyMerger", + blueprint.RuleParams{ + Command: "${bloatyMerger} ${out}.lst ${out}", + CommandDeps: []string{"${bloatyMerger}"}, + Rspfile: "${out}.lst", + RspfileContent: "${in}", + }) +) + +func init() { + pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS) + pctx.SourcePathVariable("bloaty", "prebuilts/build-tools/${hostPrebuiltTag}/bin/bloaty") + pctx.HostBinToolVariable("bloatyMerger", "bloaty_merger") + android.RegisterSingletonType("file_metrics", fileSizesSingleton) + fileSizeMeasurerKey = blueprint.NewProvider(android.ModuleOutPath{}) +} + +// MeasureSizeForPath should be called by binary producers (e.g. in builder.go). +func MeasureSizeForPath(ctx android.ModuleContext, filePath android.WritablePath) { + ctx.SetProvider(fileSizeMeasurerKey, filePath) +} + +type sizesSingleton struct{} + +func fileSizesSingleton() android.Singleton { + return &sizesSingleton{} +} + +func (singleton *sizesSingleton) GenerateBuildActions(ctx android.SingletonContext) { + var deps android.Paths + // Visit all modules. If the size provider give us a binary path to measure, + // create the rule to measure it. + ctx.VisitAllModules(func(m android.Module) { + if !ctx.ModuleHasProvider(m, fileSizeMeasurerKey) { + return + } + filePath := ctx.ModuleProvider(m, fileSizeMeasurerKey).(android.ModuleOutPath) + sizeFile := filePath.ReplaceExtension(ctx, bloatyDescriptorExt) + ctx.Build(pctx, android.BuildParams{ + Rule: bloaty, + Description: "bloaty " + filePath.Rel(), + Input: filePath, + Output: sizeFile, + }) + deps = append(deps, sizeFile) + }) + + ctx.Build(pctx, android.BuildParams{ + Rule: bloatyMerger, + Inputs: android.SortedUniquePaths(deps), + Output: android.PathForOutput(ctx, "binary_sizes.pb"), + }) +}