1*333d2b36SAndroid Build Coastguard Worker// Copyright 2015 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Worker// A genrule module takes a list of source files ("srcs" property), an optional 16*333d2b36SAndroid Build Coastguard Worker// list of tools ("tools" property), and a command line ("cmd" property), to 17*333d2b36SAndroid Build Coastguard Worker// generate output files ("out" property). 18*333d2b36SAndroid Build Coastguard Worker 19*333d2b36SAndroid Build Coastguard Workerpackage genrule 20*333d2b36SAndroid Build Coastguard Worker 21*333d2b36SAndroid Build Coastguard Workerimport ( 22*333d2b36SAndroid Build Coastguard Worker "fmt" 23*333d2b36SAndroid Build Coastguard Worker "io" 24*333d2b36SAndroid Build Coastguard Worker "path/filepath" 25*333d2b36SAndroid Build Coastguard Worker "strconv" 26*333d2b36SAndroid Build Coastguard Worker "strings" 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 29*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 30*333d2b36SAndroid Build Coastguard Worker 31*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 32*333d2b36SAndroid Build Coastguard Worker) 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Workerfunc init() { 35*333d2b36SAndroid Build Coastguard Worker RegisterGenruleBuildComponents(android.InitRegistrationContext) 36*333d2b36SAndroid Build Coastguard Worker} 37*333d2b36SAndroid Build Coastguard Worker 38*333d2b36SAndroid Build Coastguard Worker// Test fixture preparer that will register most genrule build components. 39*333d2b36SAndroid Build Coastguard Worker// 40*333d2b36SAndroid Build Coastguard Worker// Singletons and mutators should only be added here if they are needed for a majority of genrule 41*333d2b36SAndroid Build Coastguard Worker// module types, otherwise they should be added under a separate preparer to allow them to be 42*333d2b36SAndroid Build Coastguard Worker// selected only when needed to reduce test execution time. 43*333d2b36SAndroid Build Coastguard Worker// 44*333d2b36SAndroid Build Coastguard Worker// Module types do not have much of an overhead unless they are used so this should include as many 45*333d2b36SAndroid Build Coastguard Worker// module types as possible. The exceptions are those module types that require mutators and/or 46*333d2b36SAndroid Build Coastguard Worker// singletons in order to function in which case they should be kept together in a separate 47*333d2b36SAndroid Build Coastguard Worker// preparer. 48*333d2b36SAndroid Build Coastguard Workervar PrepareForTestWithGenRuleBuildComponents = android.GroupFixturePreparers( 49*333d2b36SAndroid Build Coastguard Worker android.FixtureRegisterWithContext(RegisterGenruleBuildComponents), 50*333d2b36SAndroid Build Coastguard Worker) 51*333d2b36SAndroid Build Coastguard Worker 52*333d2b36SAndroid Build Coastguard Worker// Prepare a fixture to use all genrule module types, mutators and singletons fully. 53*333d2b36SAndroid Build Coastguard Worker// 54*333d2b36SAndroid Build Coastguard Worker// This should only be used by tests that want to run with as much of the build enabled as possible. 55*333d2b36SAndroid Build Coastguard Workervar PrepareForIntegrationTestWithGenrule = android.GroupFixturePreparers( 56*333d2b36SAndroid Build Coastguard Worker PrepareForTestWithGenRuleBuildComponents, 57*333d2b36SAndroid Build Coastguard Worker) 58*333d2b36SAndroid Build Coastguard Worker 59*333d2b36SAndroid Build Coastguard Workerfunc RegisterGenruleBuildComponents(ctx android.RegistrationContext) { 60*333d2b36SAndroid Build Coastguard Worker ctx.RegisterModuleType("genrule_defaults", defaultsFactory) 61*333d2b36SAndroid Build Coastguard Worker 62*333d2b36SAndroid Build Coastguard Worker ctx.RegisterModuleType("gensrcs", GenSrcsFactory) 63*333d2b36SAndroid Build Coastguard Worker ctx.RegisterModuleType("genrule", GenRuleFactory) 64*333d2b36SAndroid Build Coastguard Worker 65*333d2b36SAndroid Build Coastguard Worker ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { 66*333d2b36SAndroid Build Coastguard Worker ctx.BottomUp("genrule_tool_deps", toolDepsMutator) 67*333d2b36SAndroid Build Coastguard Worker }) 68*333d2b36SAndroid Build Coastguard Worker} 69*333d2b36SAndroid Build Coastguard Worker 70*333d2b36SAndroid Build Coastguard Workervar ( 71*333d2b36SAndroid Build Coastguard Worker pctx = android.NewPackageContext("android/soong/genrule") 72*333d2b36SAndroid Build Coastguard Worker 73*333d2b36SAndroid Build Coastguard Worker // Used by gensrcs when there is more than 1 shard to merge the outputs 74*333d2b36SAndroid Build Coastguard Worker // of each shard into a zip file. 75*333d2b36SAndroid Build Coastguard Worker gensrcsMerge = pctx.AndroidStaticRule("gensrcsMerge", blueprint.RuleParams{ 76*333d2b36SAndroid Build Coastguard Worker Command: "${soongZip} -o ${tmpZip} @${tmpZip}.rsp && ${zipSync} -d ${genDir} ${tmpZip}", 77*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"${soongZip}", "${zipSync}"}, 78*333d2b36SAndroid Build Coastguard Worker Rspfile: "${tmpZip}.rsp", 79*333d2b36SAndroid Build Coastguard Worker RspfileContent: "${zipArgs}", 80*333d2b36SAndroid Build Coastguard Worker }, "tmpZip", "genDir", "zipArgs") 81*333d2b36SAndroid Build Coastguard Worker) 82*333d2b36SAndroid Build Coastguard Worker 83*333d2b36SAndroid Build Coastguard Workerfunc init() { 84*333d2b36SAndroid Build Coastguard Worker pctx.Import("android/soong/android") 85*333d2b36SAndroid Build Coastguard Worker 86*333d2b36SAndroid Build Coastguard Worker pctx.HostBinToolVariable("soongZip", "soong_zip") 87*333d2b36SAndroid Build Coastguard Worker pctx.HostBinToolVariable("zipSync", "zipsync") 88*333d2b36SAndroid Build Coastguard Worker} 89*333d2b36SAndroid Build Coastguard Worker 90*333d2b36SAndroid Build Coastguard Workertype SourceFileGenerator interface { 91*333d2b36SAndroid Build Coastguard Worker GeneratedSourceFiles() android.Paths 92*333d2b36SAndroid Build Coastguard Worker GeneratedHeaderDirs() android.Paths 93*333d2b36SAndroid Build Coastguard Worker GeneratedDeps() android.Paths 94*333d2b36SAndroid Build Coastguard Worker} 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker// Alias for android.HostToolProvider 97*333d2b36SAndroid Build Coastguard Worker// Deprecated: use android.HostToolProvider instead. 98*333d2b36SAndroid Build Coastguard Workertype HostToolProvider interface { 99*333d2b36SAndroid Build Coastguard Worker android.HostToolProvider 100*333d2b36SAndroid Build Coastguard Worker} 101*333d2b36SAndroid Build Coastguard Worker 102*333d2b36SAndroid Build Coastguard Workertype hostToolDependencyTag struct { 103*333d2b36SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 104*333d2b36SAndroid Build Coastguard Worker android.LicenseAnnotationToolchainDependencyTag 105*333d2b36SAndroid Build Coastguard Worker label string 106*333d2b36SAndroid Build Coastguard Worker} 107*333d2b36SAndroid Build Coastguard Worker 108*333d2b36SAndroid Build Coastguard Workerfunc (t hostToolDependencyTag) AllowDisabledModuleDependency(target android.Module) bool { 109*333d2b36SAndroid Build Coastguard Worker // Allow depending on a disabled module if it's replaced by a prebuilt 110*333d2b36SAndroid Build Coastguard Worker // counterpart. We get the prebuilt through android.PrebuiltGetPreferred in 111*333d2b36SAndroid Build Coastguard Worker // GenerateAndroidBuildActions. 112*333d2b36SAndroid Build Coastguard Worker return target.IsReplacedByPrebuilt() 113*333d2b36SAndroid Build Coastguard Worker} 114*333d2b36SAndroid Build Coastguard Worker 115*333d2b36SAndroid Build Coastguard Workerfunc (t hostToolDependencyTag) AllowDisabledModuleDependencyProxy( 116*333d2b36SAndroid Build Coastguard Worker ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool { 117*333d2b36SAndroid Build Coastguard Worker return android.OtherModuleProviderOrDefault( 118*333d2b36SAndroid Build Coastguard Worker ctx, target, android.CommonModuleInfoKey).ReplacedByPrebuilt 119*333d2b36SAndroid Build Coastguard Worker} 120*333d2b36SAndroid Build Coastguard Worker 121*333d2b36SAndroid Build Coastguard Workervar _ android.AllowDisabledModuleDependency = (*hostToolDependencyTag)(nil) 122*333d2b36SAndroid Build Coastguard Worker 123*333d2b36SAndroid Build Coastguard Workertype generatorProperties struct { 124*333d2b36SAndroid Build Coastguard Worker // The command to run on one or more input files. Cmd supports substitution of a few variables. 125*333d2b36SAndroid Build Coastguard Worker // 126*333d2b36SAndroid Build Coastguard Worker // Available variables for substitution: 127*333d2b36SAndroid Build Coastguard Worker // 128*333d2b36SAndroid Build Coastguard Worker // $(location): the path to the first entry in tools or tool_files. 129*333d2b36SAndroid Build Coastguard Worker // $(location <label>): the path to the tool, tool_file, input or output with name <label>. Use $(location) if <label> refers to a rule that outputs exactly one file. 130*333d2b36SAndroid Build Coastguard Worker // $(locations <label>): the paths to the tools, tool_files, inputs or outputs with name <label>. Use $(locations) if <label> refers to a rule that outputs two or more files. 131*333d2b36SAndroid Build Coastguard Worker // $(in): one or more input files. 132*333d2b36SAndroid Build Coastguard Worker // $(out): a single output file. 133*333d2b36SAndroid Build Coastguard Worker // $(genDir): the sandbox directory for this tool; contains $(out). 134*333d2b36SAndroid Build Coastguard Worker // $$: a literal $ 135*333d2b36SAndroid Build Coastguard Worker Cmd proptools.Configurable[string] `android:"replace_instead_of_append"` 136*333d2b36SAndroid Build Coastguard Worker 137*333d2b36SAndroid Build Coastguard Worker // name of the modules (if any) that produces the host executable. Leave empty for 138*333d2b36SAndroid Build Coastguard Worker // prebuilts or scripts that do not need a module to build them. 139*333d2b36SAndroid Build Coastguard Worker Tools []string 140*333d2b36SAndroid Build Coastguard Worker 141*333d2b36SAndroid Build Coastguard Worker // Local files that are used by the tool 142*333d2b36SAndroid Build Coastguard Worker Tool_files []string `android:"path"` 143*333d2b36SAndroid Build Coastguard Worker 144*333d2b36SAndroid Build Coastguard Worker // List of directories to export generated headers from 145*333d2b36SAndroid Build Coastguard Worker Export_include_dirs []string 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Worker // list of input files 148*333d2b36SAndroid Build Coastguard Worker Srcs proptools.Configurable[[]string] `android:"path,arch_variant"` 149*333d2b36SAndroid Build Coastguard Worker 150*333d2b36SAndroid Build Coastguard Worker // Same as srcs, but will add dependencies on modules via a device os variation and the device's 151*333d2b36SAndroid Build Coastguard Worker // first supported arch's variation. Can be used to add a dependency from a host genrule to 152*333d2b36SAndroid Build Coastguard Worker // a device module. 153*333d2b36SAndroid Build Coastguard Worker Device_first_srcs proptools.Configurable[[]string] `android:"path_device_first"` 154*333d2b36SAndroid Build Coastguard Worker 155*333d2b36SAndroid Build Coastguard Worker // Same as srcs, but will add dependencies on modules via a device os variation and the common 156*333d2b36SAndroid Build Coastguard Worker // arch variation. Can be used to add a dependency from a host genrule to a device module. 157*333d2b36SAndroid Build Coastguard Worker Device_common_srcs proptools.Configurable[[]string] `android:"path_device_common"` 158*333d2b36SAndroid Build Coastguard Worker 159*333d2b36SAndroid Build Coastguard Worker // Same as srcs, but will add dependencies on modules via a common_os os variation. 160*333d2b36SAndroid Build Coastguard Worker Common_os_srcs proptools.Configurable[[]string] `android:"path_common_os"` 161*333d2b36SAndroid Build Coastguard Worker 162*333d2b36SAndroid Build Coastguard Worker // input files to exclude 163*333d2b36SAndroid Build Coastguard Worker Exclude_srcs []string `android:"path,arch_variant"` 164*333d2b36SAndroid Build Coastguard Worker 165*333d2b36SAndroid Build Coastguard Worker // Enable restat to update the output only if the output is changed 166*333d2b36SAndroid Build Coastguard Worker Write_if_changed *bool 167*333d2b36SAndroid Build Coastguard Worker 168*333d2b36SAndroid Build Coastguard Worker // When set to true, an additional $(build_number_file) label will be available 169*333d2b36SAndroid Build Coastguard Worker // to use in the cmd. This will be the location of a text file containing the 170*333d2b36SAndroid Build Coastguard Worker // build number. The dependency on this file will be "order-only", meaning that 171*333d2b36SAndroid Build Coastguard Worker // the genrule will not rerun when only this file changes, to avoid rerunning 172*333d2b36SAndroid Build Coastguard Worker // the genrule every build, because the build number changes every build. 173*333d2b36SAndroid Build Coastguard Worker // This also means that you should not attempt to consume the build number from 174*333d2b36SAndroid Build Coastguard Worker // the result of this genrule in another build rule. If you do, the build number 175*333d2b36SAndroid Build Coastguard Worker // in the second build rule will be stale when the second build rule rebuilds 176*333d2b36SAndroid Build Coastguard Worker // but this genrule does not. Only certain allowlisted modules are allowed to 177*333d2b36SAndroid Build Coastguard Worker // use this property, usages of the build number should be kept to the absolute 178*333d2b36SAndroid Build Coastguard Worker // minimum. Particularly no modules on the system image may include the build 179*333d2b36SAndroid Build Coastguard Worker // number. Prefer using libbuildversion via the use_version_lib property on 180*333d2b36SAndroid Build Coastguard Worker // cc modules. 181*333d2b36SAndroid Build Coastguard Worker Uses_order_only_build_number_file *bool 182*333d2b36SAndroid Build Coastguard Worker} 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Workertype Module struct { 185*333d2b36SAndroid Build Coastguard Worker android.ModuleBase 186*333d2b36SAndroid Build Coastguard Worker android.DefaultableModuleBase 187*333d2b36SAndroid Build Coastguard Worker android.ApexModuleBase 188*333d2b36SAndroid Build Coastguard Worker 189*333d2b36SAndroid Build Coastguard Worker // For other packages to make their own genrules with extra 190*333d2b36SAndroid Build Coastguard Worker // properties 191*333d2b36SAndroid Build Coastguard Worker Extra interface{} 192*333d2b36SAndroid Build Coastguard Worker 193*333d2b36SAndroid Build Coastguard Worker // CmdModifier can be set by wrappers around genrule to modify the command, for example to 194*333d2b36SAndroid Build Coastguard Worker // prefix environment variables to it. 195*333d2b36SAndroid Build Coastguard Worker CmdModifier func(ctx android.ModuleContext, cmd string) string 196*333d2b36SAndroid Build Coastguard Worker 197*333d2b36SAndroid Build Coastguard Worker android.ImageInterface 198*333d2b36SAndroid Build Coastguard Worker 199*333d2b36SAndroid Build Coastguard Worker properties generatorProperties 200*333d2b36SAndroid Build Coastguard Worker 201*333d2b36SAndroid Build Coastguard Worker // For the different tasks that genrule and gensrc generate. genrule will 202*333d2b36SAndroid Build Coastguard Worker // generate 1 task, and gensrc will generate 1 or more tasks based on the 203*333d2b36SAndroid Build Coastguard Worker // number of shards the input files are sharded into. 204*333d2b36SAndroid Build Coastguard Worker taskGenerator taskFunc 205*333d2b36SAndroid Build Coastguard Worker 206*333d2b36SAndroid Build Coastguard Worker rule blueprint.Rule 207*333d2b36SAndroid Build Coastguard Worker rawCommands []string 208*333d2b36SAndroid Build Coastguard Worker 209*333d2b36SAndroid Build Coastguard Worker exportedIncludeDirs android.Paths 210*333d2b36SAndroid Build Coastguard Worker 211*333d2b36SAndroid Build Coastguard Worker outputFiles android.Paths 212*333d2b36SAndroid Build Coastguard Worker outputDeps android.Paths 213*333d2b36SAndroid Build Coastguard Worker 214*333d2b36SAndroid Build Coastguard Worker subName string 215*333d2b36SAndroid Build Coastguard Worker subDir string 216*333d2b36SAndroid Build Coastguard Worker} 217*333d2b36SAndroid Build Coastguard Worker 218*333d2b36SAndroid Build Coastguard Workertype taskFunc func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask 219*333d2b36SAndroid Build Coastguard Worker 220*333d2b36SAndroid Build Coastguard Workertype generateTask struct { 221*333d2b36SAndroid Build Coastguard Worker in android.Paths 222*333d2b36SAndroid Build Coastguard Worker out android.WritablePaths 223*333d2b36SAndroid Build Coastguard Worker copyTo android.WritablePaths // For gensrcs to set on gensrcsMerge rule. 224*333d2b36SAndroid Build Coastguard Worker genDir android.WritablePath 225*333d2b36SAndroid Build Coastguard Worker extraInputs map[string][]string 226*333d2b36SAndroid Build Coastguard Worker 227*333d2b36SAndroid Build Coastguard Worker cmd string 228*333d2b36SAndroid Build Coastguard Worker // For gensrsc sharding. 229*333d2b36SAndroid Build Coastguard Worker shard int 230*333d2b36SAndroid Build Coastguard Worker shards int 231*333d2b36SAndroid Build Coastguard Worker 232*333d2b36SAndroid Build Coastguard Worker // For nsjail tasks 233*333d2b36SAndroid Build Coastguard Worker useNsjail bool 234*333d2b36SAndroid Build Coastguard Worker dirSrcs android.DirectoryPaths 235*333d2b36SAndroid Build Coastguard Worker keepGendir bool 236*333d2b36SAndroid Build Coastguard Worker} 237*333d2b36SAndroid Build Coastguard Worker 238*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) GeneratedSourceFiles() android.Paths { 239*333d2b36SAndroid Build Coastguard Worker return g.outputFiles 240*333d2b36SAndroid Build Coastguard Worker} 241*333d2b36SAndroid Build Coastguard Worker 242*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) Srcs() android.Paths { 243*333d2b36SAndroid Build Coastguard Worker return append(android.Paths{}, g.outputFiles...) 244*333d2b36SAndroid Build Coastguard Worker} 245*333d2b36SAndroid Build Coastguard Worker 246*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) GeneratedHeaderDirs() android.Paths { 247*333d2b36SAndroid Build Coastguard Worker return g.exportedIncludeDirs 248*333d2b36SAndroid Build Coastguard Worker} 249*333d2b36SAndroid Build Coastguard Worker 250*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) GeneratedDeps() android.Paths { 251*333d2b36SAndroid Build Coastguard Worker return g.outputDeps 252*333d2b36SAndroid Build Coastguard Worker} 253*333d2b36SAndroid Build Coastguard Worker 254*333d2b36SAndroid Build Coastguard Workervar _ android.SourceFileProducer = (*Module)(nil) 255*333d2b36SAndroid Build Coastguard Worker 256*333d2b36SAndroid Build Coastguard Workerfunc toolDepsMutator(ctx android.BottomUpMutatorContext) { 257*333d2b36SAndroid Build Coastguard Worker if g, ok := ctx.Module().(*Module); ok { 258*333d2b36SAndroid Build Coastguard Worker for _, tool := range g.properties.Tools { 259*333d2b36SAndroid Build Coastguard Worker tag := hostToolDependencyTag{label: tool} 260*333d2b36SAndroid Build Coastguard Worker if m := android.SrcIsModule(tool); m != "" { 261*333d2b36SAndroid Build Coastguard Worker tool = m 262*333d2b36SAndroid Build Coastguard Worker } 263*333d2b36SAndroid Build Coastguard Worker ctx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), tag, tool) 264*333d2b36SAndroid Build Coastguard Worker } 265*333d2b36SAndroid Build Coastguard Worker } 266*333d2b36SAndroid Build Coastguard Worker} 267*333d2b36SAndroid Build Coastguard Worker 268*333d2b36SAndroid Build Coastguard Workervar buildNumberAllowlistKey = android.NewOnceKey("genruleBuildNumberAllowlistKey") 269*333d2b36SAndroid Build Coastguard Worker 270*333d2b36SAndroid Build Coastguard Worker// This allowlist should be kept to the bare minimum, it's 271*333d2b36SAndroid Build Coastguard Worker// intended for things that existed before the build number 272*333d2b36SAndroid Build Coastguard Worker// was tightly controlled. Prefer using libbuildversion 273*333d2b36SAndroid Build Coastguard Worker// via the use_version_lib property of cc modules. 274*333d2b36SAndroid Build Coastguard Worker// This is a function instead of a global map so that 275*333d2b36SAndroid Build Coastguard Worker// soong plugins cannot add entries to the allowlist 276*333d2b36SAndroid Build Coastguard Workerfunc isModuleInBuildNumberAllowlist(ctx android.ModuleContext) bool { 277*333d2b36SAndroid Build Coastguard Worker allowlist := ctx.Config().Once(buildNumberAllowlistKey, func() interface{} { 278*333d2b36SAndroid Build Coastguard Worker // Define the allowlist as a list and then copy it into a map so that 279*333d2b36SAndroid Build Coastguard Worker // gofmt doesn't change unnecessary lines trying to align the values of the map. 280*333d2b36SAndroid Build Coastguard Worker allowlist := []string{ 281*333d2b36SAndroid Build Coastguard Worker // go/keep-sorted start 282*333d2b36SAndroid Build Coastguard Worker "build/soong/tests:gen", 283*333d2b36SAndroid Build Coastguard Worker "hardware/google/camera/common/hal/aidl_service:aidl_camera_build_version", 284*333d2b36SAndroid Build Coastguard Worker "tools/tradefederation/core:tradefed_zip", 285*333d2b36SAndroid Build Coastguard Worker "vendor/google/services/LyricCameraHAL/src/apex:com.google.pixel.camera.hal.manifest", 286*333d2b36SAndroid Build Coastguard Worker // go/keep-sorted end 287*333d2b36SAndroid Build Coastguard Worker } 288*333d2b36SAndroid Build Coastguard Worker allowlistMap := make(map[string]bool, len(allowlist)) 289*333d2b36SAndroid Build Coastguard Worker for _, a := range allowlist { 290*333d2b36SAndroid Build Coastguard Worker allowlistMap[a] = true 291*333d2b36SAndroid Build Coastguard Worker } 292*333d2b36SAndroid Build Coastguard Worker return allowlistMap 293*333d2b36SAndroid Build Coastguard Worker }).(map[string]bool) 294*333d2b36SAndroid Build Coastguard Worker 295*333d2b36SAndroid Build Coastguard Worker _, ok := allowlist[ctx.ModuleDir()+":"+ctx.ModuleName()] 296*333d2b36SAndroid Build Coastguard Worker return ok 297*333d2b36SAndroid Build Coastguard Worker} 298*333d2b36SAndroid Build Coastguard Worker 299*333d2b36SAndroid Build Coastguard Worker// generateCommonBuildActions contains build action generation logic 300*333d2b36SAndroid Build Coastguard Worker// common to both the mixed build case and the legacy case of genrule processing. 301*333d2b36SAndroid Build Coastguard Worker// To fully support genrule in mixed builds, the contents of this function should 302*333d2b36SAndroid Build Coastguard Worker// approach zero; there should be no genrule action registration done directly 303*333d2b36SAndroid Build Coastguard Worker// by Soong logic in the mixed-build case. 304*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { 305*333d2b36SAndroid Build Coastguard Worker // Add the variant as a suffix to the make modules to create, so that the make modules 306*333d2b36SAndroid Build Coastguard Worker // don't conflict because make doesn't know about variants. However, this causes issues with 307*333d2b36SAndroid Build Coastguard Worker // tracking required dependencies as the required property in soong is passed straight to make 308*333d2b36SAndroid Build Coastguard Worker // without accounting for these suffixes. To make it a little easier to work with, don't use 309*333d2b36SAndroid Build Coastguard Worker // a suffix for android_common variants so that java_genrules look like regular 1-variant 310*333d2b36SAndroid Build Coastguard Worker // genrules to make. 311*333d2b36SAndroid Build Coastguard Worker if ctx.ModuleSubDir() != "android_common" { 312*333d2b36SAndroid Build Coastguard Worker g.subName = ctx.ModuleSubDir() 313*333d2b36SAndroid Build Coastguard Worker } 314*333d2b36SAndroid Build Coastguard Worker 315*333d2b36SAndroid Build Coastguard Worker if len(g.properties.Export_include_dirs) > 0 { 316*333d2b36SAndroid Build Coastguard Worker for _, dir := range g.properties.Export_include_dirs { 317*333d2b36SAndroid Build Coastguard Worker g.exportedIncludeDirs = append(g.exportedIncludeDirs, 318*333d2b36SAndroid Build Coastguard Worker android.PathForModuleGen(ctx, g.subDir, ctx.ModuleDir(), dir)) 319*333d2b36SAndroid Build Coastguard Worker // Also export without ModuleDir for consistency with Export_include_dirs not being set 320*333d2b36SAndroid Build Coastguard Worker g.exportedIncludeDirs = append(g.exportedIncludeDirs, 321*333d2b36SAndroid Build Coastguard Worker android.PathForModuleGen(ctx, g.subDir, dir)) 322*333d2b36SAndroid Build Coastguard Worker } 323*333d2b36SAndroid Build Coastguard Worker } else { 324*333d2b36SAndroid Build Coastguard Worker g.exportedIncludeDirs = append(g.exportedIncludeDirs, android.PathForModuleGen(ctx, g.subDir)) 325*333d2b36SAndroid Build Coastguard Worker } 326*333d2b36SAndroid Build Coastguard Worker 327*333d2b36SAndroid Build Coastguard Worker locationLabels := map[string]location{} 328*333d2b36SAndroid Build Coastguard Worker firstLabel := "" 329*333d2b36SAndroid Build Coastguard Worker 330*333d2b36SAndroid Build Coastguard Worker addLocationLabel := func(label string, loc location) { 331*333d2b36SAndroid Build Coastguard Worker if firstLabel == "" { 332*333d2b36SAndroid Build Coastguard Worker firstLabel = label 333*333d2b36SAndroid Build Coastguard Worker } 334*333d2b36SAndroid Build Coastguard Worker if _, exists := locationLabels[label]; !exists { 335*333d2b36SAndroid Build Coastguard Worker locationLabels[label] = loc 336*333d2b36SAndroid Build Coastguard Worker } else { 337*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("multiple locations for label %q: %q and %q (do you have duplicate srcs entries?)", 338*333d2b36SAndroid Build Coastguard Worker label, locationLabels[label], loc) 339*333d2b36SAndroid Build Coastguard Worker } 340*333d2b36SAndroid Build Coastguard Worker } 341*333d2b36SAndroid Build Coastguard Worker 342*333d2b36SAndroid Build Coastguard Worker var tools android.Paths 343*333d2b36SAndroid Build Coastguard Worker var packagedTools []android.PackagingSpec 344*333d2b36SAndroid Build Coastguard Worker if len(g.properties.Tools) > 0 { 345*333d2b36SAndroid Build Coastguard Worker seenTools := make(map[string]bool) 346*333d2b36SAndroid Build Coastguard Worker ctx.VisitDirectDepsProxyAllowDisabled(func(proxy android.ModuleProxy) { 347*333d2b36SAndroid Build Coastguard Worker switch tag := ctx.OtherModuleDependencyTag(proxy).(type) { 348*333d2b36SAndroid Build Coastguard Worker case hostToolDependencyTag: 349*333d2b36SAndroid Build Coastguard Worker // Necessary to retrieve any prebuilt replacement for the tool, since 350*333d2b36SAndroid Build Coastguard Worker // toolDepsMutator runs too late for the prebuilt mutators to have 351*333d2b36SAndroid Build Coastguard Worker // replaced the dependency. 352*333d2b36SAndroid Build Coastguard Worker module := android.PrebuiltGetPreferred(ctx, proxy) 353*333d2b36SAndroid Build Coastguard Worker tool := ctx.OtherModuleName(module) 354*333d2b36SAndroid Build Coastguard Worker if h, ok := android.OtherModuleProvider(ctx, module, android.HostToolProviderKey); ok { 355*333d2b36SAndroid Build Coastguard Worker // A HostToolProvider provides the path to a tool, which will be copied 356*333d2b36SAndroid Build Coastguard Worker // into the sandbox. 357*333d2b36SAndroid Build Coastguard Worker if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled { 358*333d2b36SAndroid Build Coastguard Worker if ctx.Config().AllowMissingDependencies() { 359*333d2b36SAndroid Build Coastguard Worker ctx.AddMissingDependencies([]string{tool}) 360*333d2b36SAndroid Build Coastguard Worker } else { 361*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("depends on disabled module %q", tool) 362*333d2b36SAndroid Build Coastguard Worker } 363*333d2b36SAndroid Build Coastguard Worker return 364*333d2b36SAndroid Build Coastguard Worker } 365*333d2b36SAndroid Build Coastguard Worker path := h.HostToolPath 366*333d2b36SAndroid Build Coastguard Worker if !path.Valid() { 367*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("host tool %q missing output file", tool) 368*333d2b36SAndroid Build Coastguard Worker return 369*333d2b36SAndroid Build Coastguard Worker } 370*333d2b36SAndroid Build Coastguard Worker if specs := android.OtherModuleProviderOrDefault( 371*333d2b36SAndroid Build Coastguard Worker ctx, module, android.InstallFilesProvider).TransitivePackagingSpecs.ToList(); specs != nil { 372*333d2b36SAndroid Build Coastguard Worker // If the HostToolProvider has PackgingSpecs, which are definitions of the 373*333d2b36SAndroid Build Coastguard Worker // required relative locations of the tool and its dependencies, use those 374*333d2b36SAndroid Build Coastguard Worker // instead. They will be copied to those relative locations in the sbox 375*333d2b36SAndroid Build Coastguard Worker // sandbox. 376*333d2b36SAndroid Build Coastguard Worker // Care must be taken since TransitivePackagingSpec may return device-side 377*333d2b36SAndroid Build Coastguard Worker // paths via the required property. Filter them out. 378*333d2b36SAndroid Build Coastguard Worker for i, ps := range specs { 379*333d2b36SAndroid Build Coastguard Worker if ps.Partition() != "" { 380*333d2b36SAndroid Build Coastguard Worker if i == 0 { 381*333d2b36SAndroid Build Coastguard Worker panic("first PackagingSpec is assumed to be the host-side tool") 382*333d2b36SAndroid Build Coastguard Worker } 383*333d2b36SAndroid Build Coastguard Worker continue 384*333d2b36SAndroid Build Coastguard Worker } 385*333d2b36SAndroid Build Coastguard Worker packagedTools = append(packagedTools, ps) 386*333d2b36SAndroid Build Coastguard Worker } 387*333d2b36SAndroid Build Coastguard Worker // Assume that the first PackagingSpec of the module is the tool. 388*333d2b36SAndroid Build Coastguard Worker addLocationLabel(tag.label, packagedToolLocation{specs[0]}) 389*333d2b36SAndroid Build Coastguard Worker } else { 390*333d2b36SAndroid Build Coastguard Worker tools = append(tools, path.Path()) 391*333d2b36SAndroid Build Coastguard Worker addLocationLabel(tag.label, toolLocation{android.Paths{path.Path()}}) 392*333d2b36SAndroid Build Coastguard Worker } 393*333d2b36SAndroid Build Coastguard Worker } else { 394*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("%q is not a host tool provider", tool) 395*333d2b36SAndroid Build Coastguard Worker return 396*333d2b36SAndroid Build Coastguard Worker } 397*333d2b36SAndroid Build Coastguard Worker 398*333d2b36SAndroid Build Coastguard Worker seenTools[tag.label] = true 399*333d2b36SAndroid Build Coastguard Worker } 400*333d2b36SAndroid Build Coastguard Worker }) 401*333d2b36SAndroid Build Coastguard Worker 402*333d2b36SAndroid Build Coastguard Worker // If AllowMissingDependencies is enabled, the build will not have stopped when 403*333d2b36SAndroid Build Coastguard Worker // AddFarVariationDependencies was called on a missing tool, which will result in nonsensical 404*333d2b36SAndroid Build Coastguard Worker // "cmd: unknown location label ..." errors later. Add a placeholder file to the local label. 405*333d2b36SAndroid Build Coastguard Worker // The command that uses this placeholder file will never be executed because the rule will be 406*333d2b36SAndroid Build Coastguard Worker // replaced with an android.Error rule reporting the missing dependencies. 407*333d2b36SAndroid Build Coastguard Worker if ctx.Config().AllowMissingDependencies() { 408*333d2b36SAndroid Build Coastguard Worker for _, tool := range g.properties.Tools { 409*333d2b36SAndroid Build Coastguard Worker if !seenTools[tool] { 410*333d2b36SAndroid Build Coastguard Worker addLocationLabel(tool, errorLocation{"***missing tool " + tool + "***"}) 411*333d2b36SAndroid Build Coastguard Worker } 412*333d2b36SAndroid Build Coastguard Worker } 413*333d2b36SAndroid Build Coastguard Worker } 414*333d2b36SAndroid Build Coastguard Worker } 415*333d2b36SAndroid Build Coastguard Worker 416*333d2b36SAndroid Build Coastguard Worker if ctx.Failed() { 417*333d2b36SAndroid Build Coastguard Worker return 418*333d2b36SAndroid Build Coastguard Worker } 419*333d2b36SAndroid Build Coastguard Worker 420*333d2b36SAndroid Build Coastguard Worker for _, toolFile := range g.properties.Tool_files { 421*333d2b36SAndroid Build Coastguard Worker paths := android.PathsForModuleSrc(ctx, []string{toolFile}) 422*333d2b36SAndroid Build Coastguard Worker tools = append(tools, paths...) 423*333d2b36SAndroid Build Coastguard Worker addLocationLabel(toolFile, toolLocation{paths}) 424*333d2b36SAndroid Build Coastguard Worker } 425*333d2b36SAndroid Build Coastguard Worker 426*333d2b36SAndroid Build Coastguard Worker addLabelsForInputs := func(propName string, include, exclude []string) android.Paths { 427*333d2b36SAndroid Build Coastguard Worker includeDirInPaths := ctx.DeviceConfig().BuildBrokenInputDir(g.Name()) 428*333d2b36SAndroid Build Coastguard Worker var srcFiles android.Paths 429*333d2b36SAndroid Build Coastguard Worker for _, in := range include { 430*333d2b36SAndroid Build Coastguard Worker paths, missingDeps := android.PathsAndMissingDepsRelativeToModuleSourceDir(android.SourceInput{ 431*333d2b36SAndroid Build Coastguard Worker Context: ctx, Paths: []string{in}, ExcludePaths: exclude, IncludeDirs: includeDirInPaths, 432*333d2b36SAndroid Build Coastguard Worker }) 433*333d2b36SAndroid Build Coastguard Worker if len(missingDeps) > 0 { 434*333d2b36SAndroid Build Coastguard Worker if !ctx.Config().AllowMissingDependencies() { 435*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("should never get here, the missing dependencies %q should have been reported in DepsMutator", 436*333d2b36SAndroid Build Coastguard Worker missingDeps)) 437*333d2b36SAndroid Build Coastguard Worker } 438*333d2b36SAndroid Build Coastguard Worker 439*333d2b36SAndroid Build Coastguard Worker // If AllowMissingDependencies is enabled, the build will not have stopped when 440*333d2b36SAndroid Build Coastguard Worker // the dependency was added on a missing SourceFileProducer module, which will result in nonsensical 441*333d2b36SAndroid Build Coastguard Worker // "cmd: label ":..." has no files" errors later. Add a placeholder file to the local label. 442*333d2b36SAndroid Build Coastguard Worker // The command that uses this placeholder file will never be executed because the rule will be 443*333d2b36SAndroid Build Coastguard Worker // replaced with an android.Error rule reporting the missing dependencies. 444*333d2b36SAndroid Build Coastguard Worker ctx.AddMissingDependencies(missingDeps) 445*333d2b36SAndroid Build Coastguard Worker addLocationLabel(in, errorLocation{"***missing " + propName + " " + in + "***"}) 446*333d2b36SAndroid Build Coastguard Worker } else { 447*333d2b36SAndroid Build Coastguard Worker srcFiles = append(srcFiles, paths...) 448*333d2b36SAndroid Build Coastguard Worker addLocationLabel(in, inputLocation{paths}) 449*333d2b36SAndroid Build Coastguard Worker } 450*333d2b36SAndroid Build Coastguard Worker } 451*333d2b36SAndroid Build Coastguard Worker return srcFiles 452*333d2b36SAndroid Build Coastguard Worker } 453*333d2b36SAndroid Build Coastguard Worker srcs := g.properties.Srcs.GetOrDefault(ctx, nil) 454*333d2b36SAndroid Build Coastguard Worker srcFiles := addLabelsForInputs("srcs", srcs, g.properties.Exclude_srcs) 455*333d2b36SAndroid Build Coastguard Worker srcFiles = append(srcFiles, addLabelsForInputs("device_first_srcs", g.properties.Device_first_srcs.GetOrDefault(ctx, nil), nil)...) 456*333d2b36SAndroid Build Coastguard Worker srcFiles = append(srcFiles, addLabelsForInputs("device_common_srcs", g.properties.Device_common_srcs.GetOrDefault(ctx, nil), nil)...) 457*333d2b36SAndroid Build Coastguard Worker srcFiles = append(srcFiles, addLabelsForInputs("common_os_srcs", g.properties.Common_os_srcs.GetOrDefault(ctx, nil), nil)...) 458*333d2b36SAndroid Build Coastguard Worker android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()}) 459*333d2b36SAndroid Build Coastguard Worker 460*333d2b36SAndroid Build Coastguard Worker var copyFrom android.Paths 461*333d2b36SAndroid Build Coastguard Worker var outputFiles android.WritablePaths 462*333d2b36SAndroid Build Coastguard Worker var zipArgs strings.Builder 463*333d2b36SAndroid Build Coastguard Worker 464*333d2b36SAndroid Build Coastguard Worker cmd := g.properties.Cmd.GetOrDefault(ctx, "") 465*333d2b36SAndroid Build Coastguard Worker if g.CmdModifier != nil { 466*333d2b36SAndroid Build Coastguard Worker cmd = g.CmdModifier(ctx, cmd) 467*333d2b36SAndroid Build Coastguard Worker } 468*333d2b36SAndroid Build Coastguard Worker 469*333d2b36SAndroid Build Coastguard Worker var extraInputs android.Paths 470*333d2b36SAndroid Build Coastguard Worker // Generate tasks, either from genrule or gensrcs. 471*333d2b36SAndroid Build Coastguard Worker for i, task := range g.taskGenerator(ctx, cmd, srcFiles) { 472*333d2b36SAndroid Build Coastguard Worker if len(task.out) == 0 { 473*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("must have at least one output file") 474*333d2b36SAndroid Build Coastguard Worker return 475*333d2b36SAndroid Build Coastguard Worker } 476*333d2b36SAndroid Build Coastguard Worker 477*333d2b36SAndroid Build Coastguard Worker // Only handle extra inputs once as these currently are the same across all tasks 478*333d2b36SAndroid Build Coastguard Worker if i == 0 { 479*333d2b36SAndroid Build Coastguard Worker for name, values := range task.extraInputs { 480*333d2b36SAndroid Build Coastguard Worker extraInputs = append(extraInputs, addLabelsForInputs(name, values, []string{})...) 481*333d2b36SAndroid Build Coastguard Worker } 482*333d2b36SAndroid Build Coastguard Worker } 483*333d2b36SAndroid Build Coastguard Worker 484*333d2b36SAndroid Build Coastguard Worker // Pick a unique path outside the task.genDir for the sbox manifest textproto, 485*333d2b36SAndroid Build Coastguard Worker // a unique rule name, and the user-visible description. 486*333d2b36SAndroid Build Coastguard Worker var rule *android.RuleBuilder 487*333d2b36SAndroid Build Coastguard Worker desc := "generate" 488*333d2b36SAndroid Build Coastguard Worker name := "generator" 489*333d2b36SAndroid Build Coastguard Worker if task.useNsjail { 490*333d2b36SAndroid Build Coastguard Worker rule = android.NewRuleBuilder(pctx, ctx).Nsjail(task.genDir, android.PathForModuleOut(ctx, "nsjail_build_sandbox")) 491*333d2b36SAndroid Build Coastguard Worker if task.keepGendir { 492*333d2b36SAndroid Build Coastguard Worker rule.NsjailKeepGendir() 493*333d2b36SAndroid Build Coastguard Worker } 494*333d2b36SAndroid Build Coastguard Worker } else { 495*333d2b36SAndroid Build Coastguard Worker manifestName := "genrule.sbox.textproto" 496*333d2b36SAndroid Build Coastguard Worker if task.shards > 0 { 497*333d2b36SAndroid Build Coastguard Worker manifestName = "genrule_" + strconv.Itoa(task.shard) + ".sbox.textproto" 498*333d2b36SAndroid Build Coastguard Worker desc += " " + strconv.Itoa(task.shard) 499*333d2b36SAndroid Build Coastguard Worker name += strconv.Itoa(task.shard) 500*333d2b36SAndroid Build Coastguard Worker } else if len(task.out) == 1 { 501*333d2b36SAndroid Build Coastguard Worker desc += " " + task.out[0].Base() 502*333d2b36SAndroid Build Coastguard Worker } 503*333d2b36SAndroid Build Coastguard Worker 504*333d2b36SAndroid Build Coastguard Worker manifestPath := android.PathForModuleOut(ctx, manifestName) 505*333d2b36SAndroid Build Coastguard Worker 506*333d2b36SAndroid Build Coastguard Worker // Use a RuleBuilder to create a rule that runs the command inside an sbox sandbox. 507*333d2b36SAndroid Build Coastguard Worker rule = getSandboxedRuleBuilder(ctx, android.NewRuleBuilder(pctx, ctx).Sbox(task.genDir, manifestPath)) 508*333d2b36SAndroid Build Coastguard Worker } 509*333d2b36SAndroid Build Coastguard Worker if Bool(g.properties.Write_if_changed) { 510*333d2b36SAndroid Build Coastguard Worker rule.Restat() 511*333d2b36SAndroid Build Coastguard Worker } 512*333d2b36SAndroid Build Coastguard Worker cmd := rule.Command() 513*333d2b36SAndroid Build Coastguard Worker 514*333d2b36SAndroid Build Coastguard Worker for _, out := range task.out { 515*333d2b36SAndroid Build Coastguard Worker addLocationLabel(out.Rel(), outputLocation{out}) 516*333d2b36SAndroid Build Coastguard Worker } 517*333d2b36SAndroid Build Coastguard Worker 518*333d2b36SAndroid Build Coastguard Worker rawCommand, err := android.Expand(task.cmd, func(name string) (string, error) { 519*333d2b36SAndroid Build Coastguard Worker // report the error directly without returning an error to android.Expand to catch multiple errors in a 520*333d2b36SAndroid Build Coastguard Worker // single run 521*333d2b36SAndroid Build Coastguard Worker reportError := func(fmt string, args ...interface{}) (string, error) { 522*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("cmd", fmt, args...) 523*333d2b36SAndroid Build Coastguard Worker return "SOONG_ERROR", nil 524*333d2b36SAndroid Build Coastguard Worker } 525*333d2b36SAndroid Build Coastguard Worker 526*333d2b36SAndroid Build Coastguard Worker // Apply shell escape to each cases to prevent source file paths containing $ from being evaluated in shell 527*333d2b36SAndroid Build Coastguard Worker switch name { 528*333d2b36SAndroid Build Coastguard Worker case "location": 529*333d2b36SAndroid Build Coastguard Worker if len(g.properties.Tools) == 0 && len(g.properties.Tool_files) == 0 { 530*333d2b36SAndroid Build Coastguard Worker return reportError("at least one `tools` or `tool_files` is required if $(location) is used") 531*333d2b36SAndroid Build Coastguard Worker } 532*333d2b36SAndroid Build Coastguard Worker loc := locationLabels[firstLabel] 533*333d2b36SAndroid Build Coastguard Worker paths := loc.Paths(cmd) 534*333d2b36SAndroid Build Coastguard Worker if len(paths) == 0 { 535*333d2b36SAndroid Build Coastguard Worker return reportError("default label %q has no files", firstLabel) 536*333d2b36SAndroid Build Coastguard Worker } else if len(paths) > 1 { 537*333d2b36SAndroid Build Coastguard Worker return reportError("default label %q has multiple files, use $(locations %s) to reference it", 538*333d2b36SAndroid Build Coastguard Worker firstLabel, firstLabel) 539*333d2b36SAndroid Build Coastguard Worker } 540*333d2b36SAndroid Build Coastguard Worker return proptools.ShellEscape(paths[0]), nil 541*333d2b36SAndroid Build Coastguard Worker case "in": 542*333d2b36SAndroid Build Coastguard Worker return strings.Join(proptools.ShellEscapeList(cmd.PathsForInputs(srcFiles)), " "), nil 543*333d2b36SAndroid Build Coastguard Worker case "out": 544*333d2b36SAndroid Build Coastguard Worker var sandboxOuts []string 545*333d2b36SAndroid Build Coastguard Worker for _, out := range task.out { 546*333d2b36SAndroid Build Coastguard Worker sandboxOuts = append(sandboxOuts, cmd.PathForOutput(out)) 547*333d2b36SAndroid Build Coastguard Worker } 548*333d2b36SAndroid Build Coastguard Worker return strings.Join(proptools.ShellEscapeList(sandboxOuts), " "), nil 549*333d2b36SAndroid Build Coastguard Worker case "genDir": 550*333d2b36SAndroid Build Coastguard Worker return proptools.ShellEscape(cmd.PathForOutput(task.genDir)), nil 551*333d2b36SAndroid Build Coastguard Worker case "build_number_file": 552*333d2b36SAndroid Build Coastguard Worker if !proptools.Bool(g.properties.Uses_order_only_build_number_file) { 553*333d2b36SAndroid Build Coastguard Worker return reportError("to use the $(build_number_file) label, you must set uses_order_only_build_number_file: true") 554*333d2b36SAndroid Build Coastguard Worker } 555*333d2b36SAndroid Build Coastguard Worker return proptools.ShellEscape(cmd.PathForInput(ctx.Config().BuildNumberFile(ctx))), nil 556*333d2b36SAndroid Build Coastguard Worker default: 557*333d2b36SAndroid Build Coastguard Worker if strings.HasPrefix(name, "location ") { 558*333d2b36SAndroid Build Coastguard Worker label := strings.TrimSpace(strings.TrimPrefix(name, "location ")) 559*333d2b36SAndroid Build Coastguard Worker if loc, ok := locationLabels[label]; ok { 560*333d2b36SAndroid Build Coastguard Worker paths := loc.Paths(cmd) 561*333d2b36SAndroid Build Coastguard Worker if len(paths) == 0 { 562*333d2b36SAndroid Build Coastguard Worker return reportError("label %q has no files", label) 563*333d2b36SAndroid Build Coastguard Worker } else if len(paths) > 1 { 564*333d2b36SAndroid Build Coastguard Worker return reportError("label %q has multiple files, use $(locations %s) to reference it", 565*333d2b36SAndroid Build Coastguard Worker label, label) 566*333d2b36SAndroid Build Coastguard Worker } 567*333d2b36SAndroid Build Coastguard Worker return proptools.ShellEscape(paths[0]), nil 568*333d2b36SAndroid Build Coastguard Worker } else { 569*333d2b36SAndroid Build Coastguard Worker return reportError("unknown location label %q is not in srcs, out, tools or tool_files.", label) 570*333d2b36SAndroid Build Coastguard Worker } 571*333d2b36SAndroid Build Coastguard Worker } else if strings.HasPrefix(name, "locations ") { 572*333d2b36SAndroid Build Coastguard Worker label := strings.TrimSpace(strings.TrimPrefix(name, "locations ")) 573*333d2b36SAndroid Build Coastguard Worker if loc, ok := locationLabels[label]; ok { 574*333d2b36SAndroid Build Coastguard Worker paths := loc.Paths(cmd) 575*333d2b36SAndroid Build Coastguard Worker if len(paths) == 0 { 576*333d2b36SAndroid Build Coastguard Worker return reportError("label %q has no files", label) 577*333d2b36SAndroid Build Coastguard Worker } 578*333d2b36SAndroid Build Coastguard Worker return strings.Join(proptools.ShellEscapeList(paths), " "), nil 579*333d2b36SAndroid Build Coastguard Worker } else { 580*333d2b36SAndroid Build Coastguard Worker return reportError("unknown locations label %q is not in srcs, out, tools or tool_files.", label) 581*333d2b36SAndroid Build Coastguard Worker } 582*333d2b36SAndroid Build Coastguard Worker } else { 583*333d2b36SAndroid Build Coastguard Worker return reportError("unknown variable '$(%s)'", name) 584*333d2b36SAndroid Build Coastguard Worker } 585*333d2b36SAndroid Build Coastguard Worker } 586*333d2b36SAndroid Build Coastguard Worker }) 587*333d2b36SAndroid Build Coastguard Worker 588*333d2b36SAndroid Build Coastguard Worker if err != nil { 589*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("cmd", "%s", err.Error()) 590*333d2b36SAndroid Build Coastguard Worker return 591*333d2b36SAndroid Build Coastguard Worker } 592*333d2b36SAndroid Build Coastguard Worker 593*333d2b36SAndroid Build Coastguard Worker g.rawCommands = append(g.rawCommands, rawCommand) 594*333d2b36SAndroid Build Coastguard Worker 595*333d2b36SAndroid Build Coastguard Worker cmd.Text(rawCommand) 596*333d2b36SAndroid Build Coastguard Worker cmd.Implicits(srcFiles) // need to be able to reference other srcs 597*333d2b36SAndroid Build Coastguard Worker cmd.Implicits(extraInputs) 598*333d2b36SAndroid Build Coastguard Worker cmd.ImplicitOutputs(task.out) 599*333d2b36SAndroid Build Coastguard Worker cmd.Implicits(task.in) 600*333d2b36SAndroid Build Coastguard Worker cmd.ImplicitTools(tools) 601*333d2b36SAndroid Build Coastguard Worker cmd.ImplicitPackagedTools(packagedTools) 602*333d2b36SAndroid Build Coastguard Worker if proptools.Bool(g.properties.Uses_order_only_build_number_file) { 603*333d2b36SAndroid Build Coastguard Worker if !isModuleInBuildNumberAllowlist(ctx) { 604*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("Only allowlisted modules may use uses_order_only_build_number_file: true") 605*333d2b36SAndroid Build Coastguard Worker } 606*333d2b36SAndroid Build Coastguard Worker cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx)) 607*333d2b36SAndroid Build Coastguard Worker } 608*333d2b36SAndroid Build Coastguard Worker 609*333d2b36SAndroid Build Coastguard Worker if task.useNsjail { 610*333d2b36SAndroid Build Coastguard Worker for _, input := range task.dirSrcs { 611*333d2b36SAndroid Build Coastguard Worker cmd.ImplicitDirectory(input) 612*333d2b36SAndroid Build Coastguard Worker // TODO(b/375551969): remove glob 613*333d2b36SAndroid Build Coastguard Worker if paths, err := ctx.GlobWithDeps(filepath.Join(input.String(), "**/*"), nil); err == nil { 614*333d2b36SAndroid Build Coastguard Worker rule.NsjailImplicits(android.PathsForSource(ctx, paths)) 615*333d2b36SAndroid Build Coastguard Worker } else { 616*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("dir_srcs", "can't glob %q", input.String()) 617*333d2b36SAndroid Build Coastguard Worker } 618*333d2b36SAndroid Build Coastguard Worker } 619*333d2b36SAndroid Build Coastguard Worker } 620*333d2b36SAndroid Build Coastguard Worker 621*333d2b36SAndroid Build Coastguard Worker // Create the rule to run the genrule command inside sbox. 622*333d2b36SAndroid Build Coastguard Worker rule.Build(name, desc) 623*333d2b36SAndroid Build Coastguard Worker 624*333d2b36SAndroid Build Coastguard Worker if len(task.copyTo) > 0 { 625*333d2b36SAndroid Build Coastguard Worker // If copyTo is set, multiple shards need to be copied into a single directory. 626*333d2b36SAndroid Build Coastguard Worker // task.out contains the per-shard paths, and copyTo contains the corresponding 627*333d2b36SAndroid Build Coastguard Worker // final path. The files need to be copied into the final directory by a 628*333d2b36SAndroid Build Coastguard Worker // single rule so it can remove the directory before it starts to ensure no 629*333d2b36SAndroid Build Coastguard Worker // old files remain. zipsync already does this, so build up zipArgs that 630*333d2b36SAndroid Build Coastguard Worker // zip all the per-shard directories into a single zip. 631*333d2b36SAndroid Build Coastguard Worker outputFiles = append(outputFiles, task.copyTo...) 632*333d2b36SAndroid Build Coastguard Worker copyFrom = append(copyFrom, task.out.Paths()...) 633*333d2b36SAndroid Build Coastguard Worker zipArgs.WriteString(" -C " + task.genDir.String()) 634*333d2b36SAndroid Build Coastguard Worker zipArgs.WriteString(android.JoinWithPrefix(task.out.Strings(), " -f ")) 635*333d2b36SAndroid Build Coastguard Worker } else { 636*333d2b36SAndroid Build Coastguard Worker outputFiles = append(outputFiles, task.out...) 637*333d2b36SAndroid Build Coastguard Worker } 638*333d2b36SAndroid Build Coastguard Worker } 639*333d2b36SAndroid Build Coastguard Worker 640*333d2b36SAndroid Build Coastguard Worker if len(copyFrom) > 0 { 641*333d2b36SAndroid Build Coastguard Worker // Create a rule that zips all the per-shard directories into a single zip and then 642*333d2b36SAndroid Build Coastguard Worker // uses zipsync to unzip it into the final directory. 643*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 644*333d2b36SAndroid Build Coastguard Worker Rule: gensrcsMerge, 645*333d2b36SAndroid Build Coastguard Worker Implicits: copyFrom, 646*333d2b36SAndroid Build Coastguard Worker Outputs: outputFiles, 647*333d2b36SAndroid Build Coastguard Worker Description: "merge shards", 648*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 649*333d2b36SAndroid Build Coastguard Worker "zipArgs": zipArgs.String(), 650*333d2b36SAndroid Build Coastguard Worker "tmpZip": android.PathForModuleGen(ctx, g.subDir+".zip").String(), 651*333d2b36SAndroid Build Coastguard Worker "genDir": android.PathForModuleGen(ctx, g.subDir).String(), 652*333d2b36SAndroid Build Coastguard Worker }, 653*333d2b36SAndroid Build Coastguard Worker }) 654*333d2b36SAndroid Build Coastguard Worker } 655*333d2b36SAndroid Build Coastguard Worker 656*333d2b36SAndroid Build Coastguard Worker g.outputFiles = outputFiles.Paths() 657*333d2b36SAndroid Build Coastguard Worker} 658*333d2b36SAndroid Build Coastguard Worker 659*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { 660*333d2b36SAndroid Build Coastguard Worker g.generateCommonBuildActions(ctx) 661*333d2b36SAndroid Build Coastguard Worker 662*333d2b36SAndroid Build Coastguard Worker // For <= 6 outputs, just embed those directly in the users. Right now, that covers >90% of 663*333d2b36SAndroid Build Coastguard Worker // the genrules on AOSP. That will make things simpler to look at the graph in the common 664*333d2b36SAndroid Build Coastguard Worker // case. For larger sets of outputs, inject a phony target in between to limit ninja file 665*333d2b36SAndroid Build Coastguard Worker // growth. 666*333d2b36SAndroid Build Coastguard Worker if len(g.outputFiles) <= 6 { 667*333d2b36SAndroid Build Coastguard Worker g.outputDeps = g.outputFiles 668*333d2b36SAndroid Build Coastguard Worker } else { 669*333d2b36SAndroid Build Coastguard Worker phonyFile := android.PathForModuleGen(ctx, "genrule-phony") 670*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 671*333d2b36SAndroid Build Coastguard Worker Rule: blueprint.Phony, 672*333d2b36SAndroid Build Coastguard Worker Output: phonyFile, 673*333d2b36SAndroid Build Coastguard Worker Inputs: g.outputFiles, 674*333d2b36SAndroid Build Coastguard Worker }) 675*333d2b36SAndroid Build Coastguard Worker g.outputDeps = android.Paths{phonyFile} 676*333d2b36SAndroid Build Coastguard Worker } 677*333d2b36SAndroid Build Coastguard Worker 678*333d2b36SAndroid Build Coastguard Worker g.setOutputFiles(ctx) 679*333d2b36SAndroid Build Coastguard Worker 680*333d2b36SAndroid Build Coastguard Worker if ctx.Os() == android.Windows { 681*333d2b36SAndroid Build Coastguard Worker // Make doesn't support windows: 682*333d2b36SAndroid Build Coastguard Worker // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/module_arch_supported.mk;l=66;drc=f264690860bb6ee7762784d6b7201aae057ba6f2 683*333d2b36SAndroid Build Coastguard Worker g.HideFromMake() 684*333d2b36SAndroid Build Coastguard Worker } 685*333d2b36SAndroid Build Coastguard Worker} 686*333d2b36SAndroid Build Coastguard Worker 687*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) setOutputFiles(ctx android.ModuleContext) { 688*333d2b36SAndroid Build Coastguard Worker if len(g.outputFiles) == 0 { 689*333d2b36SAndroid Build Coastguard Worker return 690*333d2b36SAndroid Build Coastguard Worker } 691*333d2b36SAndroid Build Coastguard Worker ctx.SetOutputFiles(g.outputFiles, "") 692*333d2b36SAndroid Build Coastguard Worker // non-empty-string-tag should match one of the outputs 693*333d2b36SAndroid Build Coastguard Worker for _, files := range g.outputFiles { 694*333d2b36SAndroid Build Coastguard Worker ctx.SetOutputFiles(android.Paths{files}, files.Rel()) 695*333d2b36SAndroid Build Coastguard Worker } 696*333d2b36SAndroid Build Coastguard Worker} 697*333d2b36SAndroid Build Coastguard Worker 698*333d2b36SAndroid Build Coastguard Worker// Collect information for opening IDE project files in java/jdeps.go. 699*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { 700*333d2b36SAndroid Build Coastguard Worker dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...) 701*333d2b36SAndroid Build Coastguard Worker for _, src := range g.properties.Srcs.GetOrDefault(ctx, nil) { 702*333d2b36SAndroid Build Coastguard Worker if strings.HasPrefix(src, ":") { 703*333d2b36SAndroid Build Coastguard Worker src = strings.Trim(src, ":") 704*333d2b36SAndroid Build Coastguard Worker dpInfo.Deps = append(dpInfo.Deps, src) 705*333d2b36SAndroid Build Coastguard Worker } 706*333d2b36SAndroid Build Coastguard Worker } 707*333d2b36SAndroid Build Coastguard Worker} 708*333d2b36SAndroid Build Coastguard Worker 709*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) AndroidMk() android.AndroidMkData { 710*333d2b36SAndroid Build Coastguard Worker return android.AndroidMkData{ 711*333d2b36SAndroid Build Coastguard Worker Class: "ETC", 712*333d2b36SAndroid Build Coastguard Worker OutputFile: android.OptionalPathForPath(g.outputFiles[0]), 713*333d2b36SAndroid Build Coastguard Worker SubName: g.subName, 714*333d2b36SAndroid Build Coastguard Worker Extra: []android.AndroidMkExtraFunc{ 715*333d2b36SAndroid Build Coastguard Worker func(w io.Writer, outputFile android.Path) { 716*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true") 717*333d2b36SAndroid Build Coastguard Worker }, 718*333d2b36SAndroid Build Coastguard Worker }, 719*333d2b36SAndroid Build Coastguard Worker Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { 720*333d2b36SAndroid Build Coastguard Worker android.WriteAndroidMkData(w, data) 721*333d2b36SAndroid Build Coastguard Worker if data.SubName != "" { 722*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(w, ".PHONY:", name) 723*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(w, name, ":", name+g.subName) 724*333d2b36SAndroid Build Coastguard Worker } 725*333d2b36SAndroid Build Coastguard Worker }, 726*333d2b36SAndroid Build Coastguard Worker } 727*333d2b36SAndroid Build Coastguard Worker} 728*333d2b36SAndroid Build Coastguard Worker 729*333d2b36SAndroid Build Coastguard Workervar _ android.ApexModule = (*Module)(nil) 730*333d2b36SAndroid Build Coastguard Worker 731*333d2b36SAndroid Build Coastguard Worker// Implements android.ApexModule 732*333d2b36SAndroid Build Coastguard Workerfunc (g *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 733*333d2b36SAndroid Build Coastguard Worker sdkVersion android.ApiLevel) error { 734*333d2b36SAndroid Build Coastguard Worker // Because generated outputs are checked by client modules(e.g. cc_library, ...) 735*333d2b36SAndroid Build Coastguard Worker // we can safely ignore the check here. 736*333d2b36SAndroid Build Coastguard Worker return nil 737*333d2b36SAndroid Build Coastguard Worker} 738*333d2b36SAndroid Build Coastguard Worker 739*333d2b36SAndroid Build Coastguard Workerfunc generatorFactory(taskGenerator taskFunc, props ...interface{}) *Module { 740*333d2b36SAndroid Build Coastguard Worker module := &Module{ 741*333d2b36SAndroid Build Coastguard Worker taskGenerator: taskGenerator, 742*333d2b36SAndroid Build Coastguard Worker } 743*333d2b36SAndroid Build Coastguard Worker 744*333d2b36SAndroid Build Coastguard Worker module.AddProperties(props...) 745*333d2b36SAndroid Build Coastguard Worker module.AddProperties(&module.properties) 746*333d2b36SAndroid Build Coastguard Worker 747*333d2b36SAndroid Build Coastguard Worker module.ImageInterface = noopImageInterface{} 748*333d2b36SAndroid Build Coastguard Worker 749*333d2b36SAndroid Build Coastguard Worker return module 750*333d2b36SAndroid Build Coastguard Worker} 751*333d2b36SAndroid Build Coastguard Worker 752*333d2b36SAndroid Build Coastguard Workertype noopImageInterface struct{} 753*333d2b36SAndroid Build Coastguard Worker 754*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) ImageMutatorBegin(android.ImageInterfaceContext) {} 755*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) VendorVariantNeeded(android.ImageInterfaceContext) bool { return false } 756*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) ProductVariantNeeded(android.ImageInterfaceContext) bool { return false } 757*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) CoreVariantNeeded(android.ImageInterfaceContext) bool { return false } 758*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) RamdiskVariantNeeded(android.ImageInterfaceContext) bool { return false } 759*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) VendorRamdiskVariantNeeded(android.ImageInterfaceContext) bool { 760*333d2b36SAndroid Build Coastguard Worker return false 761*333d2b36SAndroid Build Coastguard Worker} 762*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) DebugRamdiskVariantNeeded(android.ImageInterfaceContext) bool { 763*333d2b36SAndroid Build Coastguard Worker return false 764*333d2b36SAndroid Build Coastguard Worker} 765*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) RecoveryVariantNeeded(android.ImageInterfaceContext) bool { return false } 766*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) ExtraImageVariations(ctx android.ImageInterfaceContext) []string { 767*333d2b36SAndroid Build Coastguard Worker return nil 768*333d2b36SAndroid Build Coastguard Worker} 769*333d2b36SAndroid Build Coastguard Workerfunc (x noopImageInterface) SetImageVariation(ctx android.ImageInterfaceContext, variation string) { 770*333d2b36SAndroid Build Coastguard Worker} 771*333d2b36SAndroid Build Coastguard Worker 772*333d2b36SAndroid Build Coastguard Workerfunc NewGenSrcs() *Module { 773*333d2b36SAndroid Build Coastguard Worker properties := &genSrcsProperties{} 774*333d2b36SAndroid Build Coastguard Worker 775*333d2b36SAndroid Build Coastguard Worker // finalSubDir is the name of the subdirectory that output files will be generated into. 776*333d2b36SAndroid Build Coastguard Worker // It is used so that per-shard directories can be placed alongside it an then finally 777*333d2b36SAndroid Build Coastguard Worker // merged into it. 778*333d2b36SAndroid Build Coastguard Worker const finalSubDir = "gensrcs" 779*333d2b36SAndroid Build Coastguard Worker 780*333d2b36SAndroid Build Coastguard Worker taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask { 781*333d2b36SAndroid Build Coastguard Worker shardSize := defaultShardSize 782*333d2b36SAndroid Build Coastguard Worker if s := properties.Shard_size; s != nil { 783*333d2b36SAndroid Build Coastguard Worker shardSize = int(*s) 784*333d2b36SAndroid Build Coastguard Worker } 785*333d2b36SAndroid Build Coastguard Worker 786*333d2b36SAndroid Build Coastguard Worker // gensrcs rules can easily hit command line limits by repeating the command for 787*333d2b36SAndroid Build Coastguard Worker // every input file. Shard the input files into groups. 788*333d2b36SAndroid Build Coastguard Worker shards := android.ShardPaths(srcFiles, shardSize) 789*333d2b36SAndroid Build Coastguard Worker var generateTasks []generateTask 790*333d2b36SAndroid Build Coastguard Worker 791*333d2b36SAndroid Build Coastguard Worker for i, shard := range shards { 792*333d2b36SAndroid Build Coastguard Worker var commands []string 793*333d2b36SAndroid Build Coastguard Worker var outFiles android.WritablePaths 794*333d2b36SAndroid Build Coastguard Worker var copyTo android.WritablePaths 795*333d2b36SAndroid Build Coastguard Worker 796*333d2b36SAndroid Build Coastguard Worker // When sharding is enabled (i.e. len(shards) > 1), the sbox rules for each 797*333d2b36SAndroid Build Coastguard Worker // shard will be write to their own directories and then be merged together 798*333d2b36SAndroid Build Coastguard Worker // into finalSubDir. If sharding is not enabled (i.e. len(shards) == 1), 799*333d2b36SAndroid Build Coastguard Worker // the sbox rule will write directly to finalSubDir. 800*333d2b36SAndroid Build Coastguard Worker genSubDir := finalSubDir 801*333d2b36SAndroid Build Coastguard Worker if len(shards) > 1 { 802*333d2b36SAndroid Build Coastguard Worker genSubDir = strconv.Itoa(i) 803*333d2b36SAndroid Build Coastguard Worker } 804*333d2b36SAndroid Build Coastguard Worker 805*333d2b36SAndroid Build Coastguard Worker genDir := android.PathForModuleGen(ctx, genSubDir) 806*333d2b36SAndroid Build Coastguard Worker // TODO(ccross): this RuleBuilder is a hack to be able to call 807*333d2b36SAndroid Build Coastguard Worker // rule.Command().PathForOutput. Replace this with passing the rule into the 808*333d2b36SAndroid Build Coastguard Worker // generator. 809*333d2b36SAndroid Build Coastguard Worker rule := getSandboxedRuleBuilder(ctx, android.NewRuleBuilder(pctx, ctx).Sbox(genDir, nil)) 810*333d2b36SAndroid Build Coastguard Worker 811*333d2b36SAndroid Build Coastguard Worker for _, in := range shard { 812*333d2b36SAndroid Build Coastguard Worker outFile := android.GenPathWithExtAndTrimExt(ctx, finalSubDir, in, String(properties.Output_extension), String(properties.Trim_extension)) 813*333d2b36SAndroid Build Coastguard Worker 814*333d2b36SAndroid Build Coastguard Worker // If sharding is enabled, then outFile is the path to the output file in 815*333d2b36SAndroid Build Coastguard Worker // the shard directory, and copyTo is the path to the output file in the 816*333d2b36SAndroid Build Coastguard Worker // final directory. 817*333d2b36SAndroid Build Coastguard Worker if len(shards) > 1 { 818*333d2b36SAndroid Build Coastguard Worker shardFile := android.GenPathWithExtAndTrimExt(ctx, genSubDir, in, String(properties.Output_extension), String(properties.Trim_extension)) 819*333d2b36SAndroid Build Coastguard Worker copyTo = append(copyTo, outFile) 820*333d2b36SAndroid Build Coastguard Worker outFile = shardFile 821*333d2b36SAndroid Build Coastguard Worker } 822*333d2b36SAndroid Build Coastguard Worker 823*333d2b36SAndroid Build Coastguard Worker outFiles = append(outFiles, outFile) 824*333d2b36SAndroid Build Coastguard Worker 825*333d2b36SAndroid Build Coastguard Worker // pre-expand the command line to replace $in and $out with references to 826*333d2b36SAndroid Build Coastguard Worker // a single input and output file. 827*333d2b36SAndroid Build Coastguard Worker command, err := android.Expand(rawCommand, func(name string) (string, error) { 828*333d2b36SAndroid Build Coastguard Worker switch name { 829*333d2b36SAndroid Build Coastguard Worker case "in": 830*333d2b36SAndroid Build Coastguard Worker return in.String(), nil 831*333d2b36SAndroid Build Coastguard Worker case "out": 832*333d2b36SAndroid Build Coastguard Worker return rule.Command().PathForOutput(outFile), nil 833*333d2b36SAndroid Build Coastguard Worker default: 834*333d2b36SAndroid Build Coastguard Worker return "$(" + name + ")", nil 835*333d2b36SAndroid Build Coastguard Worker } 836*333d2b36SAndroid Build Coastguard Worker }) 837*333d2b36SAndroid Build Coastguard Worker if err != nil { 838*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("cmd", err.Error()) 839*333d2b36SAndroid Build Coastguard Worker } 840*333d2b36SAndroid Build Coastguard Worker 841*333d2b36SAndroid Build Coastguard Worker // escape the command in case for example it contains '#', an odd number of '"', etc 842*333d2b36SAndroid Build Coastguard Worker command = fmt.Sprintf("bash -c %v", proptools.ShellEscape(command)) 843*333d2b36SAndroid Build Coastguard Worker commands = append(commands, command) 844*333d2b36SAndroid Build Coastguard Worker } 845*333d2b36SAndroid Build Coastguard Worker fullCommand := strings.Join(commands, " && ") 846*333d2b36SAndroid Build Coastguard Worker 847*333d2b36SAndroid Build Coastguard Worker generateTasks = append(generateTasks, generateTask{ 848*333d2b36SAndroid Build Coastguard Worker in: shard, 849*333d2b36SAndroid Build Coastguard Worker out: outFiles, 850*333d2b36SAndroid Build Coastguard Worker copyTo: copyTo, 851*333d2b36SAndroid Build Coastguard Worker genDir: genDir, 852*333d2b36SAndroid Build Coastguard Worker cmd: fullCommand, 853*333d2b36SAndroid Build Coastguard Worker shard: i, 854*333d2b36SAndroid Build Coastguard Worker shards: len(shards), 855*333d2b36SAndroid Build Coastguard Worker extraInputs: map[string][]string{ 856*333d2b36SAndroid Build Coastguard Worker "data": properties.Data, 857*333d2b36SAndroid Build Coastguard Worker }, 858*333d2b36SAndroid Build Coastguard Worker }) 859*333d2b36SAndroid Build Coastguard Worker } 860*333d2b36SAndroid Build Coastguard Worker 861*333d2b36SAndroid Build Coastguard Worker return generateTasks 862*333d2b36SAndroid Build Coastguard Worker } 863*333d2b36SAndroid Build Coastguard Worker 864*333d2b36SAndroid Build Coastguard Worker g := generatorFactory(taskGenerator, properties) 865*333d2b36SAndroid Build Coastguard Worker g.subDir = finalSubDir 866*333d2b36SAndroid Build Coastguard Worker return g 867*333d2b36SAndroid Build Coastguard Worker} 868*333d2b36SAndroid Build Coastguard Worker 869*333d2b36SAndroid Build Coastguard Workerfunc GenSrcsFactory() android.Module { 870*333d2b36SAndroid Build Coastguard Worker m := NewGenSrcs() 871*333d2b36SAndroid Build Coastguard Worker android.InitAndroidModule(m) 872*333d2b36SAndroid Build Coastguard Worker android.InitDefaultableModule(m) 873*333d2b36SAndroid Build Coastguard Worker return m 874*333d2b36SAndroid Build Coastguard Worker} 875*333d2b36SAndroid Build Coastguard Worker 876*333d2b36SAndroid Build Coastguard Workertype genSrcsProperties struct { 877*333d2b36SAndroid Build Coastguard Worker // extension that will be substituted for each output file 878*333d2b36SAndroid Build Coastguard Worker Output_extension *string 879*333d2b36SAndroid Build Coastguard Worker 880*333d2b36SAndroid Build Coastguard Worker // maximum number of files that will be passed on a single command line. 881*333d2b36SAndroid Build Coastguard Worker Shard_size *int64 882*333d2b36SAndroid Build Coastguard Worker 883*333d2b36SAndroid Build Coastguard Worker // Additional files needed for build that are not tooling related. 884*333d2b36SAndroid Build Coastguard Worker Data []string `android:"path"` 885*333d2b36SAndroid Build Coastguard Worker 886*333d2b36SAndroid Build Coastguard Worker // Trim the matched extension for each input file, and it should start with ".". 887*333d2b36SAndroid Build Coastguard Worker Trim_extension *string 888*333d2b36SAndroid Build Coastguard Worker} 889*333d2b36SAndroid Build Coastguard Worker 890*333d2b36SAndroid Build Coastguard Workerconst defaultShardSize = 50 891*333d2b36SAndroid Build Coastguard Worker 892*333d2b36SAndroid Build Coastguard Workerfunc NewGenRule() *Module { 893*333d2b36SAndroid Build Coastguard Worker properties := &genRuleProperties{} 894*333d2b36SAndroid Build Coastguard Worker 895*333d2b36SAndroid Build Coastguard Worker taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask { 896*333d2b36SAndroid Build Coastguard Worker useNsjail := Bool(properties.Use_nsjail) 897*333d2b36SAndroid Build Coastguard Worker 898*333d2b36SAndroid Build Coastguard Worker dirSrcs := android.DirectoryPathsForModuleSrc(ctx, properties.Dir_srcs) 899*333d2b36SAndroid Build Coastguard Worker if len(dirSrcs) > 0 && !useNsjail { 900*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("dir_srcs", "can't use dir_srcs if use_nsjail is false") 901*333d2b36SAndroid Build Coastguard Worker return nil 902*333d2b36SAndroid Build Coastguard Worker } 903*333d2b36SAndroid Build Coastguard Worker 904*333d2b36SAndroid Build Coastguard Worker keepGendir := Bool(properties.Keep_gendir) 905*333d2b36SAndroid Build Coastguard Worker if keepGendir && !useNsjail { 906*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("keep_gendir", "can't use keep_gendir if use_nsjail is false") 907*333d2b36SAndroid Build Coastguard Worker return nil 908*333d2b36SAndroid Build Coastguard Worker } 909*333d2b36SAndroid Build Coastguard Worker 910*333d2b36SAndroid Build Coastguard Worker outs := make(android.WritablePaths, len(properties.Out)) 911*333d2b36SAndroid Build Coastguard Worker for i, out := range properties.Out { 912*333d2b36SAndroid Build Coastguard Worker outs[i] = android.PathForModuleGen(ctx, out) 913*333d2b36SAndroid Build Coastguard Worker } 914*333d2b36SAndroid Build Coastguard Worker return []generateTask{{ 915*333d2b36SAndroid Build Coastguard Worker in: srcFiles, 916*333d2b36SAndroid Build Coastguard Worker out: outs, 917*333d2b36SAndroid Build Coastguard Worker genDir: android.PathForModuleGen(ctx), 918*333d2b36SAndroid Build Coastguard Worker cmd: rawCommand, 919*333d2b36SAndroid Build Coastguard Worker useNsjail: useNsjail, 920*333d2b36SAndroid Build Coastguard Worker dirSrcs: dirSrcs, 921*333d2b36SAndroid Build Coastguard Worker keepGendir: keepGendir, 922*333d2b36SAndroid Build Coastguard Worker }} 923*333d2b36SAndroid Build Coastguard Worker } 924*333d2b36SAndroid Build Coastguard Worker 925*333d2b36SAndroid Build Coastguard Worker return generatorFactory(taskGenerator, properties) 926*333d2b36SAndroid Build Coastguard Worker} 927*333d2b36SAndroid Build Coastguard Worker 928*333d2b36SAndroid Build Coastguard Workerfunc GenRuleFactory() android.Module { 929*333d2b36SAndroid Build Coastguard Worker m := NewGenRule() 930*333d2b36SAndroid Build Coastguard Worker android.InitAndroidModule(m) 931*333d2b36SAndroid Build Coastguard Worker android.InitDefaultableModule(m) 932*333d2b36SAndroid Build Coastguard Worker return m 933*333d2b36SAndroid Build Coastguard Worker} 934*333d2b36SAndroid Build Coastguard Worker 935*333d2b36SAndroid Build Coastguard Workertype genRuleProperties struct { 936*333d2b36SAndroid Build Coastguard Worker Use_nsjail *bool 937*333d2b36SAndroid Build Coastguard Worker 938*333d2b36SAndroid Build Coastguard Worker // List of input directories. Can be set only when use_nsjail is true. Currently, usage of 939*333d2b36SAndroid Build Coastguard Worker // dir_srcs is limited only to Trusty build. 940*333d2b36SAndroid Build Coastguard Worker Dir_srcs []string `android:"path"` 941*333d2b36SAndroid Build Coastguard Worker 942*333d2b36SAndroid Build Coastguard Worker // If set to true, $(genDir) is not truncated. Useful when this genrule can be incrementally 943*333d2b36SAndroid Build Coastguard Worker // built. Can be set only when use_nsjail is true. 944*333d2b36SAndroid Build Coastguard Worker Keep_gendir *bool 945*333d2b36SAndroid Build Coastguard Worker 946*333d2b36SAndroid Build Coastguard Worker // names of the output files that will be generated 947*333d2b36SAndroid Build Coastguard Worker Out []string `android:"arch_variant"` 948*333d2b36SAndroid Build Coastguard Worker} 949*333d2b36SAndroid Build Coastguard Worker 950*333d2b36SAndroid Build Coastguard Workervar Bool = proptools.Bool 951*333d2b36SAndroid Build Coastguard Workervar String = proptools.String 952*333d2b36SAndroid Build Coastguard Worker 953*333d2b36SAndroid Build Coastguard Worker// Defaults 954*333d2b36SAndroid Build Coastguard Workertype Defaults struct { 955*333d2b36SAndroid Build Coastguard Worker android.ModuleBase 956*333d2b36SAndroid Build Coastguard Worker android.DefaultsModuleBase 957*333d2b36SAndroid Build Coastguard Worker} 958*333d2b36SAndroid Build Coastguard Worker 959*333d2b36SAndroid Build Coastguard Workerfunc defaultsFactory() android.Module { 960*333d2b36SAndroid Build Coastguard Worker return DefaultsFactory() 961*333d2b36SAndroid Build Coastguard Worker} 962*333d2b36SAndroid Build Coastguard Worker 963*333d2b36SAndroid Build Coastguard Workerfunc DefaultsFactory(props ...interface{}) android.Module { 964*333d2b36SAndroid Build Coastguard Worker module := &Defaults{} 965*333d2b36SAndroid Build Coastguard Worker 966*333d2b36SAndroid Build Coastguard Worker module.AddProperties(props...) 967*333d2b36SAndroid Build Coastguard Worker module.AddProperties( 968*333d2b36SAndroid Build Coastguard Worker &generatorProperties{}, 969*333d2b36SAndroid Build Coastguard Worker &genRuleProperties{}, 970*333d2b36SAndroid Build Coastguard Worker ) 971*333d2b36SAndroid Build Coastguard Worker 972*333d2b36SAndroid Build Coastguard Worker android.InitDefaultsModule(module) 973*333d2b36SAndroid Build Coastguard Worker 974*333d2b36SAndroid Build Coastguard Worker return module 975*333d2b36SAndroid Build Coastguard Worker} 976*333d2b36SAndroid Build Coastguard Worker 977*333d2b36SAndroid Build Coastguard Workervar sandboxingAllowlistKey = android.NewOnceKey("genruleSandboxingAllowlistKey") 978*333d2b36SAndroid Build Coastguard Worker 979*333d2b36SAndroid Build Coastguard Workertype sandboxingAllowlistSets struct { 980*333d2b36SAndroid Build Coastguard Worker sandboxingDenyModuleSet map[string]bool 981*333d2b36SAndroid Build Coastguard Worker} 982*333d2b36SAndroid Build Coastguard Worker 983*333d2b36SAndroid Build Coastguard Workerfunc getSandboxingAllowlistSets(ctx android.PathContext) *sandboxingAllowlistSets { 984*333d2b36SAndroid Build Coastguard Worker return ctx.Config().Once(sandboxingAllowlistKey, func() interface{} { 985*333d2b36SAndroid Build Coastguard Worker sandboxingDenyModuleSet := map[string]bool{} 986*333d2b36SAndroid Build Coastguard Worker 987*333d2b36SAndroid Build Coastguard Worker android.AddToStringSet(sandboxingDenyModuleSet, SandboxingDenyModuleList) 988*333d2b36SAndroid Build Coastguard Worker return &sandboxingAllowlistSets{ 989*333d2b36SAndroid Build Coastguard Worker sandboxingDenyModuleSet: sandboxingDenyModuleSet, 990*333d2b36SAndroid Build Coastguard Worker } 991*333d2b36SAndroid Build Coastguard Worker }).(*sandboxingAllowlistSets) 992*333d2b36SAndroid Build Coastguard Worker} 993*333d2b36SAndroid Build Coastguard Worker 994*333d2b36SAndroid Build Coastguard Workerfunc getSandboxedRuleBuilder(ctx android.ModuleContext, r *android.RuleBuilder) *android.RuleBuilder { 995*333d2b36SAndroid Build Coastguard Worker if !ctx.DeviceConfig().GenruleSandboxing() { 996*333d2b36SAndroid Build Coastguard Worker return r.SandboxTools() 997*333d2b36SAndroid Build Coastguard Worker } 998*333d2b36SAndroid Build Coastguard Worker sandboxingAllowlistSets := getSandboxingAllowlistSets(ctx) 999*333d2b36SAndroid Build Coastguard Worker if sandboxingAllowlistSets.sandboxingDenyModuleSet[ctx.ModuleName()] { 1000*333d2b36SAndroid Build Coastguard Worker return r.SandboxTools() 1001*333d2b36SAndroid Build Coastguard Worker } 1002*333d2b36SAndroid Build Coastguard Worker return r.SandboxInputs() 1003*333d2b36SAndroid Build Coastguard Worker} 1004