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