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 `android:"path"` 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) GenerateAndroidBuildActions(ctx android.ModuleContext) { 97 m.outDir = android.PathForModuleGen(ctx, "") 98 99 for _, in := range android.PathsForModuleSrc(ctx, m.properties.Srcs) { 100 if !strings.HasSuffix(in.Rel(), ".mojom") { 101 ctx.PropertyErrorf("srcs", "Source is not a .mojom file: %s", in.Rel()) 102 continue 103 } 104 105 out := android.PathForModuleGen(ctx, in.Rel()) 106 m.generatedSrcs = append(m.generatedSrcs, out) 107 108 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 109 Rule: downgradeMojomTypesRule, 110 Input: in, 111 Output: out, 112 Args: map[string]string{ 113 "outDir": path.Dir(out.String()), 114 }, 115 }) 116 } 117} 118 119func (m *mojomDowngradedFiles) GeneratedHeaderDirs() android.Paths { 120 return nil 121} 122 123func (m *mojomDowngradedFiles) GeneratedDeps() android.Paths { 124 return append(android.Paths{}, m.generatedSrcs...) 125} 126 127func (m *mojomDowngradedFiles) GeneratedSourceFiles() android.Paths { 128 return append(android.Paths{}, m.generatedSrcs...) 129} 130 131func (m *mojomDowngradedFiles) Srcs() android.Paths { 132 return append(android.Paths{}, m.generatedSrcs...) 133} 134 135func mojomDowngradedFilesFactory() android.Module { 136 m := &mojomDowngradedFiles{} 137 m.AddProperties(&m.properties) 138 android.InitAndroidModule(m) 139 return m 140} 141 142type mojomPicklesProperties struct { 143 // list of input files 144 Srcs []string `android:"path"` 145} 146 147type mojomPickles struct { 148 android.ModuleBase 149 150 properties mojomPicklesProperties 151 152 generatedSrcs android.Paths 153 outDir android.Path 154} 155 156var _ genrule.SourceFileGenerator = (*mojomPickles)(nil) 157 158func (m *mojomPickles) GenerateAndroidBuildActions(ctx android.ModuleContext) { 159 m.outDir = android.PathForModuleGen(ctx, "") 160 161 for _, in := range android.PathsForModuleSrc(ctx, m.properties.Srcs) { 162 if !strings.HasSuffix(in.Rel(), ".mojom") { 163 ctx.PropertyErrorf("srcs", "Source is not a .mojom file: %s", in.Rel()) 164 continue 165 } 166 167 srcRoot := strings.TrimSuffix(in.String(), in.Rel()) 168 169 relStem := strings.TrimSuffix(in.Rel(), ".mojom") 170 171 out := android.PathForModuleGen(ctx, relStem+".p") 172 m.generatedSrcs = append(m.generatedSrcs, out) 173 174 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 175 Rule: generateMojomPicklesRule, 176 Input: in, 177 Output: out, 178 Args: map[string]string{ 179 "package": srcRoot, 180 "outDir": m.outDir.String(), 181 }, 182 }) 183 } 184} 185 186func (m *mojomPickles) GeneratedHeaderDirs() android.Paths { 187 return nil 188} 189 190func (m *mojomPickles) GeneratedDeps() android.Paths { 191 return append(android.Paths{}, m.generatedSrcs...) 192} 193 194func (m *mojomPickles) GeneratedSourceFiles() android.Paths { 195 return append(android.Paths{}, m.generatedSrcs...) 196} 197 198func (m *mojomPickles) Srcs() android.Paths { 199 return append(android.Paths{}, m.generatedSrcs...) 200} 201 202func mojomPicklesFactory() android.Module { 203 m := &mojomPickles{} 204 m.AddProperties(&m.properties) 205 android.InitAndroidModule(m) 206 return m 207} 208 209// mojomGenerationProperties are the common properties across the header, 210// source and Java source modules. 211type mojomGenerationProperties struct { 212 // list of input files 213 Srcs []string `android:"path"` 214 215 // name of the output .srcjar 216 Srcjar string 217 218 // name of the templates module 219 Templates string `android:"path"` 220 221 // Additional flags to pass to the bindings generation script 222 Flags string 223 224 // list of pickles modules that will be imported 225 Pickles []string `android:"path"` 226 227 // list of include paths 228 Includes []string 229 230 // list of typemaps modules that will be imported 231 Typemaps []string `android:"path"` 232 233 // If true, set --use_once_callback flag to the generator. 234 // This works only on C++ generation. 235 Use_once_callback bool 236} 237 238// flags generates all needed flags for the build rule. 239func (p *mojomGenerationProperties) flags(ctx android.ModuleContext) string { 240 flags := []string{} 241 242 for _, typemap := range android.PathsForModuleSrc(ctx, p.Typemaps) { 243 flags = append(flags, fmt.Sprintf("--typemap=%s", typemap.String())) 244 } 245 for _, include := range android.PathsForSource(ctx, p.Includes) { 246 flags = append(flags, fmt.Sprintf("-I=%s:%s", include, include)) 247 } 248 for _, pickle := range p.Pickles { 249 m := android.SrcIsModule(pickle) 250 if m == "" { 251 ctx.PropertyErrorf("pickles", "not a module: %q", m) 252 continue 253 } 254 module := android.GetModuleFromPathDep(ctx, m, "").(*mojomPickles) 255 flags = append(flags, fmt.Sprintf("--gen_dir=%s", module.outDir.String())) 256 } 257 if p.Flags != "" { 258 flags = append(flags, p.Flags) 259 } 260 if p.Use_once_callback { 261 flags = append(flags, "--use_once_callback") 262 } 263 264 return strings.Join(flags, " ") 265} 266 267// implicitDeps collects all dependencies of the module. 268func (p *mojomGenerationProperties) implicitDeps(ctx android.ModuleContext) android.Paths { 269 deps := android.Paths{} 270 deps = append(deps, android.PathsForModuleSrc(ctx, p.Pickles)...) 271 deps = append(deps, android.PathsForModuleSrc(ctx, p.Typemaps)...) 272 deps = append(deps, android.PathsForModuleSrc(ctx, []string{p.Templates})...) 273 return deps 274} 275 276// templateDir returns the path where the template .zips are located. 277func (p *mojomGenerationProperties) templateDir(ctx android.ModuleContext) string { 278 srcFiles := android.PathsForModuleSrc(ctx, []string{p.Templates}) 279 if len(srcFiles) == 0 { 280 ctx.PropertyErrorf("templates", "module %s does not produce any files", p.Templates) 281 return "" 282 } 283 return path.Dir(srcFiles[0].String()) 284} 285 286// mojomSrcsRuleDescription has the necessary arguments to perform one 287// invocation of generateMojomSrcsRule. 288type mojomSrcsRuleDescription struct { 289 generatedExtensions []string 290 extraFlags string 291} 292 293// generateBuildActions generates all the necessary build actions for the 294// current module. 295func (p *mojomGenerationProperties) generateBuildActions( 296 ctx android.ModuleContext, 297 mojomGenerator string, 298 descriptions []mojomSrcsRuleDescription, 299) android.Paths { 300 outDir := android.PathForModuleGen(ctx, "") 301 implicitDeps := p.implicitDeps(ctx) 302 templateDir := p.templateDir(ctx) 303 generatedSrcs := android.Paths{} 304 305 for _, in := range android.PathsForModuleSrc(ctx, p.Srcs) { 306 if !strings.HasSuffix(in.Rel(), ".mojom") { 307 ctx.PropertyErrorf("srcs", "Source is not a .mojom file: %s", in.Rel()) 308 continue 309 } 310 relStem := strings.TrimSuffix(in.Rel(), ".mojom") 311 srcRoot := strings.TrimSuffix(in.String(), in.Rel()) 312 313 for _, description := range descriptions { 314 outs := android.WritablePaths{} 315 for _, ext := range description.generatedExtensions { 316 out := android.PathForModuleGen(ctx, relStem+ext) 317 outs = append(outs, out) 318 generatedSrcs = append(generatedSrcs, out) 319 } 320 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 321 Rule: generateMojomSrcsRule, 322 Input: in, 323 Implicits: implicitDeps, 324 Outputs: outs, 325 Args: map[string]string{ 326 "mojomGenerator": mojomGenerator, 327 "package": srcRoot, 328 "flags": fmt.Sprintf("%s %s", p.flags(ctx), description.extraFlags), 329 "outDir": outDir.String(), 330 "templateDir": templateDir, 331 }, 332 }) 333 } 334 } 335 336 return generatedSrcs 337} 338 339// mojomHeaders generates all the .h files for a .mojom source. 340type mojomHeaders struct { 341 android.ModuleBase 342 343 properties mojomGenerationProperties 344 345 exportedHeaderDirs android.Paths 346 generatedSrcs android.Paths 347} 348 349var _ genrule.SourceFileGenerator = (*mojomHeaders)(nil) 350 351func (m *mojomHeaders) GenerateAndroidBuildActions(ctx android.ModuleContext) { 352 m.generatedSrcs = m.properties.generateBuildActions( 353 ctx, 354 "c++", 355 []mojomSrcsRuleDescription{ 356 { 357 generatedExtensions: []string{".mojom.h"}, 358 extraFlags: "", 359 }, 360 { 361 generatedExtensions: []string{".mojom-shared.h", ".mojom-shared-internal.h"}, 362 extraFlags: "--generate_non_variant_code", 363 }, 364 { 365 generatedExtensions: []string{".mojom-shared-message-ids.h"}, 366 extraFlags: "--generate_message_ids --generate_non_variant_code", 367 }, 368 }, 369 ) 370 m.exportedHeaderDirs = append(m.exportedHeaderDirs, android.PathForModuleGen(ctx, "")) 371} 372 373func (m *mojomHeaders) GeneratedHeaderDirs() android.Paths { 374 return m.exportedHeaderDirs 375} 376 377func (m *mojomHeaders) GeneratedDeps() android.Paths { 378 return append(android.Paths{}, m.generatedSrcs...) 379} 380 381func (m *mojomHeaders) GeneratedSourceFiles() android.Paths { 382 return append(android.Paths{}, m.generatedSrcs...) 383} 384 385func (m *mojomHeaders) Srcs() android.Paths { 386 return append(android.Paths{}, m.generatedSrcs...) 387} 388 389func mojomHeadersFactory() android.Module { 390 m := &mojomHeaders{} 391 m.AddProperties(&m.properties) 392 android.InitAndroidModule(m) 393 return m 394} 395 396// mojomHeaders generates all the .cc files for a .mojom source. 397type mojomSrcs struct { 398 android.ModuleBase 399 400 properties mojomGenerationProperties 401 402 generatedSrcs android.Paths 403} 404 405var _ genrule.SourceFileGenerator = (*mojomSrcs)(nil) 406 407func (m *mojomSrcs) GenerateAndroidBuildActions(ctx android.ModuleContext) { 408 m.generatedSrcs = m.properties.generateBuildActions( 409 ctx, 410 "c++", 411 []mojomSrcsRuleDescription{ 412 { 413 generatedExtensions: []string{".mojom.cc"}, 414 extraFlags: "", 415 }, 416 { 417 generatedExtensions: []string{".mojom-shared.cc"}, 418 extraFlags: "--generate_non_variant_code", 419 }, 420 }, 421 ) 422} 423 424func (m *mojomSrcs) GeneratedHeaderDirs() android.Paths { 425 return nil 426} 427 428func (m *mojomSrcs) GeneratedDeps() android.Paths { 429 return append(android.Paths{}, m.generatedSrcs...) 430} 431 432func (m *mojomSrcs) GeneratedSourceFiles() android.Paths { 433 return append(android.Paths{}, m.generatedSrcs...) 434} 435 436func (m *mojomSrcs) Srcs() android.Paths { 437 return append(android.Paths{}, m.generatedSrcs...) 438} 439 440func mojomSrcsFactory() android.Module { 441 m := &mojomSrcs{} 442 m.AddProperties(&m.properties) 443 android.InitAndroidModule(m) 444 return m 445} 446 447// mojomHeaders generates the .srcjar file for a set of .mojom source. 448type mojomSrcjar struct { 449 android.ModuleBase 450 451 properties mojomGenerationProperties 452 453 outDir android.Path 454 generatedSrcs android.Paths 455} 456 457var _ genrule.SourceFileGenerator = (*mojomSrcjar)(nil) 458 459func (m *mojomSrcjar) GenerateAndroidBuildActions(ctx android.ModuleContext) { 460 srcjars := m.properties.generateBuildActions( 461 ctx, 462 "java", 463 []mojomSrcsRuleDescription{ 464 { 465 generatedExtensions: []string{".mojom.srcjar"}, 466 extraFlags: "", 467 }, 468 }, 469 ) 470 471 out := android.PathForModuleGen(ctx, m.properties.Srcjar) 472 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 473 Rule: mergeSrcjarsRule, 474 Inputs: srcjars, 475 Output: out, 476 }) 477 m.generatedSrcs = append(m.generatedSrcs, out) 478} 479 480func (m *mojomSrcjar) GeneratedHeaderDirs() android.Paths { 481 return nil 482} 483 484func (m *mojomSrcjar) GeneratedDeps() android.Paths { 485 return append(android.Paths{}, m.generatedSrcs...) 486} 487 488func (m *mojomSrcjar) GeneratedSourceFiles() android.Paths { 489 return append(android.Paths{}, m.generatedSrcs...) 490} 491 492func (m *mojomSrcjar) Srcs() android.Paths { 493 return append(android.Paths{}, m.generatedSrcs...) 494} 495 496func mojomSrcjarFactory() android.Module { 497 m := &mojomSrcjar{} 498 m.AddProperties(&m.properties) 499 android.InitAndroidModule(m) 500 return m 501} 502