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