1// Copyright 2023 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package build_flags 16 17import ( 18 "fmt" 19 20 "android/soong/android" 21) 22 23// A singleton module that collects all of the build flags declared in the 24// tree into a single combined file for export to the external flag setting 25// server (inside Google it's Gantry). 26// 27// Note that this is ALL build_declarations modules present in the tree, not just 28// ones that are relevant to the product currently being built, so that that infra 29// doesn't need to pull from multiple builds and merge them. 30func AllBuildFlagDeclarationsFactory() android.Singleton { 31 return &allBuildFlagDeclarationsSingleton{} 32} 33 34type allBuildFlagDeclarationsSingleton struct { 35 flagsBinaryProtoPath android.OutputPath 36 flagsTextProtoPath android.OutputPath 37 configsBinaryProtoPath android.OutputPath 38 configsTextProtoPath android.OutputPath 39} 40 41func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) { 42 // Find all of the build_flag_declarations modules 43 var flagsFiles android.Paths 44 // Find all of the release_config_contribution modules 45 var contributionDirs android.Paths 46 ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { 47 decl, ok := android.OtherModuleProvider(ctx, module, BuildFlagDeclarationsProviderKey) 48 if ok { 49 flagsFiles = append(flagsFiles, decl.IntermediateCacheOutputPath) 50 } 51 52 contrib, ok := android.OtherModuleProvider(ctx, module, ReleaseConfigContributionsProviderKey) 53 if ok { 54 contributionDirs = append(contributionDirs, contrib.ContributionDir) 55 } 56 }) 57 58 // Generate build action for build_flag (binary proto output) 59 this.flagsBinaryProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.pb") 60 ctx.Build(pctx, android.BuildParams{ 61 Rule: allDeclarationsRule, 62 Inputs: flagsFiles, 63 Output: this.flagsBinaryProtoPath, 64 Description: "all_build_flag_declarations", 65 Args: map[string]string{ 66 "intermediates": android.JoinPathsWithPrefix(flagsFiles, "--intermediate "), 67 }, 68 }) 69 ctx.Phony("all_build_flag_declarations", this.flagsBinaryProtoPath) 70 71 // Generate build action for build_flag (text proto output) 72 this.flagsTextProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.textproto") 73 ctx.Build(pctx, android.BuildParams{ 74 Rule: allDeclarationsRuleTextProto, 75 Input: this.flagsBinaryProtoPath, 76 Output: this.flagsTextProtoPath, 77 Description: "all_build_flag_declarations_textproto", 78 }) 79 ctx.Phony("all_build_flag_declarations_textproto", this.flagsTextProtoPath) 80 81 // Generate build action for release_configs (binary proto output) 82 this.configsBinaryProtoPath = android.PathForIntermediates(ctx, "all_release_config_contributions.pb") 83 ctx.Build(pctx, android.BuildParams{ 84 Rule: allReleaseConfigContributionsRule, 85 Inputs: contributionDirs, 86 Output: this.configsBinaryProtoPath, 87 Description: "all_release_config_contributions", 88 Args: map[string]string{ 89 "dirs": android.JoinPathsWithPrefix(contributionDirs, "--dir "), 90 "format": "pb", 91 }, 92 }) 93 ctx.Phony("all_release_config_contributions", this.configsBinaryProtoPath) 94 95 this.configsTextProtoPath = android.PathForIntermediates(ctx, "all_release_config_contributions.textproto") 96 ctx.Build(pctx, android.BuildParams{ 97 Rule: allReleaseConfigContributionsRule, 98 Inputs: contributionDirs, 99 Output: this.configsTextProtoPath, 100 Description: "all_release_config_contributions_textproto", 101 Args: map[string]string{ 102 "dirs": android.JoinPathsWithPrefix(contributionDirs, "--dir "), 103 "format": "textproto", 104 }, 105 }) 106 ctx.Phony("all_release_config_contributions_textproto", this.configsTextProtoPath) 107 108 // Add a simple target for ci/build_metadata to use. 109 ctx.Phony("release_config_metadata", 110 this.flagsBinaryProtoPath, 111 this.flagsTextProtoPath, 112 this.configsBinaryProtoPath, 113 this.configsTextProtoPath, 114 ) 115 116 ctx.DistForGoal("droid", this.flagsBinaryProtoPath) 117 for _, goal := range []string{"docs", "droid", "sdk", "release_config_metadata"} { 118 ctx.DistForGoalWithFilename(goal, this.flagsBinaryProtoPath, "build_flags/all_flags.pb") 119 ctx.DistForGoalWithFilename(goal, this.flagsTextProtoPath, "build_flags/all_flags.textproto") 120 ctx.DistForGoalWithFilename(goal, this.configsBinaryProtoPath, "build_flags/all_release_config_contributions.pb") 121 ctx.DistForGoalWithFilename(goal, this.configsTextProtoPath, "build_flags/all_release_config_contributions.textproto") 122 } 123 124 if ctx.Config().HasDeviceProduct() { 125 flagsDir := android.PathForOutput(ctx, "release-config") 126 baseAllRelease := fmt.Sprintf("all_release_configs-%s", ctx.Config().DeviceProduct()) 127 128 distAllReleaseConfigsArtifact := func(ext string) { 129 ctx.DistForGoalWithFilename( 130 "droid", 131 flagsDir.Join(ctx, fmt.Sprintf("%s.%s", baseAllRelease, ext)), 132 fmt.Sprintf("build_flags/all_release_configs.%s", ext), 133 ) 134 } 135 136 distAllReleaseConfigsArtifact("pb") 137 distAllReleaseConfigsArtifact("textproto") 138 distAllReleaseConfigsArtifact("json") 139 ctx.DistForGoalWithFilename( 140 "droid", 141 flagsDir.Join(ctx, fmt.Sprintf("inheritance_graph-%s.dot", ctx.Config().DeviceProduct())), 142 fmt.Sprintf("build_flags/inheritance_graph-%s.dot", ctx.Config().DeviceProduct()), 143 ) 144 } 145} 146