• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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