1*6c119a46SAndroid Build Coastguard Worker// Copyright (C) 2017 The Android Open Source Project 2*6c119a46SAndroid Build Coastguard Worker// 3*6c119a46SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*6c119a46SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*6c119a46SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*6c119a46SAndroid Build Coastguard Worker// 7*6c119a46SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*6c119a46SAndroid Build Coastguard Worker// 9*6c119a46SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*6c119a46SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*6c119a46SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*6c119a46SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*6c119a46SAndroid Build Coastguard Worker// limitations under the License. 14*6c119a46SAndroid Build Coastguard Worker 15*6c119a46SAndroid Build Coastguard Worker/* 16*6c119a46SAndroid Build Coastguard WorkerPackage wayland_protocol defines an plugin module for the Soong build system, 17*6c119a46SAndroid Build Coastguard Workerwhich makes it easier to generate code from a list of Wayland protocol files. 18*6c119a46SAndroid Build Coastguard Worker 19*6c119a46SAndroid Build Coastguard WorkerThe primary build module is "wayland_protocol_codegen", which takes a list of 20*6c119a46SAndroid Build Coastguard Workerprotocol files, and runs a configurable code-generation tool to generate 21*6c119a46SAndroid Build Coastguard Workersource code for each one. There is also a "wayland_protocol_codegen_defaults" 22*6c119a46SAndroid Build Coastguard Workerfor setting common properties. 23*6c119a46SAndroid Build Coastguard Worker 24*6c119a46SAndroid Build Coastguard WorkerThis package is substantially similar to the base "android/soong/genrule" 25*6c119a46SAndroid Build Coastguard Workerpackage, which was originally used for inspiration for this one, and has 26*6c119a46SAndroid Build Coastguard Workerbeen recently restructured so that it can be kept in sync with a tool like 27*6c119a46SAndroid Build Coastguard Worker"vimdiff" to keep things in sync as needed. 28*6c119a46SAndroid Build Coastguard Worker 29*6c119a46SAndroid Build Coastguard WorkerNotable differences: 30*6c119a46SAndroid Build Coastguard Worker 31*6c119a46SAndroid Build Coastguard Worker - This package implements a more powerful template mechanism for specifying 32*6c119a46SAndroid Build Coastguard Worker what output path/filename should be used for each source filename. The 33*6c119a46SAndroid Build Coastguard Worker genrule package only allows the extension on each source filename to be 34*6c119a46SAndroid Build Coastguard Worker replaced. 35*6c119a46SAndroid Build Coastguard Worker 36*6c119a46SAndroid Build Coastguard Worker - This package drops support for depfiles, after observing comments that 37*6c119a46SAndroid Build Coastguard Worker they are problematic in the genrule package sources. 38*6c119a46SAndroid Build Coastguard Worker 39*6c119a46SAndroid Build Coastguard Worker - This package drops "Extra" and "CmdModifier" from the public Module 40*6c119a46SAndroid Build Coastguard Worker structure, as this module is not expected to be extended. 41*6c119a46SAndroid Build Coastguard Worker 42*6c119a46SAndroid Build Coastguard Worker - This package drops "rule" from the public Module structure, as it was 43*6c119a46SAndroid Build Coastguard Worker unused but present in genrule. 44*6c119a46SAndroid Build Coastguard Worker 45*6c119a46SAndroid Build Coastguard Worker# Usage 46*6c119a46SAndroid Build Coastguard Worker 47*6c119a46SAndroid Build Coastguard Worker wayland_protocol_codegen { 48*6c119a46SAndroid Build Coastguard Worker // A standard target name. 49*6c119a46SAndroid Build Coastguard Worker name: "wayland_extension_protocol_sources", 50*6c119a46SAndroid Build Coastguard Worker 51*6c119a46SAndroid Build Coastguard Worker // A simple template for generating output filenames. 52*6c119a46SAndroid Build Coastguard Worker output: "$(in).c" 53*6c119a46SAndroid Build Coastguard Worker 54*6c119a46SAndroid Build Coastguard Worker // The command line template. See "Cmd". 55*6c119a46SAndroid Build Coastguard Worker cmd: "$(location wayland_scanner) code < $(in) > $(out)", 56*6c119a46SAndroid Build Coastguard Worker 57*6c119a46SAndroid Build Coastguard Worker // Protocol source files for the expansion. 58*6c119a46SAndroid Build Coastguard Worker srcs: [":wayland_extension_protocols"], 59*6c119a46SAndroid Build Coastguard Worker 60*6c119a46SAndroid Build Coastguard Worker // Any buildable binaries to use as tools 61*6c119a46SAndroid Build Coastguard Worker tools: ["wayland_scanner"], 62*6c119a46SAndroid Build Coastguard Worker 63*6c119a46SAndroid Build Coastguard Worker // Any source files to be used (scripts, template files) 64*6c119a46SAndroid Build Coastguard Worker tools_files: [], 65*6c119a46SAndroid Build Coastguard Worker } 66*6c119a46SAndroid Build Coastguard Worker*/ 67*6c119a46SAndroid Build Coastguard Workerpackage soong_wayland_protocol_codegen 68*6c119a46SAndroid Build Coastguard Worker 69*6c119a46SAndroid Build Coastguard Workerimport ( 70*6c119a46SAndroid Build Coastguard Worker "fmt" 71*6c119a46SAndroid Build Coastguard Worker "strconv" 72*6c119a46SAndroid Build Coastguard Worker "strings" 73*6c119a46SAndroid Build Coastguard Worker 74*6c119a46SAndroid Build Coastguard Worker "github.com/google/blueprint" 75*6c119a46SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 76*6c119a46SAndroid Build Coastguard Worker 77*6c119a46SAndroid Build Coastguard Worker "android/soong/android" 78*6c119a46SAndroid Build Coastguard Worker "android/soong/genrule" 79*6c119a46SAndroid Build Coastguard Worker) 80*6c119a46SAndroid Build Coastguard Worker 81*6c119a46SAndroid Build Coastguard Workerfunc init() { 82*6c119a46SAndroid Build Coastguard Worker registerCodeGenBuildComponents(android.InitRegistrationContext) 83*6c119a46SAndroid Build Coastguard Worker} 84*6c119a46SAndroid Build Coastguard Worker 85*6c119a46SAndroid Build Coastguard Workerfunc registerCodeGenBuildComponents(ctx android.RegistrationContext) { 86*6c119a46SAndroid Build Coastguard Worker ctx.RegisterModuleType("wayland_protocol_codegen_defaults", defaultsFactory) 87*6c119a46SAndroid Build Coastguard Worker 88*6c119a46SAndroid Build Coastguard Worker ctx.RegisterModuleType("wayland_protocol_codegen", codegenFactory) 89*6c119a46SAndroid Build Coastguard Worker 90*6c119a46SAndroid Build Coastguard Worker ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { 91*6c119a46SAndroid Build Coastguard Worker ctx.BottomUp("wayland_protocol_codegen_tool_deps", toolDepsMutator) 92*6c119a46SAndroid Build Coastguard Worker }) 93*6c119a46SAndroid Build Coastguard Worker} 94*6c119a46SAndroid Build Coastguard Worker 95*6c119a46SAndroid Build Coastguard Workervar ( 96*6c119a46SAndroid Build Coastguard Worker pctx = android.NewPackageContext("android/soong/external/wayland_protocol_codegen") 97*6c119a46SAndroid Build Coastguard Worker 98*6c119a46SAndroid Build Coastguard Worker // Used by wayland_protocol_codegen when there is more than 1 shard to merge the outputs 99*6c119a46SAndroid Build Coastguard Worker // of each shard into a zip file. 100*6c119a46SAndroid Build Coastguard Worker gensrcsMerge = pctx.AndroidStaticRule("wayland_protocol_codegenMerge", blueprint.RuleParams{ 101*6c119a46SAndroid Build Coastguard Worker Command: "${soongZip} -o ${tmpZip} @${tmpZip}.rsp && ${zipSync} -d ${genDir} ${tmpZip}", 102*6c119a46SAndroid Build Coastguard Worker CommandDeps: []string{"${soongZip}", "${zipSync}"}, 103*6c119a46SAndroid Build Coastguard Worker Rspfile: "${tmpZip}.rsp", 104*6c119a46SAndroid Build Coastguard Worker RspfileContent: "${zipArgs}", 105*6c119a46SAndroid Build Coastguard Worker }, "tmpZip", "genDir", "zipArgs") 106*6c119a46SAndroid Build Coastguard Worker) 107*6c119a46SAndroid Build Coastguard Worker 108*6c119a46SAndroid Build Coastguard Workerfunc init() { 109*6c119a46SAndroid Build Coastguard Worker pctx.Import("android/soong/android") 110*6c119a46SAndroid Build Coastguard Worker 111*6c119a46SAndroid Build Coastguard Worker pctx.HostBinToolVariable("soongZip", "soong_zip") 112*6c119a46SAndroid Build Coastguard Worker pctx.HostBinToolVariable("zipSync", "zipsync") 113*6c119a46SAndroid Build Coastguard Worker} 114*6c119a46SAndroid Build Coastguard Worker 115*6c119a46SAndroid Build Coastguard Workertype hostToolDependencyTag struct { 116*6c119a46SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 117*6c119a46SAndroid Build Coastguard Worker android.LicenseAnnotationToolchainDependencyTag 118*6c119a46SAndroid Build Coastguard Worker label string 119*6c119a46SAndroid Build Coastguard Worker} 120*6c119a46SAndroid Build Coastguard Worker 121*6c119a46SAndroid Build Coastguard Workerfunc (t hostToolDependencyTag) AllowDisabledModuleDependency(target android.Module) bool { 122*6c119a46SAndroid Build Coastguard Worker // Allow depending on a disabled module if it's replaced by a prebuilt 123*6c119a46SAndroid Build Coastguard Worker // counterpart. We get the prebuilt through android.PrebuiltGetPreferred in 124*6c119a46SAndroid Build Coastguard Worker // GenerateAndroidBuildActions. 125*6c119a46SAndroid Build Coastguard Worker return target.IsReplacedByPrebuilt() 126*6c119a46SAndroid Build Coastguard Worker} 127*6c119a46SAndroid Build Coastguard Worker 128*6c119a46SAndroid Build Coastguard Workerfunc (t hostToolDependencyTag) AllowDisabledModuleDependencyProxy( 129*6c119a46SAndroid Build Coastguard Worker ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool { 130*6c119a46SAndroid Build Coastguard Worker return android.OtherModuleProviderOrDefault( 131*6c119a46SAndroid Build Coastguard Worker ctx, target, android.CommonModuleInfoKey).ReplacedByPrebuilt 132*6c119a46SAndroid Build Coastguard Worker} 133*6c119a46SAndroid Build Coastguard Worker 134*6c119a46SAndroid Build Coastguard Workervar _ android.AllowDisabledModuleDependency = (*hostToolDependencyTag)(nil) 135*6c119a46SAndroid Build Coastguard Worker 136*6c119a46SAndroid Build Coastguard Workertype generatorProperties struct { 137*6c119a46SAndroid Build Coastguard Worker // The command to run on one or more input files. Cmd supports 138*6c119a46SAndroid Build Coastguard Worker // substitution of a few variables (the actual substitution is implemented 139*6c119a46SAndroid Build Coastguard Worker // in GenerateAndroidBuildActions below) 140*6c119a46SAndroid Build Coastguard Worker // 141*6c119a46SAndroid Build Coastguard Worker // Available variables for substitution: 142*6c119a46SAndroid Build Coastguard Worker // 143*6c119a46SAndroid Build Coastguard Worker // - $(location) 144*6c119a46SAndroid Build Coastguard Worker // the path to the first entry in tools or tool_files 145*6c119a46SAndroid Build Coastguard Worker // - $(location <label>) 146*6c119a46SAndroid Build Coastguard Worker // the path to the tool, tool_file, input or output with name <label>. Use 147*6c119a46SAndroid Build Coastguard Worker // $(location) if <label> refers to a rule that outputs exactly one file. 148*6c119a46SAndroid Build Coastguard Worker // - $(locations <label>) 149*6c119a46SAndroid Build Coastguard Worker // the paths to the tools, tool_files, inputs or outputs with name 150*6c119a46SAndroid Build Coastguard Worker // <label>. Use $(locations) if <label> refers to a rule that outputs two 151*6c119a46SAndroid Build Coastguard Worker // or more files. 152*6c119a46SAndroid Build Coastguard Worker // - $(in) 153*6c119a46SAndroid Build Coastguard Worker // one or more input files 154*6c119a46SAndroid Build Coastguard Worker // - $(out) 155*6c119a46SAndroid Build Coastguard Worker // a single output file 156*6c119a46SAndroid Build Coastguard Worker // - $(genDir) 157*6c119a46SAndroid Build Coastguard Worker // the sandbox directory for this tool; contains $(out) 158*6c119a46SAndroid Build Coastguard Worker // - $$ 159*6c119a46SAndroid Build Coastguard Worker // a literal '$' 160*6c119a46SAndroid Build Coastguard Worker // 161*6c119a46SAndroid Build Coastguard Worker // All files used must be declared as inputs (to ensure proper up-to-date 162*6c119a46SAndroid Build Coastguard Worker // checks). Use "$(in)" directly in Cmd to ensure that all inputs used are 163*6c119a46SAndroid Build Coastguard Worker // declared. 164*6c119a46SAndroid Build Coastguard Worker Cmd *string 165*6c119a46SAndroid Build Coastguard Worker 166*6c119a46SAndroid Build Coastguard Worker // name of the modules (if any) that produces the host executable. Leave 167*6c119a46SAndroid Build Coastguard Worker // empty for prebuilts or scripts that do not need a module to build them. 168*6c119a46SAndroid Build Coastguard Worker Tools []string 169*6c119a46SAndroid Build Coastguard Worker 170*6c119a46SAndroid Build Coastguard Worker // Local source files that are used as scripts or other input files needed 171*6c119a46SAndroid Build Coastguard Worker // by a tool. 172*6c119a46SAndroid Build Coastguard Worker Tool_files []string `android:"path"` 173*6c119a46SAndroid Build Coastguard Worker 174*6c119a46SAndroid Build Coastguard Worker // List of directories to export generated headers from. 175*6c119a46SAndroid Build Coastguard Worker Export_include_dirs []string 176*6c119a46SAndroid Build Coastguard Worker 177*6c119a46SAndroid Build Coastguard Worker // List of input files. 178*6c119a46SAndroid Build Coastguard Worker Srcs []string `android:"path,arch_variant"` 179*6c119a46SAndroid Build Coastguard Worker 180*6c119a46SAndroid Build Coastguard Worker // Input files to exclude. 181*6c119a46SAndroid Build Coastguard Worker Exclude_srcs []string `android:"path,arch_variant"` 182*6c119a46SAndroid Build Coastguard Worker} 183*6c119a46SAndroid Build Coastguard Worker 184*6c119a46SAndroid Build Coastguard Workertype Module struct { 185*6c119a46SAndroid Build Coastguard Worker android.ModuleBase 186*6c119a46SAndroid Build Coastguard Worker android.DefaultableModuleBase 187*6c119a46SAndroid Build Coastguard Worker android.ApexModuleBase 188*6c119a46SAndroid Build Coastguard Worker 189*6c119a46SAndroid Build Coastguard Worker android.ImageInterface 190*6c119a46SAndroid Build Coastguard Worker 191*6c119a46SAndroid Build Coastguard Worker properties generatorProperties 192*6c119a46SAndroid Build Coastguard Worker 193*6c119a46SAndroid Build Coastguard Worker taskGenerator taskFunc 194*6c119a46SAndroid Build Coastguard Worker 195*6c119a46SAndroid Build Coastguard Worker rawCommands []string 196*6c119a46SAndroid Build Coastguard Worker 197*6c119a46SAndroid Build Coastguard Worker exportedIncludeDirs android.Paths 198*6c119a46SAndroid Build Coastguard Worker 199*6c119a46SAndroid Build Coastguard Worker outputFiles android.Paths 200*6c119a46SAndroid Build Coastguard Worker outputDeps android.Paths 201*6c119a46SAndroid Build Coastguard Worker 202*6c119a46SAndroid Build Coastguard Worker subName string 203*6c119a46SAndroid Build Coastguard Worker subDir string 204*6c119a46SAndroid Build Coastguard Worker 205*6c119a46SAndroid Build Coastguard Worker // Collect the module directory for IDE info in java/jdeps.go. 206*6c119a46SAndroid Build Coastguard Worker modulePaths []string 207*6c119a46SAndroid Build Coastguard Worker} 208*6c119a46SAndroid Build Coastguard Worker 209*6c119a46SAndroid Build Coastguard Workertype taskFunc func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask 210*6c119a46SAndroid Build Coastguard Worker 211*6c119a46SAndroid Build Coastguard Workertype generateTask struct { 212*6c119a46SAndroid Build Coastguard Worker in android.Paths 213*6c119a46SAndroid Build Coastguard Worker out android.WritablePaths 214*6c119a46SAndroid Build Coastguard Worker copyTo android.WritablePaths 215*6c119a46SAndroid Build Coastguard Worker genDir android.WritablePath 216*6c119a46SAndroid Build Coastguard Worker cmd string 217*6c119a46SAndroid Build Coastguard Worker 218*6c119a46SAndroid Build Coastguard Worker shard int 219*6c119a46SAndroid Build Coastguard Worker shards int 220*6c119a46SAndroid Build Coastguard Worker} 221*6c119a46SAndroid Build Coastguard Worker 222*6c119a46SAndroid Build Coastguard Worker// Part of genrule.SourceFileGenerator. 223*6c119a46SAndroid Build Coastguard Worker// Returns the list of generated source files. 224*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) GeneratedSourceFiles() android.Paths { 225*6c119a46SAndroid Build Coastguard Worker return g.outputFiles 226*6c119a46SAndroid Build Coastguard Worker} 227*6c119a46SAndroid Build Coastguard Worker 228*6c119a46SAndroid Build Coastguard Worker// Part of genrule.SourceFileGenerator. 229*6c119a46SAndroid Build Coastguard Worker// Returns the list of input source files. 230*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) Srcs() android.Paths { 231*6c119a46SAndroid Build Coastguard Worker return append(android.Paths{}, g.outputFiles...) 232*6c119a46SAndroid Build Coastguard Worker} 233*6c119a46SAndroid Build Coastguard Worker 234*6c119a46SAndroid Build Coastguard Worker// Part of genrule.SourceFileGenerator. 235*6c119a46SAndroid Build Coastguard Worker// Returns the list of the list of exported include paths. 236*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) GeneratedHeaderDirs() android.Paths { 237*6c119a46SAndroid Build Coastguard Worker return g.exportedIncludeDirs 238*6c119a46SAndroid Build Coastguard Worker} 239*6c119a46SAndroid Build Coastguard Worker 240*6c119a46SAndroid Build Coastguard Worker// Part of genrule.SourceFileGenerator. 241*6c119a46SAndroid Build Coastguard Worker// Returns the list of files to be used as dependencies when using 242*6c119a46SAndroid Build Coastguard Worker// GeneratedHeaderDirs 243*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) GeneratedDeps() android.Paths { 244*6c119a46SAndroid Build Coastguard Worker return g.outputDeps 245*6c119a46SAndroid Build Coastguard Worker} 246*6c119a46SAndroid Build Coastguard Worker 247*6c119a46SAndroid Build Coastguard Worker// Ensure Module implements the genrule.SourceFileGenerator interface. 248*6c119a46SAndroid Build Coastguard Workervar _ genrule.SourceFileGenerator = (*Module)(nil) 249*6c119a46SAndroid Build Coastguard Worker 250*6c119a46SAndroid Build Coastguard Worker// Ensure Module implements the android.SourceFileProducer interface. 251*6c119a46SAndroid Build Coastguard Workervar _ android.SourceFileProducer = (*Module)(nil) 252*6c119a46SAndroid Build Coastguard Worker 253*6c119a46SAndroid Build Coastguard Workerfunc toolDepsMutator(ctx android.BottomUpMutatorContext) { 254*6c119a46SAndroid Build Coastguard Worker if g, ok := ctx.Module().(*Module); ok { 255*6c119a46SAndroid Build Coastguard Worker for _, tool := range g.properties.Tools { 256*6c119a46SAndroid Build Coastguard Worker tag := hostToolDependencyTag{label: tool} 257*6c119a46SAndroid Build Coastguard Worker if m := android.SrcIsModule(tool); m != "" { 258*6c119a46SAndroid Build Coastguard Worker tool = m 259*6c119a46SAndroid Build Coastguard Worker } 260*6c119a46SAndroid Build Coastguard Worker ctx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), tag, tool) 261*6c119a46SAndroid Build Coastguard Worker } 262*6c119a46SAndroid Build Coastguard Worker } 263*6c119a46SAndroid Build Coastguard Worker} 264*6c119a46SAndroid Build Coastguard Worker 265*6c119a46SAndroid Build Coastguard Worker// Part of android.Module. 266*6c119a46SAndroid Build Coastguard Worker// Generates all the rules and builds commands used by this module instance. 267*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { 268*6c119a46SAndroid Build Coastguard Worker g.subName = ctx.ModuleSubDir() 269*6c119a46SAndroid Build Coastguard Worker 270*6c119a46SAndroid Build Coastguard Worker // Collect the module directory for IDE info in java/jdeps.go. 271*6c119a46SAndroid Build Coastguard Worker g.modulePaths = append(g.modulePaths, ctx.ModuleDir()) 272*6c119a46SAndroid Build Coastguard Worker 273*6c119a46SAndroid Build Coastguard Worker if len(g.properties.Export_include_dirs) > 0 { 274*6c119a46SAndroid Build Coastguard Worker for _, dir := range g.properties.Export_include_dirs { 275*6c119a46SAndroid Build Coastguard Worker g.exportedIncludeDirs = append(g.exportedIncludeDirs, 276*6c119a46SAndroid Build Coastguard Worker android.PathForModuleGen(ctx, g.subDir, ctx.ModuleDir(), dir)) 277*6c119a46SAndroid Build Coastguard Worker } 278*6c119a46SAndroid Build Coastguard Worker } else { 279*6c119a46SAndroid Build Coastguard Worker g.exportedIncludeDirs = append(g.exportedIncludeDirs, android.PathForModuleGen(ctx, g.subDir)) 280*6c119a46SAndroid Build Coastguard Worker } 281*6c119a46SAndroid Build Coastguard Worker 282*6c119a46SAndroid Build Coastguard Worker locationLabels := map[string]location{} 283*6c119a46SAndroid Build Coastguard Worker firstLabel := "" 284*6c119a46SAndroid Build Coastguard Worker 285*6c119a46SAndroid Build Coastguard Worker addLocationLabel := func(label string, loc location) { 286*6c119a46SAndroid Build Coastguard Worker if firstLabel == "" { 287*6c119a46SAndroid Build Coastguard Worker firstLabel = label 288*6c119a46SAndroid Build Coastguard Worker } 289*6c119a46SAndroid Build Coastguard Worker if _, exists := locationLabels[label]; !exists { 290*6c119a46SAndroid Build Coastguard Worker locationLabels[label] = loc 291*6c119a46SAndroid Build Coastguard Worker } else { 292*6c119a46SAndroid Build Coastguard Worker ctx.ModuleErrorf("multiple locations for label %q: %q and %q (do you have duplicate srcs entries?)", 293*6c119a46SAndroid Build Coastguard Worker label, locationLabels[label], loc) 294*6c119a46SAndroid Build Coastguard Worker } 295*6c119a46SAndroid Build Coastguard Worker } 296*6c119a46SAndroid Build Coastguard Worker 297*6c119a46SAndroid Build Coastguard Worker var tools android.Paths 298*6c119a46SAndroid Build Coastguard Worker var packagedTools []android.PackagingSpec 299*6c119a46SAndroid Build Coastguard Worker if len(g.properties.Tools) > 0 { 300*6c119a46SAndroid Build Coastguard Worker seenTools := make(map[string]bool) 301*6c119a46SAndroid Build Coastguard Worker 302*6c119a46SAndroid Build Coastguard Worker ctx.VisitDirectDepsProxyAllowDisabled(func(proxy android.ModuleProxy) { 303*6c119a46SAndroid Build Coastguard Worker switch tag := ctx.OtherModuleDependencyTag(proxy).(type) { 304*6c119a46SAndroid Build Coastguard Worker case hostToolDependencyTag: 305*6c119a46SAndroid Build Coastguard Worker // Necessary to retrieve any prebuilt replacement for the tool, since 306*6c119a46SAndroid Build Coastguard Worker // toolDepsMutator runs too late for the prebuilt mutators to have 307*6c119a46SAndroid Build Coastguard Worker // replaced the dependency. 308*6c119a46SAndroid Build Coastguard Worker module := android.PrebuiltGetPreferred(ctx, proxy) 309*6c119a46SAndroid Build Coastguard Worker tool := ctx.OtherModuleName(module) 310*6c119a46SAndroid Build Coastguard Worker if h, ok := android.OtherModuleProvider(ctx, module, android.HostToolProviderKey); ok { 311*6c119a46SAndroid Build Coastguard Worker // A HostToolProvider provides the path to a tool, which will be copied 312*6c119a46SAndroid Build Coastguard Worker // into the sandbox. 313*6c119a46SAndroid Build Coastguard Worker if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled { 314*6c119a46SAndroid Build Coastguard Worker if ctx.Config().AllowMissingDependencies() { 315*6c119a46SAndroid Build Coastguard Worker ctx.AddMissingDependencies([]string{tool}) 316*6c119a46SAndroid Build Coastguard Worker } else { 317*6c119a46SAndroid Build Coastguard Worker ctx.ModuleErrorf("depends on disabled module %q", tool) 318*6c119a46SAndroid Build Coastguard Worker } 319*6c119a46SAndroid Build Coastguard Worker return 320*6c119a46SAndroid Build Coastguard Worker } 321*6c119a46SAndroid Build Coastguard Worker path := h.HostToolPath 322*6c119a46SAndroid Build Coastguard Worker if !path.Valid() { 323*6c119a46SAndroid Build Coastguard Worker ctx.ModuleErrorf("host tool %q missing output file", tool) 324*6c119a46SAndroid Build Coastguard Worker return 325*6c119a46SAndroid Build Coastguard Worker } 326*6c119a46SAndroid Build Coastguard Worker if specs := android.OtherModuleProviderOrDefault( 327*6c119a46SAndroid Build Coastguard Worker ctx, module, android.InstallFilesProvider).TransitivePackagingSpecs.ToList(); specs != nil { 328*6c119a46SAndroid Build Coastguard Worker // If the HostToolProvider has PackgingSpecs, which are definitions of the 329*6c119a46SAndroid Build Coastguard Worker // required relative locations of the tool and its dependencies, use those 330*6c119a46SAndroid Build Coastguard Worker // instead. They will be copied to those relative locations in the sbox 331*6c119a46SAndroid Build Coastguard Worker // sandbox. 332*6c119a46SAndroid Build Coastguard Worker // Care must be taken since TransitivePackagingSpec may return device-side 333*6c119a46SAndroid Build Coastguard Worker // paths via the required property. Filter them out. 334*6c119a46SAndroid Build Coastguard Worker for i, ps := range specs { 335*6c119a46SAndroid Build Coastguard Worker if ps.Partition() != "" { 336*6c119a46SAndroid Build Coastguard Worker if i == 0 { 337*6c119a46SAndroid Build Coastguard Worker panic("first PackagingSpec is assumed to be the host-side tool") 338*6c119a46SAndroid Build Coastguard Worker } 339*6c119a46SAndroid Build Coastguard Worker continue 340*6c119a46SAndroid Build Coastguard Worker } 341*6c119a46SAndroid Build Coastguard Worker packagedTools = append(packagedTools, ps) 342*6c119a46SAndroid Build Coastguard Worker } 343*6c119a46SAndroid Build Coastguard Worker // Assume that the first PackagingSpec of the module is the tool. 344*6c119a46SAndroid Build Coastguard Worker addLocationLabel(tag.label, packagedToolLocation{specs[0]}) 345*6c119a46SAndroid Build Coastguard Worker } else { 346*6c119a46SAndroid Build Coastguard Worker tools = append(tools, path.Path()) 347*6c119a46SAndroid Build Coastguard Worker addLocationLabel(tag.label, toolLocation{android.Paths{path.Path()}}) 348*6c119a46SAndroid Build Coastguard Worker } 349*6c119a46SAndroid Build Coastguard Worker } else { 350*6c119a46SAndroid Build Coastguard Worker ctx.ModuleErrorf("%q is not a host tool provider", tool) 351*6c119a46SAndroid Build Coastguard Worker return 352*6c119a46SAndroid Build Coastguard Worker } 353*6c119a46SAndroid Build Coastguard Worker 354*6c119a46SAndroid Build Coastguard Worker seenTools[tag.label] = true 355*6c119a46SAndroid Build Coastguard Worker } 356*6c119a46SAndroid Build Coastguard Worker }) 357*6c119a46SAndroid Build Coastguard Worker 358*6c119a46SAndroid Build Coastguard Worker // If AllowMissingDependencies is enabled, the build will not have stopped when 359*6c119a46SAndroid Build Coastguard Worker // AddFarVariationDependencies was called on a missing tool, which will result in nonsensical 360*6c119a46SAndroid Build Coastguard Worker // "cmd: unknown location label ..." errors later. Add a placeholder file to the local label. 361*6c119a46SAndroid Build Coastguard Worker // The command that uses this placeholder file will never be executed because the rule will be 362*6c119a46SAndroid Build Coastguard Worker // replaced with an android.Error rule reporting the missing dependencies. 363*6c119a46SAndroid Build Coastguard Worker if ctx.Config().AllowMissingDependencies() { 364*6c119a46SAndroid Build Coastguard Worker for _, tool := range g.properties.Tools { 365*6c119a46SAndroid Build Coastguard Worker if !seenTools[tool] { 366*6c119a46SAndroid Build Coastguard Worker addLocationLabel(tool, errorLocation{"***missing tool " + tool + "***"}) 367*6c119a46SAndroid Build Coastguard Worker } 368*6c119a46SAndroid Build Coastguard Worker } 369*6c119a46SAndroid Build Coastguard Worker } 370*6c119a46SAndroid Build Coastguard Worker } 371*6c119a46SAndroid Build Coastguard Worker 372*6c119a46SAndroid Build Coastguard Worker if ctx.Failed() { 373*6c119a46SAndroid Build Coastguard Worker return 374*6c119a46SAndroid Build Coastguard Worker } 375*6c119a46SAndroid Build Coastguard Worker 376*6c119a46SAndroid Build Coastguard Worker for _, toolFile := range g.properties.Tool_files { 377*6c119a46SAndroid Build Coastguard Worker paths := android.PathsForModuleSrc(ctx, []string{toolFile}) 378*6c119a46SAndroid Build Coastguard Worker tools = append(tools, paths...) 379*6c119a46SAndroid Build Coastguard Worker addLocationLabel(toolFile, toolLocation{paths}) 380*6c119a46SAndroid Build Coastguard Worker } 381*6c119a46SAndroid Build Coastguard Worker 382*6c119a46SAndroid Build Coastguard Worker includeDirInPaths := ctx.DeviceConfig().BuildBrokenInputDir(g.Name()) 383*6c119a46SAndroid Build Coastguard Worker var srcFiles android.Paths 384*6c119a46SAndroid Build Coastguard Worker for _, in := range g.properties.Srcs { 385*6c119a46SAndroid Build Coastguard Worker paths, missingDeps := android.PathsAndMissingDepsRelativeToModuleSourceDir(android.SourceInput{ 386*6c119a46SAndroid Build Coastguard Worker Context: ctx, Paths: []string{in}, ExcludePaths: g.properties.Exclude_srcs, IncludeDirs: includeDirInPaths, 387*6c119a46SAndroid Build Coastguard Worker }) 388*6c119a46SAndroid Build Coastguard Worker if len(missingDeps) > 0 { 389*6c119a46SAndroid Build Coastguard Worker if !ctx.Config().AllowMissingDependencies() { 390*6c119a46SAndroid Build Coastguard Worker panic(fmt.Errorf("should never get here, the missing dependencies %q should have been reported in DepsMutator", 391*6c119a46SAndroid Build Coastguard Worker missingDeps)) 392*6c119a46SAndroid Build Coastguard Worker } 393*6c119a46SAndroid Build Coastguard Worker 394*6c119a46SAndroid Build Coastguard Worker // If AllowMissingDependencies is enabled, the build will not have stopped when 395*6c119a46SAndroid Build Coastguard Worker // the dependency was added on a missing SourceFileProducer module, which will result in nonsensical 396*6c119a46SAndroid Build Coastguard Worker // "cmd: label ":..." has no files" errors later. Add a placeholder file to the local label. 397*6c119a46SAndroid Build Coastguard Worker // The command that uses this placeholder file will never be executed because the rule will be 398*6c119a46SAndroid Build Coastguard Worker // replaced with an android.Error rule reporting the missing dependencies. 399*6c119a46SAndroid Build Coastguard Worker ctx.AddMissingDependencies(missingDeps) 400*6c119a46SAndroid Build Coastguard Worker addLocationLabel(in, errorLocation{"***missing srcs " + in + "***"}) 401*6c119a46SAndroid Build Coastguard Worker } else { 402*6c119a46SAndroid Build Coastguard Worker srcFiles = append(srcFiles, paths...) 403*6c119a46SAndroid Build Coastguard Worker addLocationLabel(in, inputLocation{paths}) 404*6c119a46SAndroid Build Coastguard Worker } 405*6c119a46SAndroid Build Coastguard Worker } 406*6c119a46SAndroid Build Coastguard Worker 407*6c119a46SAndroid Build Coastguard Worker var copyFrom android.Paths 408*6c119a46SAndroid Build Coastguard Worker var outputFiles android.WritablePaths 409*6c119a46SAndroid Build Coastguard Worker var zipArgs strings.Builder 410*6c119a46SAndroid Build Coastguard Worker 411*6c119a46SAndroid Build Coastguard Worker cmd := proptools.String(g.properties.Cmd) 412*6c119a46SAndroid Build Coastguard Worker 413*6c119a46SAndroid Build Coastguard Worker tasks := g.taskGenerator(ctx, cmd, srcFiles) 414*6c119a46SAndroid Build Coastguard Worker if ctx.Failed() { 415*6c119a46SAndroid Build Coastguard Worker return 416*6c119a46SAndroid Build Coastguard Worker } 417*6c119a46SAndroid Build Coastguard Worker 418*6c119a46SAndroid Build Coastguard Worker for _, task := range tasks { 419*6c119a46SAndroid Build Coastguard Worker if len(task.out) == 0 { 420*6c119a46SAndroid Build Coastguard Worker ctx.ModuleErrorf("must have at least one output file") 421*6c119a46SAndroid Build Coastguard Worker return 422*6c119a46SAndroid Build Coastguard Worker } 423*6c119a46SAndroid Build Coastguard Worker 424*6c119a46SAndroid Build Coastguard Worker // Pick a unique path outside the task.genDir for the sbox manifest textproto, 425*6c119a46SAndroid Build Coastguard Worker // a unique rule name, and the user-visible description. 426*6c119a46SAndroid Build Coastguard Worker manifestName := "wayland_protocol_codegen.sbox.textproto" 427*6c119a46SAndroid Build Coastguard Worker desc := "generate" 428*6c119a46SAndroid Build Coastguard Worker name := "generator" 429*6c119a46SAndroid Build Coastguard Worker if task.shards > 0 { 430*6c119a46SAndroid Build Coastguard Worker manifestName = "wayland_protocol_codegen_" + strconv.Itoa(task.shard) + ".sbox.textproto" 431*6c119a46SAndroid Build Coastguard Worker desc += " " + strconv.Itoa(task.shard) 432*6c119a46SAndroid Build Coastguard Worker name += strconv.Itoa(task.shard) 433*6c119a46SAndroid Build Coastguard Worker } else if len(task.out) == 1 { 434*6c119a46SAndroid Build Coastguard Worker desc += " " + task.out[0].Base() 435*6c119a46SAndroid Build Coastguard Worker } 436*6c119a46SAndroid Build Coastguard Worker 437*6c119a46SAndroid Build Coastguard Worker manifestPath := android.PathForModuleOut(ctx, manifestName) 438*6c119a46SAndroid Build Coastguard Worker 439*6c119a46SAndroid Build Coastguard Worker // Use a RuleBuilder to create a rule that runs the command inside an sbox sandbox. 440*6c119a46SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx).Sbox(task.genDir, manifestPath).SandboxTools() 441*6c119a46SAndroid Build Coastguard Worker cmd := rule.Command() 442*6c119a46SAndroid Build Coastguard Worker 443*6c119a46SAndroid Build Coastguard Worker for _, out := range task.out { 444*6c119a46SAndroid Build Coastguard Worker addLocationLabel(out.Rel(), outputLocation{out}) 445*6c119a46SAndroid Build Coastguard Worker } 446*6c119a46SAndroid Build Coastguard Worker 447*6c119a46SAndroid Build Coastguard Worker rawCommand, err := android.Expand(task.cmd, func(name string) (string, error) { 448*6c119a46SAndroid Build Coastguard Worker // Report the error directly without returning an error to android.Expand to catch multiple errors in a 449*6c119a46SAndroid Build Coastguard Worker // single run 450*6c119a46SAndroid Build Coastguard Worker reportError := func(fmt string, args ...interface{}) (string, error) { 451*6c119a46SAndroid Build Coastguard Worker ctx.PropertyErrorf("cmd", fmt, args...) 452*6c119a46SAndroid Build Coastguard Worker return "SOONG_ERROR", nil 453*6c119a46SAndroid Build Coastguard Worker } 454*6c119a46SAndroid Build Coastguard Worker 455*6c119a46SAndroid Build Coastguard Worker // Apply shell escape to each cases to prevent source file paths containing $ from being evaluated in shell 456*6c119a46SAndroid Build Coastguard Worker switch name { 457*6c119a46SAndroid Build Coastguard Worker case "location": 458*6c119a46SAndroid Build Coastguard Worker if len(g.properties.Tools) == 0 && len(g.properties.Tool_files) == 0 { 459*6c119a46SAndroid Build Coastguard Worker return reportError("at least one `tools` or `tool_files` is required if $(location) is used") 460*6c119a46SAndroid Build Coastguard Worker } 461*6c119a46SAndroid Build Coastguard Worker loc := locationLabels[firstLabel] 462*6c119a46SAndroid Build Coastguard Worker paths := loc.Paths(cmd) 463*6c119a46SAndroid Build Coastguard Worker if len(paths) == 0 { 464*6c119a46SAndroid Build Coastguard Worker return reportError("default label %q has no files", firstLabel) 465*6c119a46SAndroid Build Coastguard Worker } else if len(paths) > 1 { 466*6c119a46SAndroid Build Coastguard Worker return reportError("default label %q has multiple files, use $(locations %s) to reference it", 467*6c119a46SAndroid Build Coastguard Worker firstLabel, firstLabel) 468*6c119a46SAndroid Build Coastguard Worker } 469*6c119a46SAndroid Build Coastguard Worker return proptools.ShellEscape(paths[0]), nil 470*6c119a46SAndroid Build Coastguard Worker case "in": 471*6c119a46SAndroid Build Coastguard Worker return strings.Join(proptools.ShellEscapeList(cmd.PathsForInputs(srcFiles)), " "), nil 472*6c119a46SAndroid Build Coastguard Worker case "out": 473*6c119a46SAndroid Build Coastguard Worker var sandboxOuts []string 474*6c119a46SAndroid Build Coastguard Worker for _, out := range task.out { 475*6c119a46SAndroid Build Coastguard Worker sandboxOuts = append(sandboxOuts, cmd.PathForOutput(out)) 476*6c119a46SAndroid Build Coastguard Worker } 477*6c119a46SAndroid Build Coastguard Worker return strings.Join(proptools.ShellEscapeList(sandboxOuts), " "), nil 478*6c119a46SAndroid Build Coastguard Worker case "genDir": 479*6c119a46SAndroid Build Coastguard Worker return proptools.ShellEscape(cmd.PathForOutput(task.genDir)), nil 480*6c119a46SAndroid Build Coastguard Worker default: 481*6c119a46SAndroid Build Coastguard Worker if strings.HasPrefix(name, "location ") { 482*6c119a46SAndroid Build Coastguard Worker label := strings.TrimSpace(strings.TrimPrefix(name, "location ")) 483*6c119a46SAndroid Build Coastguard Worker if loc, ok := locationLabels[label]; ok { 484*6c119a46SAndroid Build Coastguard Worker paths := loc.Paths(cmd) 485*6c119a46SAndroid Build Coastguard Worker if len(paths) == 0 { 486*6c119a46SAndroid Build Coastguard Worker return reportError("label %q has no files", label) 487*6c119a46SAndroid Build Coastguard Worker } else if len(paths) > 1 { 488*6c119a46SAndroid Build Coastguard Worker return reportError("label %q has multiple files, use $(locations %s) to reference it", 489*6c119a46SAndroid Build Coastguard Worker label, label) 490*6c119a46SAndroid Build Coastguard Worker } 491*6c119a46SAndroid Build Coastguard Worker return proptools.ShellEscape(paths[0]), nil 492*6c119a46SAndroid Build Coastguard Worker } else { 493*6c119a46SAndroid Build Coastguard Worker return reportError("unknown location label %q is not in srcs, out, tools or tool_files.", label) 494*6c119a46SAndroid Build Coastguard Worker } 495*6c119a46SAndroid Build Coastguard Worker } else if strings.HasPrefix(name, "locations ") { 496*6c119a46SAndroid Build Coastguard Worker label := strings.TrimSpace(strings.TrimPrefix(name, "locations ")) 497*6c119a46SAndroid Build Coastguard Worker if loc, ok := locationLabels[label]; ok { 498*6c119a46SAndroid Build Coastguard Worker paths := loc.Paths(cmd) 499*6c119a46SAndroid Build Coastguard Worker if len(paths) == 0 { 500*6c119a46SAndroid Build Coastguard Worker return reportError("label %q has no files", label) 501*6c119a46SAndroid Build Coastguard Worker } 502*6c119a46SAndroid Build Coastguard Worker return proptools.ShellEscape(strings.Join(paths, " ")), nil 503*6c119a46SAndroid Build Coastguard Worker } else { 504*6c119a46SAndroid Build Coastguard Worker return reportError("unknown locations label %q is not in srcs, out, tools or tool_files.", label) 505*6c119a46SAndroid Build Coastguard Worker } 506*6c119a46SAndroid Build Coastguard Worker } else { 507*6c119a46SAndroid Build Coastguard Worker return reportError("unknown variable '$(%s)'", name) 508*6c119a46SAndroid Build Coastguard Worker } 509*6c119a46SAndroid Build Coastguard Worker } 510*6c119a46SAndroid Build Coastguard Worker }) 511*6c119a46SAndroid Build Coastguard Worker 512*6c119a46SAndroid Build Coastguard Worker if err != nil { 513*6c119a46SAndroid Build Coastguard Worker ctx.PropertyErrorf("cmd", "%s", err.Error()) 514*6c119a46SAndroid Build Coastguard Worker return 515*6c119a46SAndroid Build Coastguard Worker } 516*6c119a46SAndroid Build Coastguard Worker 517*6c119a46SAndroid Build Coastguard Worker g.rawCommands = append(g.rawCommands, rawCommand) 518*6c119a46SAndroid Build Coastguard Worker 519*6c119a46SAndroid Build Coastguard Worker cmd.Text(rawCommand) 520*6c119a46SAndroid Build Coastguard Worker cmd.ImplicitOutputs(task.out) 521*6c119a46SAndroid Build Coastguard Worker cmd.Implicits(task.in) 522*6c119a46SAndroid Build Coastguard Worker cmd.ImplicitTools(tools) 523*6c119a46SAndroid Build Coastguard Worker cmd.ImplicitPackagedTools(packagedTools) 524*6c119a46SAndroid Build Coastguard Worker 525*6c119a46SAndroid Build Coastguard Worker // Create the rule to run the genrule command inside sbox. 526*6c119a46SAndroid Build Coastguard Worker rule.Build(name, desc) 527*6c119a46SAndroid Build Coastguard Worker 528*6c119a46SAndroid Build Coastguard Worker if len(task.copyTo) > 0 { 529*6c119a46SAndroid Build Coastguard Worker // If copyTo is set, multiple shards need to be copied into a single directory. 530*6c119a46SAndroid Build Coastguard Worker // task.out contains the per-shard paths, and copyTo contains the corresponding 531*6c119a46SAndroid Build Coastguard Worker // final path. The files need to be copied into the final directory by a 532*6c119a46SAndroid Build Coastguard Worker // single rule so it can remove the directory before it starts to ensure no 533*6c119a46SAndroid Build Coastguard Worker // old files remain. zipsync already does this, so build up zipArgs that 534*6c119a46SAndroid Build Coastguard Worker // zip all the per-shard directories into a single zip. 535*6c119a46SAndroid Build Coastguard Worker outputFiles = append(outputFiles, task.copyTo...) 536*6c119a46SAndroid Build Coastguard Worker copyFrom = append(copyFrom, task.out.Paths()...) 537*6c119a46SAndroid Build Coastguard Worker zipArgs.WriteString(" -C " + task.genDir.String()) 538*6c119a46SAndroid Build Coastguard Worker zipArgs.WriteString(android.JoinWithPrefix(task.out.Strings(), " -f ")) 539*6c119a46SAndroid Build Coastguard Worker } else { 540*6c119a46SAndroid Build Coastguard Worker outputFiles = append(outputFiles, task.out...) 541*6c119a46SAndroid Build Coastguard Worker } 542*6c119a46SAndroid Build Coastguard Worker } 543*6c119a46SAndroid Build Coastguard Worker 544*6c119a46SAndroid Build Coastguard Worker if len(copyFrom) > 0 { 545*6c119a46SAndroid Build Coastguard Worker // Create a rule that zips all the per-shard directories into a single zip and then 546*6c119a46SAndroid Build Coastguard Worker // uses zipsync to unzip it into the final directory. 547*6c119a46SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 548*6c119a46SAndroid Build Coastguard Worker Rule: gensrcsMerge, 549*6c119a46SAndroid Build Coastguard Worker Implicits: copyFrom, 550*6c119a46SAndroid Build Coastguard Worker Outputs: outputFiles, 551*6c119a46SAndroid Build Coastguard Worker Description: "merge shards", 552*6c119a46SAndroid Build Coastguard Worker Args: map[string]string{ 553*6c119a46SAndroid Build Coastguard Worker "zipArgs": zipArgs.String(), 554*6c119a46SAndroid Build Coastguard Worker "tmpZip": android.PathForModuleGen(ctx, g.subDir+".zip").String(), 555*6c119a46SAndroid Build Coastguard Worker "genDir": android.PathForModuleGen(ctx, g.subDir).String(), 556*6c119a46SAndroid Build Coastguard Worker }, 557*6c119a46SAndroid Build Coastguard Worker }) 558*6c119a46SAndroid Build Coastguard Worker } 559*6c119a46SAndroid Build Coastguard Worker 560*6c119a46SAndroid Build Coastguard Worker g.outputFiles = outputFiles.Paths() 561*6c119a46SAndroid Build Coastguard Worker} 562*6c119a46SAndroid Build Coastguard Worker 563*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { 564*6c119a46SAndroid Build Coastguard Worker g.generateCommonBuildActions(ctx) 565*6c119a46SAndroid Build Coastguard Worker 566*6c119a46SAndroid Build Coastguard Worker // When there are less than six outputs, we directly give those as the 567*6c119a46SAndroid Build Coastguard Worker // output dependency for this module. However, if there are more outputs, 568*6c119a46SAndroid Build Coastguard Worker // we inject a phony target. This potentially saves space in the generated 569*6c119a46SAndroid Build Coastguard Worker // ninja file, as well as simplifying any visualizations of the dependency 570*6c119a46SAndroid Build Coastguard Worker // graph. 571*6c119a46SAndroid Build Coastguard Worker if len(g.outputFiles) <= 6 { 572*6c119a46SAndroid Build Coastguard Worker g.outputDeps = g.outputFiles 573*6c119a46SAndroid Build Coastguard Worker } else { 574*6c119a46SAndroid Build Coastguard Worker phonyFile := android.PathForModuleGen(ctx, "genrule-phony") 575*6c119a46SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 576*6c119a46SAndroid Build Coastguard Worker Rule: blueprint.Phony, 577*6c119a46SAndroid Build Coastguard Worker Output: phonyFile, 578*6c119a46SAndroid Build Coastguard Worker Inputs: g.outputFiles, 579*6c119a46SAndroid Build Coastguard Worker }) 580*6c119a46SAndroid Build Coastguard Worker g.outputDeps = android.Paths{phonyFile} 581*6c119a46SAndroid Build Coastguard Worker } 582*6c119a46SAndroid Build Coastguard Worker 583*6c119a46SAndroid Build Coastguard Worker g.setOutputFiles(ctx) 584*6c119a46SAndroid Build Coastguard Worker} 585*6c119a46SAndroid Build Coastguard Worker 586*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) setOutputFiles(ctx android.ModuleContext) { 587*6c119a46SAndroid Build Coastguard Worker if len(g.outputFiles) == 0 { 588*6c119a46SAndroid Build Coastguard Worker return 589*6c119a46SAndroid Build Coastguard Worker } 590*6c119a46SAndroid Build Coastguard Worker ctx.SetOutputFiles(g.outputFiles, "") 591*6c119a46SAndroid Build Coastguard Worker // non-empty-string-tag should match one of the outputs 592*6c119a46SAndroid Build Coastguard Worker for _, files := range g.outputFiles { 593*6c119a46SAndroid Build Coastguard Worker ctx.SetOutputFiles(android.Paths{files}, files.Rel()) 594*6c119a46SAndroid Build Coastguard Worker } 595*6c119a46SAndroid Build Coastguard Worker} 596*6c119a46SAndroid Build Coastguard Worker 597*6c119a46SAndroid Build Coastguard Worker// Part of android.IDEInfo. 598*6c119a46SAndroid Build Coastguard Worker// Collect information for opening IDE project files in java/jdeps.go. 599*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { 600*6c119a46SAndroid Build Coastguard Worker dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...) 601*6c119a46SAndroid Build Coastguard Worker for _, src := range g.properties.Srcs { 602*6c119a46SAndroid Build Coastguard Worker if strings.HasPrefix(src, ":") { 603*6c119a46SAndroid Build Coastguard Worker src = strings.Trim(src, ":") 604*6c119a46SAndroid Build Coastguard Worker dpInfo.Deps = append(dpInfo.Deps, src) 605*6c119a46SAndroid Build Coastguard Worker } 606*6c119a46SAndroid Build Coastguard Worker } 607*6c119a46SAndroid Build Coastguard Worker dpInfo.Paths = append(dpInfo.Paths, g.modulePaths...) 608*6c119a46SAndroid Build Coastguard Worker} 609*6c119a46SAndroid Build Coastguard Worker 610*6c119a46SAndroid Build Coastguard Workervar _ android.IDEInfo = (*Module)(nil) 611*6c119a46SAndroid Build Coastguard Worker 612*6c119a46SAndroid Build Coastguard Worker// Ensure Module implements android.ApexModule 613*6c119a46SAndroid Build Coastguard Worker// Note: gensrcs implements it but it's possible we do not actually need to. 614*6c119a46SAndroid Build Coastguard Workervar _ android.ApexModule = (*Module)(nil) 615*6c119a46SAndroid Build Coastguard Worker 616*6c119a46SAndroid Build Coastguard Worker// Part of android.ApexModule. 617*6c119a46SAndroid Build Coastguard Workerfunc (g *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 618*6c119a46SAndroid Build Coastguard Worker sdkVersion android.ApiLevel) error { 619*6c119a46SAndroid Build Coastguard Worker // Because generated outputs are checked by client modules(e.g. cc_library, ...) 620*6c119a46SAndroid Build Coastguard Worker // we can safely ignore the check here. 621*6c119a46SAndroid Build Coastguard Worker return nil 622*6c119a46SAndroid Build Coastguard Worker} 623*6c119a46SAndroid Build Coastguard Worker 624*6c119a46SAndroid Build Coastguard Workerfunc generatorFactory(taskGenerator taskFunc, props ...interface{}) *Module { 625*6c119a46SAndroid Build Coastguard Worker module := &Module{ 626*6c119a46SAndroid Build Coastguard Worker taskGenerator: taskGenerator, 627*6c119a46SAndroid Build Coastguard Worker } 628*6c119a46SAndroid Build Coastguard Worker 629*6c119a46SAndroid Build Coastguard Worker module.AddProperties(props...) 630*6c119a46SAndroid Build Coastguard Worker module.AddProperties(&module.properties) 631*6c119a46SAndroid Build Coastguard Worker 632*6c119a46SAndroid Build Coastguard Worker module.ImageInterface = noopImageInterface{} 633*6c119a46SAndroid Build Coastguard Worker 634*6c119a46SAndroid Build Coastguard Worker return module 635*6c119a46SAndroid Build Coastguard Worker} 636*6c119a46SAndroid Build Coastguard Worker 637*6c119a46SAndroid Build Coastguard Workertype noopImageInterface struct{} 638*6c119a46SAndroid Build Coastguard Worker 639*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) ImageMutatorBegin(android.ImageInterfaceContext) {} 640*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) VendorVariantNeeded(android.ImageInterfaceContext) bool { return false } 641*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) ProductVariantNeeded(android.ImageInterfaceContext) bool { return false } 642*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) CoreVariantNeeded(android.ImageInterfaceContext) bool { return false } 643*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) RamdiskVariantNeeded(android.ImageInterfaceContext) bool { return false } 644*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) VendorRamdiskVariantNeeded(android.ImageInterfaceContext) bool { return false } 645*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) DebugRamdiskVariantNeeded(android.ImageInterfaceContext) bool { return false } 646*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) RecoveryVariantNeeded(android.ImageInterfaceContext) bool { return false } 647*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) ExtraImageVariations(ctx android.ImageInterfaceContext) []string { return nil } 648*6c119a46SAndroid Build Coastguard Workerfunc (x noopImageInterface) SetImageVariation(ctx android.ImageInterfaceContext, variation string) { 649*6c119a46SAndroid Build Coastguard Worker} 650*6c119a46SAndroid Build Coastguard Worker 651*6c119a46SAndroid Build Coastguard Worker// Constructs a Module for handling the code generation. 652*6c119a46SAndroid Build Coastguard Workerfunc newCodegen() *Module { 653*6c119a46SAndroid Build Coastguard Worker properties := &codegenProperties{} 654*6c119a46SAndroid Build Coastguard Worker 655*6c119a46SAndroid Build Coastguard Worker // finalSubDir is the name of the subdirectory that output files will be generated into. 656*6c119a46SAndroid Build Coastguard Worker // It is used so that per-shard directories can be placed alongside it an then finally 657*6c119a46SAndroid Build Coastguard Worker // merged into it. 658*6c119a46SAndroid Build Coastguard Worker const finalSubDir = "wayland_protocol_codegen" 659*6c119a46SAndroid Build Coastguard Worker 660*6c119a46SAndroid Build Coastguard Worker // Code generation commands are sharded so that up to this many files 661*6c119a46SAndroid Build Coastguard Worker // are generated as part of one sandbox process. 662*6c119a46SAndroid Build Coastguard Worker const defaultShardSize = 100 663*6c119a46SAndroid Build Coastguard Worker 664*6c119a46SAndroid Build Coastguard Worker taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask { 665*6c119a46SAndroid Build Coastguard Worker shardSize := defaultShardSize 666*6c119a46SAndroid Build Coastguard Worker 667*6c119a46SAndroid Build Coastguard Worker if len(srcFiles) == 0 { 668*6c119a46SAndroid Build Coastguard Worker ctx.ModuleErrorf("must have at least one source file") 669*6c119a46SAndroid Build Coastguard Worker return []generateTask{} 670*6c119a46SAndroid Build Coastguard Worker } 671*6c119a46SAndroid Build Coastguard Worker 672*6c119a46SAndroid Build Coastguard Worker // wayland_protocol_codegen rules can easily hit command line limits by 673*6c119a46SAndroid Build Coastguard Worker // repeating the command for every input file. Shard the input files into 674*6c119a46SAndroid Build Coastguard Worker // groups. 675*6c119a46SAndroid Build Coastguard Worker shards := android.ShardPaths(srcFiles, shardSize) 676*6c119a46SAndroid Build Coastguard Worker var generateTasks []generateTask 677*6c119a46SAndroid Build Coastguard Worker 678*6c119a46SAndroid Build Coastguard Worker distinctOutputs := make(map[string]android.Path) 679*6c119a46SAndroid Build Coastguard Worker 680*6c119a46SAndroid Build Coastguard Worker for i, shard := range shards { 681*6c119a46SAndroid Build Coastguard Worker var commands []string 682*6c119a46SAndroid Build Coastguard Worker var outFiles android.WritablePaths 683*6c119a46SAndroid Build Coastguard Worker var copyTo android.WritablePaths 684*6c119a46SAndroid Build Coastguard Worker 685*6c119a46SAndroid Build Coastguard Worker // When sharding is enabled (i.e. len(shards) > 1), the sbox rules for each 686*6c119a46SAndroid Build Coastguard Worker // shard will be write to their own directories and then be merged together 687*6c119a46SAndroid Build Coastguard Worker // into finalSubDir. If sharding is not enabled (i.e. len(shards) == 1), 688*6c119a46SAndroid Build Coastguard Worker // the sbox rule will write directly to finalSubDir. 689*6c119a46SAndroid Build Coastguard Worker genSubDir := finalSubDir 690*6c119a46SAndroid Build Coastguard Worker if len(shards) > 1 { 691*6c119a46SAndroid Build Coastguard Worker genSubDir = strconv.Itoa(i) 692*6c119a46SAndroid Build Coastguard Worker } 693*6c119a46SAndroid Build Coastguard Worker 694*6c119a46SAndroid Build Coastguard Worker genDir := android.PathForModuleGen(ctx, genSubDir) 695*6c119a46SAndroid Build Coastguard Worker // NOTE: This TODO is copied from gensrcs, as applies here too. 696*6c119a46SAndroid Build Coastguard Worker // TODO(ccross): this RuleBuilder is a hack to be able to call 697*6c119a46SAndroid Build Coastguard Worker // rule.Command().PathForOutput. Replace this with passing the rule into the 698*6c119a46SAndroid Build Coastguard Worker // generator. 699*6c119a46SAndroid Build Coastguard Worker rule := android.NewRuleBuilder(pctx, ctx).Sbox(genDir, nil).SandboxTools() 700*6c119a46SAndroid Build Coastguard Worker 701*6c119a46SAndroid Build Coastguard Worker for _, in := range shard { 702*6c119a46SAndroid Build Coastguard Worker outFileRaw := expandOutputPath(ctx, *properties, in) 703*6c119a46SAndroid Build Coastguard Worker 704*6c119a46SAndroid Build Coastguard Worker if conflictWith, hasKey := distinctOutputs[outFileRaw]; hasKey { 705*6c119a46SAndroid Build Coastguard Worker ctx.ModuleErrorf("generation conflict: both '%v' and '%v' generate '%v'", 706*6c119a46SAndroid Build Coastguard Worker conflictWith.String(), in.String(), outFileRaw) 707*6c119a46SAndroid Build Coastguard Worker } 708*6c119a46SAndroid Build Coastguard Worker 709*6c119a46SAndroid Build Coastguard Worker distinctOutputs[outFileRaw] = in 710*6c119a46SAndroid Build Coastguard Worker 711*6c119a46SAndroid Build Coastguard Worker outFile := android.PathForModuleGen(ctx, finalSubDir, outFileRaw) 712*6c119a46SAndroid Build Coastguard Worker 713*6c119a46SAndroid Build Coastguard Worker // If sharding is enabled, then outFile is the path to the output file in 714*6c119a46SAndroid Build Coastguard Worker // the shard directory, and copyTo is the path to the output file in the 715*6c119a46SAndroid Build Coastguard Worker // final directory. 716*6c119a46SAndroid Build Coastguard Worker if len(shards) > 1 { 717*6c119a46SAndroid Build Coastguard Worker shardFile := android.PathForModuleGen(ctx, genSubDir, outFileRaw) 718*6c119a46SAndroid Build Coastguard Worker copyTo = append(copyTo, outFile) 719*6c119a46SAndroid Build Coastguard Worker outFile = shardFile 720*6c119a46SAndroid Build Coastguard Worker } 721*6c119a46SAndroid Build Coastguard Worker 722*6c119a46SAndroid Build Coastguard Worker outFiles = append(outFiles, outFile) 723*6c119a46SAndroid Build Coastguard Worker 724*6c119a46SAndroid Build Coastguard Worker // pre-expand the command line to replace $in and $out with references to 725*6c119a46SAndroid Build Coastguard Worker // a single input and output file. 726*6c119a46SAndroid Build Coastguard Worker command, err := android.Expand(rawCommand, func(name string) (string, error) { 727*6c119a46SAndroid Build Coastguard Worker switch name { 728*6c119a46SAndroid Build Coastguard Worker case "in": 729*6c119a46SAndroid Build Coastguard Worker return in.String(), nil 730*6c119a46SAndroid Build Coastguard Worker case "out": 731*6c119a46SAndroid Build Coastguard Worker return rule.Command().PathForOutput(outFile), nil 732*6c119a46SAndroid Build Coastguard Worker default: 733*6c119a46SAndroid Build Coastguard Worker return "$(" + name + ")", nil 734*6c119a46SAndroid Build Coastguard Worker } 735*6c119a46SAndroid Build Coastguard Worker }) 736*6c119a46SAndroid Build Coastguard Worker if err != nil { 737*6c119a46SAndroid Build Coastguard Worker ctx.PropertyErrorf("cmd", err.Error()) 738*6c119a46SAndroid Build Coastguard Worker } 739*6c119a46SAndroid Build Coastguard Worker 740*6c119a46SAndroid Build Coastguard Worker // escape the command in case for example it contains '#', an odd number of '"', etc 741*6c119a46SAndroid Build Coastguard Worker command = fmt.Sprintf("bash -c %v", proptools.ShellEscape(command)) 742*6c119a46SAndroid Build Coastguard Worker commands = append(commands, command) 743*6c119a46SAndroid Build Coastguard Worker } 744*6c119a46SAndroid Build Coastguard Worker fullCommand := strings.Join(commands, " && ") 745*6c119a46SAndroid Build Coastguard Worker 746*6c119a46SAndroid Build Coastguard Worker generateTasks = append(generateTasks, generateTask{ 747*6c119a46SAndroid Build Coastguard Worker in: shard, 748*6c119a46SAndroid Build Coastguard Worker out: outFiles, 749*6c119a46SAndroid Build Coastguard Worker copyTo: copyTo, 750*6c119a46SAndroid Build Coastguard Worker genDir: genDir, 751*6c119a46SAndroid Build Coastguard Worker cmd: fullCommand, 752*6c119a46SAndroid Build Coastguard Worker shard: i, 753*6c119a46SAndroid Build Coastguard Worker shards: len(shards), 754*6c119a46SAndroid Build Coastguard Worker }) 755*6c119a46SAndroid Build Coastguard Worker } 756*6c119a46SAndroid Build Coastguard Worker 757*6c119a46SAndroid Build Coastguard Worker return generateTasks 758*6c119a46SAndroid Build Coastguard Worker } 759*6c119a46SAndroid Build Coastguard Worker 760*6c119a46SAndroid Build Coastguard Worker g := generatorFactory(taskGenerator, properties) 761*6c119a46SAndroid Build Coastguard Worker g.subDir = finalSubDir 762*6c119a46SAndroid Build Coastguard Worker return g 763*6c119a46SAndroid Build Coastguard Worker} 764*6c119a46SAndroid Build Coastguard Worker 765*6c119a46SAndroid Build Coastguard Worker// Factory for code generation modules 766*6c119a46SAndroid Build Coastguard Workerfunc codegenFactory() android.Module { 767*6c119a46SAndroid Build Coastguard Worker m := newCodegen() 768*6c119a46SAndroid Build Coastguard Worker android.InitAndroidModule(m) 769*6c119a46SAndroid Build Coastguard Worker android.InitDefaultableModule(m) 770*6c119a46SAndroid Build Coastguard Worker return m 771*6c119a46SAndroid Build Coastguard Worker} 772*6c119a46SAndroid Build Coastguard Worker 773*6c119a46SAndroid Build Coastguard Worker// The custom properties specific to this code generation module. 774*6c119a46SAndroid Build Coastguard Workertype codegenProperties struct { 775*6c119a46SAndroid Build Coastguard Worker // The string to prepend to every protocol filename to generate the 776*6c119a46SAndroid Build Coastguard Worker // corresponding output filename. The empty string by default. 777*6c119a46SAndroid Build Coastguard Worker // Deprecated. Prefer "Output" instead. 778*6c119a46SAndroid Build Coastguard Worker Prefix *string 779*6c119a46SAndroid Build Coastguard Worker 780*6c119a46SAndroid Build Coastguard Worker // The suffix to append to every protocol filename to generate the 781*6c119a46SAndroid Build Coastguard Worker // corresponding output filename. The empty string by default. 782*6c119a46SAndroid Build Coastguard Worker // Deprecated. Prefer "Output" instead. 783*6c119a46SAndroid Build Coastguard Worker Suffix *string 784*6c119a46SAndroid Build Coastguard Worker 785*6c119a46SAndroid Build Coastguard Worker // The output filename template. 786*6c119a46SAndroid Build Coastguard Worker // 787*6c119a46SAndroid Build Coastguard Worker // This template string allows the output file name to be generated for 788*6c119a46SAndroid Build Coastguard Worker // each source file, using some limited properties of the source file. 789*6c119a46SAndroid Build Coastguard Worker // 790*6c119a46SAndroid Build Coastguard Worker // $(in:base): The base filename, no path or extension 791*6c119a46SAndroid Build Coastguard Worker // $(in:base.ext): The filename, no path 792*6c119a46SAndroid Build Coastguard Worker // $(in:path/base): The filename with path but no extension 793*6c119a46SAndroid Build Coastguard Worker // $(in:path/base.ext): The full source filename 794*6c119a46SAndroid Build Coastguard Worker // $(in): An alias for $(in:base) for the base filename, no extension 795*6c119a46SAndroid Build Coastguard Worker // 796*6c119a46SAndroid Build Coastguard Worker // Note that the path that is maintained is the relative path used when 797*6c119a46SAndroid Build Coastguard Worker // including the source in an Android.bp file. 798*6c119a46SAndroid Build Coastguard Worker // 799*6c119a46SAndroid Build Coastguard Worker // The template allows arbitrary prefixes and suffixes to be added to the 800*6c119a46SAndroid Build Coastguard Worker // output filename. For example, "a_$(in).d" would take an source filename 801*6c119a46SAndroid Build Coastguard Worker // of "b.c" and turn it into "a_b.d". 802*6c119a46SAndroid Build Coastguard Worker // 803*6c119a46SAndroid Build Coastguard Worker // The output template does not have to generate a unique filename, 804*6c119a46SAndroid Build Coastguard Worker // however the implementation will raise an error if the same output file 805*6c119a46SAndroid Build Coastguard Worker // is generated by more than one source file. 806*6c119a46SAndroid Build Coastguard Worker Output *string 807*6c119a46SAndroid Build Coastguard Worker} 808*6c119a46SAndroid Build Coastguard Worker 809*6c119a46SAndroid Build Coastguard Worker// Expands the output path pattern to form the output path for the given 810*6c119a46SAndroid Build Coastguard Worker// input path. 811*6c119a46SAndroid Build Coastguard Workerfunc expandOutputPath(ctx android.ModuleContext, properties codegenProperties, in android.Path) string { 812*6c119a46SAndroid Build Coastguard Worker template := proptools.String(properties.Output) 813*6c119a46SAndroid Build Coastguard Worker if len(template) == 0 { 814*6c119a46SAndroid Build Coastguard Worker prefix := proptools.String(properties.Prefix) 815*6c119a46SAndroid Build Coastguard Worker suffix := proptools.String(properties.Suffix) 816*6c119a46SAndroid Build Coastguard Worker return prefix + removeExtension(in.Base()) + suffix 817*6c119a46SAndroid Build Coastguard Worker } 818*6c119a46SAndroid Build Coastguard Worker 819*6c119a46SAndroid Build Coastguard Worker outPath, _ := android.Expand(template, func(name string) (string, error) { 820*6c119a46SAndroid Build Coastguard Worker // Report the error directly without returning an error to 821*6c119a46SAndroid Build Coastguard Worker // android.Expand to catch multiple errors in a single run. 822*6c119a46SAndroid Build Coastguard Worker reportError := func(fmt string, args ...interface{}) (string, error) { 823*6c119a46SAndroid Build Coastguard Worker ctx.PropertyErrorf("output", fmt, args...) 824*6c119a46SAndroid Build Coastguard Worker return "EXPANSION_ERROR", nil 825*6c119a46SAndroid Build Coastguard Worker } 826*6c119a46SAndroid Build Coastguard Worker 827*6c119a46SAndroid Build Coastguard Worker switch name { 828*6c119a46SAndroid Build Coastguard Worker case "in": 829*6c119a46SAndroid Build Coastguard Worker return removeExtension(in.Base()), nil 830*6c119a46SAndroid Build Coastguard Worker case "in:base": 831*6c119a46SAndroid Build Coastguard Worker return removeExtension(in.Base()), nil 832*6c119a46SAndroid Build Coastguard Worker case "in:base.ext": 833*6c119a46SAndroid Build Coastguard Worker return in.Base(), nil 834*6c119a46SAndroid Build Coastguard Worker case "in:path/base": 835*6c119a46SAndroid Build Coastguard Worker return removeExtension(in.Rel()), nil 836*6c119a46SAndroid Build Coastguard Worker case "in:path/base.ext": 837*6c119a46SAndroid Build Coastguard Worker return in.Rel(), nil 838*6c119a46SAndroid Build Coastguard Worker default: 839*6c119a46SAndroid Build Coastguard Worker return reportError("unknown variable '$(%s)'", name) 840*6c119a46SAndroid Build Coastguard Worker } 841*6c119a46SAndroid Build Coastguard Worker }) 842*6c119a46SAndroid Build Coastguard Worker 843*6c119a46SAndroid Build Coastguard Worker return outPath 844*6c119a46SAndroid Build Coastguard Worker} 845*6c119a46SAndroid Build Coastguard Worker 846*6c119a46SAndroid Build Coastguard Worker// Removes any extension from the final component of a path. 847*6c119a46SAndroid Build Coastguard Workerfunc removeExtension(path string) string { 848*6c119a46SAndroid Build Coastguard Worker // Note: This implementation does not handle files like ".bashrc" correctly. 849*6c119a46SAndroid Build Coastguard Worker if dot := strings.LastIndex(path, "."); dot != -1 { 850*6c119a46SAndroid Build Coastguard Worker return path[:dot] 851*6c119a46SAndroid Build Coastguard Worker } 852*6c119a46SAndroid Build Coastguard Worker return path 853*6c119a46SAndroid Build Coastguard Worker} 854*6c119a46SAndroid Build Coastguard Worker 855*6c119a46SAndroid Build Coastguard Worker// Defaults module. 856*6c119a46SAndroid Build Coastguard Workertype Defaults struct { 857*6c119a46SAndroid Build Coastguard Worker android.ModuleBase 858*6c119a46SAndroid Build Coastguard Worker android.DefaultsModuleBase 859*6c119a46SAndroid Build Coastguard Worker} 860*6c119a46SAndroid Build Coastguard Worker 861*6c119a46SAndroid Build Coastguard Workerfunc defaultsFactory() android.Module { 862*6c119a46SAndroid Build Coastguard Worker return DefaultsFactory() 863*6c119a46SAndroid Build Coastguard Worker} 864*6c119a46SAndroid Build Coastguard Worker 865*6c119a46SAndroid Build Coastguard Workerfunc DefaultsFactory(props ...interface{}) android.Module { 866*6c119a46SAndroid Build Coastguard Worker module := &Defaults{} 867*6c119a46SAndroid Build Coastguard Worker 868*6c119a46SAndroid Build Coastguard Worker module.AddProperties(props...) 869*6c119a46SAndroid Build Coastguard Worker module.AddProperties( 870*6c119a46SAndroid Build Coastguard Worker &generatorProperties{}, 871*6c119a46SAndroid Build Coastguard Worker &codegenProperties{}, 872*6c119a46SAndroid Build Coastguard Worker ) 873*6c119a46SAndroid Build Coastguard Worker 874*6c119a46SAndroid Build Coastguard Worker android.InitDefaultsModule(module) 875*6c119a46SAndroid Build Coastguard Worker 876*6c119a46SAndroid Build Coastguard Worker return module 877*6c119a46SAndroid Build Coastguard Worker} 878