• 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 `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