• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1package codegen
2
3import (
4	"fmt"
5
6	"android/soong/android"
7	"android/soong/rust"
8
9	"github.com/google/blueprint"
10	"github.com/google/blueprint/proptools"
11)
12
13type rustDeclarationsTagType struct {
14	blueprint.BaseDependencyTag
15}
16
17var rustDeclarationsTag = rustDeclarationsTagType{}
18
19type RustAconfigLibraryProperties struct {
20	// name of the aconfig_declarations module to generate a library for
21	Aconfig_declarations string
22
23	// default mode is "production", the other accepted modes are:
24	// "test": to generate test mode version of the library
25	// "exported": to generate exported mode version of the library
26	// "force-read-only": to generate force-read-only mode version of the library
27	// an error will be thrown if the mode is not supported
28	Mode *string
29}
30
31type aconfigDecorator struct {
32	*rust.BaseSourceProvider
33
34	Properties RustAconfigLibraryProperties
35}
36
37func NewRustAconfigLibrary(hod android.HostOrDeviceSupported) (*rust.Module, *aconfigDecorator) {
38	aconfig := &aconfigDecorator{
39		BaseSourceProvider: rust.NewSourceProvider(),
40		Properties:         RustAconfigLibraryProperties{},
41	}
42
43	module := rust.NewSourceProviderModule(android.HostAndDeviceSupported, aconfig, false, false)
44	return module, aconfig
45}
46
47// rust_aconfig_library generates aconfig rust code from the provided aconfig declaration. This module type will
48// create library variants that can be used as a crate dependency by adding it to the rlibs, dylibs, and rustlibs
49// properties of other modules.
50func RustAconfigLibraryFactory() android.Module {
51	module, _ := NewRustAconfigLibrary(android.HostAndDeviceSupported)
52	return module.Init()
53}
54
55func (a *aconfigDecorator) SourceProviderProps() []interface{} {
56	return append(a.BaseSourceProvider.SourceProviderProps(), &a.Properties)
57}
58
59func (a *aconfigDecorator) GenerateSource(ctx rust.ModuleContext, deps rust.PathDeps) android.Path {
60	generatedDir := android.PathForModuleGen(ctx)
61	generatedSource := android.PathForModuleGen(ctx, "src", "lib.rs")
62
63	declarationsModules := ctx.GetDirectDepsWithTag(rustDeclarationsTag)
64
65	if len(declarationsModules) != 1 {
66		panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
67	}
68	declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], android.AconfigDeclarationsProviderKey)
69
70	mode := proptools.StringDefault(a.Properties.Mode, "production")
71	if !isModeSupported(mode) {
72		ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
73	}
74
75	ctx.Build(pctx, android.BuildParams{
76		Rule:  rustRule,
77		Input: declarations.IntermediateCacheOutputPath,
78		Outputs: []android.WritablePath{
79			generatedSource,
80		},
81		Description: "rust_aconfig_library",
82		Args: map[string]string{
83			"gendir": generatedDir.String(),
84			"mode":   mode,
85		},
86	})
87	a.BaseSourceProvider.OutputFiles = android.Paths{generatedSource}
88
89	android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
90		ModeInfos: map[string]android.ModeInfo{
91			ctx.ModuleName(): {
92				Container: declarations.Container,
93				Mode:      mode,
94			}},
95	})
96
97	return generatedSource
98}
99
100func (a *aconfigDecorator) SourceProviderDeps(ctx rust.DepsContext, deps rust.Deps) rust.Deps {
101	deps = a.BaseSourceProvider.SourceProviderDeps(ctx, deps)
102	deps.Rustlibs = append(deps.Rustlibs, "libaconfig_storage_read_api")
103	deps.Rustlibs = append(deps.Rustlibs, "liblazy_static")
104	deps.Rustlibs = append(deps.Rustlibs, "liblogger")
105	deps.Rustlibs = append(deps.Rustlibs, "liblog_rust")
106	ctx.AddDependency(ctx.Module(), rustDeclarationsTag, a.Properties.Aconfig_declarations)
107	return deps
108}
109