1package libchrome 2 3import ( 4 "fmt" 5 "path" 6 "strings" 7 8 "android/soong/android" 9 "android/soong/genrule" 10 11 "github.com/google/blueprint" 12) 13 14func init() { 15 android.RegisterModuleType("generate_mojom_pickles", mojomPicklesFactory) 16 android.RegisterModuleType("generate_mojom_headers", mojomHeadersFactory) 17 android.RegisterModuleType("generate_mojom_srcs", mojomSrcsFactory) 18 android.RegisterModuleType("generate_mojom_srcjar", mojomSrcjarFactory) 19} 20 21var ( 22 pctx = android.NewPackageContext("android/soong/external/libchrome") 23 24 mojomBindingsGenerator = pctx.HostBinToolVariable("mojomBindingsGenerator", "mojom_bindings_generator") 25 mergeZips = pctx.HostBinToolVariable("mergeZips", "merge_zips") 26 27 generateMojomPicklesRule = pctx.StaticRule("generateMojomPicklesRule", blueprint.RuleParams{ 28 Command: `${mojomBindingsGenerator} 29 --use_bundled_pylibs parse 30 -d ${package} 31 ${flags} 32 -o ${outDir} 33 ${in}`, 34 CommandDeps: []string{ 35 "${mojomBindingsGenerator}", 36 }, 37 Description: "Mojo pickles generation $in => $out", 38 Restat: true, 39 }, "package", "flags", "outDir") 40 41 generateMojomSrcsRule = pctx.StaticRule("generateMojomSrcsRule", blueprint.RuleParams{ 42 Command: `${mojomBindingsGenerator} 43 --use_bundled_pylibs generate 44 -o ${outDir} 45 -I=${package}:${package} 46 -d ${package} 47 ${flags} 48 --bytecode_path=${templateDir} 49 --generators=${mojomGenerator} 50 --use_new_wrapper_types 51 ${in}`, 52 CommandDeps: []string{ 53 "${mojomBindingsGenerator}", 54 }, 55 Description: "Mojo sources generation $in => $out", 56 Restat: true, 57 }, "mojomGenerator", "package", "flags", "outDir", "templateDir") 58 59 mergeSrcjarsRule = pctx.StaticRule("mergeSrcjarsRule", blueprint.RuleParams{ 60 Command: "${mergeZips} ${out} ${in}", 61 CommandDeps: []string{ 62 "${mergeZips}", 63 }, 64 Description: "Merge .srcjars $in => $out", 65 }) 66) 67 68type mojomPicklesProperties struct { 69 // list of input files 70 Srcs []string 71} 72 73type mojomPickles struct { 74 android.ModuleBase 75 76 properties mojomPicklesProperties 77 78 generatedSrcs android.Paths 79 outDir android.Path 80} 81 82var _ genrule.SourceFileGenerator = (*mojomPickles)(nil) 83 84func (m *mojomPickles) DepsMutator(ctx android.BottomUpMutatorContext) { 85 android.ExtractSourcesDeps(ctx, m.properties.Srcs) 86} 87 88func (m *mojomPickles) GenerateAndroidBuildActions(ctx android.ModuleContext) { 89 m.outDir = android.PathForModuleGen(ctx, "") 90 91 packagePath := android.PathForModuleSrc(ctx, "") 92 93 for _, in := range ctx.ExpandSources(m.properties.Srcs, nil) { 94 if !strings.HasSuffix(in.Rel(), ".mojom") { 95 ctx.PropertyErrorf("srcs", "Source is not a .mojom file: %s", in.Rel()) 96 continue 97 } 98 relStem := strings.TrimSuffix(in.Rel(), ".mojom") 99 100 out := android.PathForModuleGen(ctx, relStem+".p") 101 m.generatedSrcs = append(m.generatedSrcs, out) 102 103 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 104 Rule: generateMojomPicklesRule, 105 Input: in, 106 Output: out, 107 Args: map[string]string{ 108 "package": packagePath.Rel(), 109 "outDir": m.outDir.String(), 110 "flags": fmt.Sprintf("-I=%s:%s", packagePath, packagePath), 111 }, 112 }) 113 } 114} 115 116func (m *mojomPickles) GeneratedHeaderDirs() android.Paths { 117 return nil 118} 119 120func (m *mojomPickles) GeneratedDeps() android.Paths { 121 return append(android.Paths{}, m.generatedSrcs...) 122} 123 124func (m *mojomPickles) GeneratedSourceFiles() android.Paths { 125 return append(android.Paths{}, m.generatedSrcs...) 126} 127 128func (m *mojomPickles) Srcs() android.Paths { 129 return append(android.Paths{}, m.generatedSrcs...) 130} 131 132func mojomPicklesFactory() android.Module { 133 m := &mojomPickles{} 134 m.AddProperties(&m.properties) 135 android.InitAndroidModule(m) 136 return m 137} 138 139// mojomGenerationProperties are the common properties across the header, 140// source and Java source modules. 141type mojomGenerationProperties struct { 142 // list of input files 143 Srcs []string 144 145 // name of the output .srcjar 146 Srcjar string 147 148 // name of the templates module 149 Templates string 150 151 // Additional flags to pass to the bindings generation script 152 Flags string 153 154 // list of pickles modules that will be imported 155 Pickles []string 156 157 // list of include paths 158 Includes []string 159 160 // list of typemaps modules that will be imported 161 Typemaps []string 162 163 // If true, set --use_once_callback flag to the generator. 164 // This works only on C++ generation. 165 Use_once_callback bool 166} 167 168// extractSources adds any necessary dependencies to satisfy filegroup or 169// generated sources modules listed in the properties using ":module" syntax, 170// if any. 171func (p *mojomGenerationProperties) extractSources(ctx android.BottomUpMutatorContext) { 172 android.ExtractSourcesDeps(ctx, p.Srcs) 173 android.ExtractSourcesDeps(ctx, p.Typemaps) 174 android.ExtractSourcesDeps(ctx, p.Pickles) 175 android.ExtractSourceDeps(ctx, &p.Templates) 176} 177 178// flags generates all needed flags for the build rule. 179func (p *mojomGenerationProperties) flags(ctx android.ModuleContext) string { 180 flags := []string{} 181 182 for _, typemap := range ctx.ExpandSources(p.Typemaps, nil) { 183 flags = append(flags, fmt.Sprintf("--typemap=%s", typemap.String())) 184 } 185 for _, include := range android.PathsForSource(ctx, p.Includes) { 186 flags = append(flags, fmt.Sprintf("-I=%s:%s", include, include)) 187 } 188 for _, pickle := range p.Pickles { 189 m := android.SrcIsModule(pickle) 190 if m == "" { 191 ctx.PropertyErrorf("pickles", "not a module: %q", m) 192 continue 193 } 194 module := ctx.GetDirectDepWithTag(m, android.SourceDepTag).(*mojomPickles) 195 flags = append(flags, fmt.Sprintf("--gen_dir=%s", module.outDir.String())) 196 } 197 if p.Flags != "" { 198 flags = append(flags, p.Flags) 199 } 200 if p.Use_once_callback { 201 flags = append(flags, "--use_once_callback") 202 } 203 204 return strings.Join(flags, " ") 205} 206 207// implicitDeps collects all dependencies of the module. 208func (p *mojomGenerationProperties) implicitDeps(ctx android.ModuleContext) android.Paths { 209 deps := android.Paths{} 210 deps = append(deps, ctx.ExpandSources(p.Pickles, nil)...) 211 deps = append(deps, ctx.ExpandSources(p.Typemaps, nil)...) 212 deps = append(deps, ctx.ExpandSources([]string{p.Templates}, nil)...) 213 return deps 214} 215 216// templateDir returns the path where the template .zips are located. 217func (p *mojomGenerationProperties) templateDir(ctx android.ModuleContext) string { 218 srcFiles := ctx.ExpandSources([]string{p.Templates}, nil) 219 if len(srcFiles) == 0 { 220 ctx.PropertyErrorf("templates", "module %s does not produce any files", p.Templates) 221 return "" 222 } 223 return path.Dir(srcFiles[0].String()) 224} 225 226// mojomSrcsRuleDescription has the necessary arguments to perform one 227// invocation of generateMojomSrcsRule. 228type mojomSrcsRuleDescription struct { 229 generatedExtensions []string 230 extraFlags string 231} 232 233// generateBuildActions generates all the necessary build actions for the 234// current module. 235func (p *mojomGenerationProperties) generateBuildActions( 236 ctx android.ModuleContext, 237 mojomGenerator string, 238 descriptions []mojomSrcsRuleDescription, 239) android.Paths { 240 packageName := android.PathForModuleSrc(ctx, "").Rel() 241 outDir := android.PathForModuleGen(ctx, "") 242 implicitDeps := p.implicitDeps(ctx) 243 templateDir := p.templateDir(ctx) 244 generatedSrcs := android.Paths{} 245 246 for _, in := range ctx.ExpandSources(p.Srcs, nil) { 247 if !strings.HasSuffix(in.Rel(), ".mojom") { 248 ctx.PropertyErrorf("srcs", "Source is not a .mojom file: %s", in.Rel()) 249 continue 250 } 251 relStem := strings.TrimSuffix(in.Rel(), ".mojom") 252 253 for _, description := range descriptions { 254 outs := android.WritablePaths{} 255 for _, ext := range description.generatedExtensions { 256 out := android.PathForModuleGen(ctx, relStem+ext) 257 outs = append(outs, out) 258 generatedSrcs = append(generatedSrcs, out) 259 } 260 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 261 Rule: generateMojomSrcsRule, 262 Input: in, 263 Implicits: implicitDeps, 264 Outputs: outs, 265 Args: map[string]string{ 266 "mojomGenerator": mojomGenerator, 267 "package": packageName, 268 "flags": fmt.Sprintf("%s %s", p.flags(ctx), description.extraFlags), 269 "outDir": outDir.String(), 270 "templateDir": templateDir, 271 }, 272 }) 273 } 274 } 275 276 return generatedSrcs 277} 278 279// mojomHeaders generates all the .h files for a .mojom source. 280type mojomHeaders struct { 281 android.ModuleBase 282 283 properties mojomGenerationProperties 284 285 exportedHeaderDirs android.Paths 286 generatedSrcs android.Paths 287} 288 289var _ genrule.SourceFileGenerator = (*mojomHeaders)(nil) 290 291func (m *mojomHeaders) DepsMutator(ctx android.BottomUpMutatorContext) { 292 m.properties.extractSources(ctx) 293} 294 295func (m *mojomHeaders) GenerateAndroidBuildActions(ctx android.ModuleContext) { 296 m.generatedSrcs = m.properties.generateBuildActions( 297 ctx, 298 "c++", 299 []mojomSrcsRuleDescription{ 300 { 301 generatedExtensions: []string{".mojom.h"}, 302 extraFlags: "", 303 }, 304 { 305 generatedExtensions: []string{".mojom-shared.h", ".mojom-shared-internal.h"}, 306 extraFlags: "--generate_non_variant_code", 307 }, 308 { 309 generatedExtensions: []string{".mojom-shared-message-ids.h"}, 310 extraFlags: "--generate_message_ids --generate_non_variant_code", 311 }, 312 }, 313 ) 314 m.exportedHeaderDirs = append(m.exportedHeaderDirs, android.PathForModuleGen(ctx, "")) 315} 316 317func (m *mojomHeaders) GeneratedHeaderDirs() android.Paths { 318 return m.exportedHeaderDirs 319} 320 321func (m *mojomHeaders) GeneratedDeps() android.Paths { 322 return append(android.Paths{}, m.generatedSrcs...) 323} 324 325func (m *mojomHeaders) GeneratedSourceFiles() android.Paths { 326 return append(android.Paths{}, m.generatedSrcs...) 327} 328 329func (m *mojomHeaders) Srcs() android.Paths { 330 return append(android.Paths{}, m.generatedSrcs...) 331} 332 333func mojomHeadersFactory() android.Module { 334 m := &mojomHeaders{} 335 m.AddProperties(&m.properties) 336 android.InitAndroidModule(m) 337 return m 338} 339 340// mojomHeaders generates all the .cc files for a .mojom source. 341type mojomSrcs struct { 342 android.ModuleBase 343 344 properties mojomGenerationProperties 345 346 generatedSrcs android.Paths 347} 348 349var _ genrule.SourceFileGenerator = (*mojomSrcs)(nil) 350 351func (m *mojomSrcs) DepsMutator(ctx android.BottomUpMutatorContext) { 352 m.properties.extractSources(ctx) 353} 354 355func (m *mojomSrcs) GenerateAndroidBuildActions(ctx android.ModuleContext) { 356 m.generatedSrcs = m.properties.generateBuildActions( 357 ctx, 358 "c++", 359 []mojomSrcsRuleDescription{ 360 { 361 generatedExtensions: []string{".mojom.cc"}, 362 extraFlags: "", 363 }, 364 { 365 generatedExtensions: []string{".mojom-shared.cc"}, 366 extraFlags: "--generate_non_variant_code", 367 }, 368 }, 369 ) 370} 371 372func (m *mojomSrcs) GeneratedHeaderDirs() android.Paths { 373 return nil 374} 375 376func (m *mojomSrcs) GeneratedDeps() android.Paths { 377 return append(android.Paths{}, m.generatedSrcs...) 378} 379 380func (m *mojomSrcs) GeneratedSourceFiles() android.Paths { 381 return append(android.Paths{}, m.generatedSrcs...) 382} 383 384func (m *mojomSrcs) Srcs() android.Paths { 385 return append(android.Paths{}, m.generatedSrcs...) 386} 387 388func mojomSrcsFactory() android.Module { 389 m := &mojomSrcs{} 390 m.AddProperties(&m.properties) 391 android.InitAndroidModule(m) 392 return m 393} 394 395// mojomHeaders generates the .srcjar file for a set of .mojom source. 396type mojomSrcjar struct { 397 android.ModuleBase 398 399 properties mojomGenerationProperties 400 401 outDir android.Path 402 generatedSrcs android.Paths 403} 404 405var _ genrule.SourceFileGenerator = (*mojomSrcjar)(nil) 406 407func (m *mojomSrcjar) DepsMutator(ctx android.BottomUpMutatorContext) { 408 m.properties.extractSources(ctx) 409} 410 411func (m *mojomSrcjar) GenerateAndroidBuildActions(ctx android.ModuleContext) { 412 srcjars := m.properties.generateBuildActions( 413 ctx, 414 "java", 415 []mojomSrcsRuleDescription{ 416 { 417 generatedExtensions: []string{".mojom.srcjar"}, 418 extraFlags: "", 419 }, 420 }, 421 ) 422 423 out := android.PathForModuleGen(ctx, m.properties.Srcjar) 424 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 425 Rule: mergeSrcjarsRule, 426 Inputs: srcjars, 427 Output: out, 428 }) 429 m.generatedSrcs = append(m.generatedSrcs, out) 430} 431 432func (m *mojomSrcjar) GeneratedHeaderDirs() android.Paths { 433 return nil 434} 435 436func (m *mojomSrcjar) GeneratedDeps() android.Paths { 437 return append(android.Paths{}, m.generatedSrcs...) 438} 439 440func (m *mojomSrcjar) GeneratedSourceFiles() android.Paths { 441 return append(android.Paths{}, m.generatedSrcs...) 442} 443 444func (m *mojomSrcjar) Srcs() android.Paths { 445 return append(android.Paths{}, m.generatedSrcs...) 446} 447 448func mojomSrcjarFactory() android.Module { 449 m := &mojomSrcjar{} 450 m.AddProperties(&m.properties) 451 android.InitAndroidModule(m) 452 return m 453} 454