diff options
author | 2024-10-02 15:42:53 -0700 | |
---|---|---|
committer | 2024-10-03 07:06:46 -0700 | |
commit | 735a80bf3e843ed9131d1ed60326927eb7e00fc9 (patch) | |
tree | b1bfa20aa1356b03c216e39ea199dc3a08338730 | |
parent | 1119e46b4a6c6282db5a3134fb64efc2d944a7ca (diff) |
Add release_config_contributions modules
These are used to enumerate what directories may contribute to release
configs, whether or not they are actually used in the build.
Bug: b/370544058
Test: manual, TH
Change-Id: I1509eb3795a9b51b29995b182b77ade76021bb52
-rw-r--r-- | aconfig/build_flags/Android.bp | 1 | ||||
-rw-r--r-- | aconfig/build_flags/build_flags_singleton.go | 81 | ||||
-rw-r--r-- | aconfig/build_flags/declarations.go | 2 | ||||
-rw-r--r-- | aconfig/build_flags/init.go | 17 | ||||
-rw-r--r-- | aconfig/build_flags/release_configs.go | 78 | ||||
-rw-r--r-- | cmd/release_config/release_config_contributions/Android.bp | 32 | ||||
-rw-r--r-- | cmd/release_config/release_config_contributions/main.go | 130 | ||||
-rw-r--r-- | cmd/release_config/release_config_lib/release_configs.go | 12 | ||||
-rw-r--r-- | cmd/release_config/release_config_proto/Android.bp | 1 |
9 files changed, 335 insertions, 19 deletions
diff --git a/aconfig/build_flags/Android.bp b/aconfig/build_flags/Android.bp index be1b872f0..139aeac3b 100644 --- a/aconfig/build_flags/Android.bp +++ b/aconfig/build_flags/Android.bp @@ -17,6 +17,7 @@ bootstrap_go_package { "build_flags_singleton.go", "declarations.go", "init.go", + "release_configs.go", ], testSrcs: [ ], diff --git a/aconfig/build_flags/build_flags_singleton.go b/aconfig/build_flags/build_flags_singleton.go index 5f0291262..ba27a8515 100644 --- a/aconfig/build_flags/build_flags_singleton.go +++ b/aconfig/build_flags/build_flags_singleton.go @@ -30,49 +30,94 @@ func AllBuildFlagDeclarationsFactory() android.Singleton { } type allBuildFlagDeclarationsSingleton struct { - intermediateBinaryProtoPath android.OutputPath - intermediateTextProtoPath android.OutputPath + flagsBinaryProtoPath android.OutputPath + flagsTextProtoPath android.OutputPath + configsBinaryProtoPath android.OutputPath + configsTextProtoPath android.OutputPath } func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) { // Find all of the build_flag_declarations modules - var intermediateFiles android.Paths + var flagsFiles android.Paths + // Find all of the release_config_contribution modules + var contributionDirs android.Paths ctx.VisitAllModules(func(module android.Module) { decl, ok := android.OtherModuleProvider(ctx, module, BuildFlagDeclarationsProviderKey) - if !ok { - return + if ok { + flagsFiles = append(flagsFiles, decl.IntermediateCacheOutputPath) + } + + contrib, ok := android.OtherModuleProvider(ctx, module, ReleaseConfigContributionsProviderKey) + if ok { + contributionDirs = append(contributionDirs, contrib.ContributionDir) } - intermediateFiles = append(intermediateFiles, decl.IntermediateCacheOutputPath) }) // Generate build action for build_flag (binary proto output) - this.intermediateBinaryProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.pb") + this.flagsBinaryProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.pb") ctx.Build(pctx, android.BuildParams{ Rule: allDeclarationsRule, - Inputs: intermediateFiles, - Output: this.intermediateBinaryProtoPath, + Inputs: flagsFiles, + Output: this.flagsBinaryProtoPath, Description: "all_build_flag_declarations", Args: map[string]string{ - "intermediates": android.JoinPathsWithPrefix(intermediateFiles, "--intermediate "), + "intermediates": android.JoinPathsWithPrefix(flagsFiles, "--intermediate "), }, }) - ctx.Phony("all_build_flag_declarations", this.intermediateBinaryProtoPath) + ctx.Phony("all_build_flag_declarations", this.flagsBinaryProtoPath) // Generate build action for build_flag (text proto output) - this.intermediateTextProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.textproto") + this.flagsTextProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.textproto") ctx.Build(pctx, android.BuildParams{ Rule: allDeclarationsRuleTextProto, - Input: this.intermediateBinaryProtoPath, - Output: this.intermediateTextProtoPath, + Input: this.flagsBinaryProtoPath, + Output: this.flagsTextProtoPath, Description: "all_build_flag_declarations_textproto", }) - ctx.Phony("all_build_flag_declarations_textproto", this.intermediateTextProtoPath) + ctx.Phony("all_build_flag_declarations_textproto", this.flagsTextProtoPath) + + // Generate build action for release_configs (binary proto output) + this.configsBinaryProtoPath = android.PathForIntermediates(ctx, "all_release_config_contributions.pb") + ctx.Build(pctx, android.BuildParams{ + Rule: allReleaseConfigContributionsRule, + Inputs: contributionDirs, + Output: this.configsBinaryProtoPath, + Description: "all_release_config_contributions", + Args: map[string]string{ + "dirs": android.JoinPathsWithPrefix(contributionDirs, "--dir "), + "format": "pb", + }, + }) + ctx.Phony("all_release_config_contributions", this.configsBinaryProtoPath) + + this.configsTextProtoPath = android.PathForIntermediates(ctx, "all_release_config_contributions.textproto") + ctx.Build(pctx, android.BuildParams{ + Rule: allReleaseConfigContributionsRule, + Inputs: contributionDirs, + Output: this.configsTextProtoPath, + Description: "all_release_config_contributions_textproto", + Args: map[string]string{ + "dirs": android.JoinPathsWithPrefix(contributionDirs, "--dir "), + "format": "textproto", + }, + }) + ctx.Phony("all_release_config_contributions_textproto", this.configsTextProtoPath) + + // Add a simple target for ci/build_metadata to use. + ctx.Phony("release_config_metadata", + this.flagsBinaryProtoPath, + this.flagsTextProtoPath, + this.configsBinaryProtoPath, + this.configsTextProtoPath, + ) } func (this *allBuildFlagDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) { - ctx.DistForGoal("droid", this.intermediateBinaryProtoPath) + ctx.DistForGoal("droid", this.flagsBinaryProtoPath) for _, goal := range []string{"docs", "droid", "sdk"} { - ctx.DistForGoalWithFilename(goal, this.intermediateBinaryProtoPath, "build_flags/all_flags.pb") - ctx.DistForGoalWithFilename(goal, this.intermediateTextProtoPath, "build_flags/all_flags.textproto") + ctx.DistForGoalWithFilename(goal, this.flagsBinaryProtoPath, "build_flags/all_flags.pb") + ctx.DistForGoalWithFilename(goal, this.flagsTextProtoPath, "build_flags/all_flags.textproto") + ctx.DistForGoalWithFilename(goal, this.configsBinaryProtoPath, "build_flags/all_release_config_contributions.pb") + ctx.DistForGoalWithFilename(goal, this.configsTextProtoPath, "build_flags/all_release_config_contributions.textproto") } } diff --git a/aconfig/build_flags/declarations.go b/aconfig/build_flags/declarations.go index e927db2cf..4a542690d 100644 --- a/aconfig/build_flags/declarations.go +++ b/aconfig/build_flags/declarations.go @@ -35,7 +35,7 @@ type DeclarationsModule struct { // Properties for "aconfig_declarations" properties struct { - // aconfig files, relative to this Android.bp file + // build flag declaration files, relative to this Android.bp file Srcs []string `android:"path"` } } diff --git a/aconfig/build_flags/init.go b/aconfig/build_flags/init.go index dc1369cd4..a7575e86a 100644 --- a/aconfig/build_flags/init.go +++ b/aconfig/build_flags/init.go @@ -65,15 +65,32 @@ var ( "${buildFlagDeclarations}", }, }) + + allReleaseConfigContributionsRule = pctx.AndroidStaticRule("all-release-config-contributions-dump", + blueprint.RuleParams{ + Command: `${releaseConfigContributions} ${dirs} --format ${format} --output ${out}`, + CommandDeps: []string{ + "${releaseConfigContributions}", + }, + }, "dirs", "format") + allReleaseConfigContributionsRuleText = pctx.AndroidStaticRule("all-release-config-contributions-dumptext", + blueprint.RuleParams{ + Command: `${releaseConfigContributions} ${dirs} --format ${format} --output ${out}`, + CommandDeps: []string{ + "${releaseConfigContributions}", + }, + }, "dirs", "format") ) func init() { RegisterBuildComponents(android.InitRegistrationContext) pctx.Import("android/soong/android") pctx.HostBinToolVariable("buildFlagDeclarations", "build-flag-declarations") + pctx.HostBinToolVariable("releaseConfigContributions", "release-config-contributions") } func RegisterBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("build_flag_declarations", DeclarationsFactory) + ctx.RegisterModuleType("release_config_contributions", ReleaseConfigContributionsFactory) ctx.RegisterParallelSingletonType("all_build_flag_declarations", AllBuildFlagDeclarationsFactory) } diff --git a/aconfig/build_flags/release_configs.go b/aconfig/build_flags/release_configs.go new file mode 100644 index 000000000..3fa8a7c02 --- /dev/null +++ b/aconfig/build_flags/release_configs.go @@ -0,0 +1,78 @@ +// Copyright 2023 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 build_flags + +import ( + "path/filepath" + + "android/soong/android" + + "github.com/google/blueprint" +) + +type ReleaseConfigContributionsProviderData struct { + ContributionDir android.SourcePath +} + +var ReleaseConfigContributionsProviderKey = blueprint.NewProvider[ReleaseConfigContributionsProviderData]() + +// Soong uses `release_config_contributions` modules to produce the +// `build_flags/all_release_config_contributions.*` artifacts, listing *all* of +// the directories in the source tree that contribute to each release config, +// whether or not they are actually used for the lunch product. +// +// This artifact helps flagging automation determine in which directory a flag +// should be placed by default. +type ReleaseConfigContributionsModule struct { + android.ModuleBase + android.DefaultableModuleBase + + // Properties for "release_config_contributions" + properties struct { + // The `release_configs/*.textproto` files provided by this + // directory, relative to this Android.bp file + Srcs []string `android:"path"` + } +} + +func ReleaseConfigContributionsFactory() android.Module { + module := &ReleaseConfigContributionsModule{} + + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + module.AddProperties(&module.properties) + + return module +} + +func (module *ReleaseConfigContributionsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + srcs := android.PathsForModuleSrc(ctx, module.properties.Srcs) + if len(srcs) == 0 { + return + } + contributionDir := filepath.Dir(filepath.Dir(srcs[0].String())) + for _, file := range srcs { + if filepath.Dir(filepath.Dir(file.String())) != contributionDir { + ctx.ModuleErrorf("Cannot include %s with %s contributions", file, contributionDir) + } + if filepath.Base(filepath.Dir(file.String())) != "release_configs" || file.Ext() != ".textproto" { + ctx.ModuleErrorf("Invalid contribution file %s", file) + } + } + android.SetProvider(ctx, ReleaseConfigContributionsProviderKey, ReleaseConfigContributionsProviderData{ + ContributionDir: android.PathForSource(ctx, contributionDir), + }) + +} diff --git a/cmd/release_config/release_config_contributions/Android.bp b/cmd/release_config/release_config_contributions/Android.bp new file mode 100644 index 000000000..6882ea245 --- /dev/null +++ b/cmd/release_config/release_config_contributions/Android.bp @@ -0,0 +1,32 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +blueprint_go_binary { + name: "release-config-contributions", + deps: [ + "golang-protobuf-encoding-prototext", + "golang-protobuf-reflect-protoreflect", + "golang-protobuf-runtime-protoimpl", + "soong-cmd-release_config-proto", + "soong-cmd-release_config-lib", + ], + srcs: [ + "main.go", + ], +} + +bootstrap_go_package { + name: "soong-cmd-release_config-release_config_contributions", + pkgPath: "android/soong/cmd/release_config/release_config_contributions", + deps: [ + "golang-protobuf-encoding-prototext", + "golang-protobuf-reflect-protoreflect", + "golang-protobuf-runtime-protoimpl", + "soong-cmd-release_config-proto", + "soong-cmd-release_config-lib", + ], + srcs: [ + "main.go", + ], +} diff --git a/cmd/release_config/release_config_contributions/main.go b/cmd/release_config/release_config_contributions/main.go new file mode 100644 index 000000000..6abf768da --- /dev/null +++ b/cmd/release_config/release_config_contributions/main.go @@ -0,0 +1,130 @@ +package main + +import ( + "flag" + "fmt" + "os" + "slices" + "strings" + + rc_lib "android/soong/cmd/release_config/release_config_lib" + rc_proto "android/soong/cmd/release_config/release_config_proto" +) + +type Flags struct { + // The path to the top of the workspace. Default: ".". + top string + + // Output file. + output string + + // Format for output file + format string + + // List of release config directories to process. + dirs rc_lib.StringList + + // Disable warning messages + quiet bool + + // Panic on errors. + debug bool +} + +func sortDirectories(dirList []string) { + order := func(dir string) int { + switch { + // These three are always in this order. + case dir == "build/release": + return 1 + case dir == "vendor/google_shared/build/release": + return 2 + case dir == "vendor/google/release": + return 3 + // Keep their subdirs in the same order. + case strings.HasPrefix(dir, "build/release/"): + return 21 + case strings.HasPrefix(dir, "vendor/google_shared/build/release/"): + return 22 + case strings.HasPrefix(dir, "vendor/google/release/"): + return 23 + // Everything else sorts by directory path. + default: + return 99 + } + } + + slices.SortFunc(dirList, func(a, b string) int { + aOrder, bOrder := order(a), order(b) + if aOrder != bOrder { + return aOrder - bOrder + } + return strings.Compare(a, b) + }) +} + +func main() { + var flags Flags + topDir, err := rc_lib.GetTopDir() + + // Handle the common arguments + flag.StringVar(&flags.top, "top", topDir, "path to top of workspace") + flag.Var(&flags.dirs, "dir", "path to a release config contribution directory. May be repeated") + flag.StringVar(&flags.format, "format", "pb", "output file format") + flag.StringVar(&flags.output, "output", "release_config_contributions.pb", "output file") + flag.BoolVar(&flags.debug, "debug", false, "turn on debugging output for errors") + flag.BoolVar(&flags.quiet, "quiet", false, "disable warning messages") + flag.Parse() + + errorExit := func(err error) { + if flags.debug { + panic(err) + } + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + + if flags.quiet { + rc_lib.DisableWarnings() + } + + if err = os.Chdir(flags.top); err != nil { + errorExit(err) + } + + contributingDirsMap := make(map[string][]string) + for _, dir := range flags.dirs { + contributions, err := rc_lib.EnumerateReleaseConfigs(dir) + if err != nil { + errorExit(err) + } + for _, name := range contributions { + contributingDirsMap[name] = append(contributingDirsMap[name], dir) + } + } + + releaseConfigNames := []string{} + for name := range contributingDirsMap { + releaseConfigNames = append(releaseConfigNames, name) + } + slices.Sort(releaseConfigNames) + + message := &rc_proto.ReleaseConfigContributionsArtifacts{ + ReleaseConfigContributionsArtifactList: []*rc_proto.ReleaseConfigContributionsArtifact{}, + } + for _, name := range releaseConfigNames { + dirs := contributingDirsMap[name] + slices.Sort(dirs) + message.ReleaseConfigContributionsArtifactList = append( + message.ReleaseConfigContributionsArtifactList, + &rc_proto.ReleaseConfigContributionsArtifact{ + Name: &name, + ContributingDirectories: dirs, + }) + } + + err = rc_lib.WriteFormattedMessage(flags.output, flags.format, message) + if err != nil { + errorExit(err) + } +} diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go index 97eb8f156..831ec02f2 100644 --- a/cmd/release_config/release_config_lib/release_configs.go +++ b/cmd/release_config/release_config_lib/release_configs.go @@ -248,6 +248,18 @@ func (configs *ReleaseConfigs) GetFlagValueDirectory(config *ReleaseConfig, flag return configs.configDirs[index], nil } +// Return the (unsorted) release configs contributed to by `dir`. +func EnumerateReleaseConfigs(dir string) ([]string, error) { + var ret []string + err := WalkTextprotoFiles(dir, "release_configs", func(path string, d fs.DirEntry, err error) error { + // Strip off the trailing `.textproto` from the name. + name := filepath.Base(path) + ret = append(ret, name[:len(name)-10]) + return err + }) + return ret, err +} + func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex int) error { if _, err := os.Stat(path); err != nil { return fmt.Errorf("%s does not exist\n", path) diff --git a/cmd/release_config/release_config_proto/Android.bp b/cmd/release_config/release_config_proto/Android.bp index c34d2030e..c6869b1fc 100644 --- a/cmd/release_config/release_config_proto/Android.bp +++ b/cmd/release_config/release_config_proto/Android.bp @@ -28,5 +28,6 @@ bootstrap_go_package { "build_flags_declarations.pb.go", "build_flags_src.pb.go", "build_flags_out.pb.go", + "release_configs_contributions.pb.go", ], } |