Loading android/module.go +59 −3 Original line number Diff line number Diff line Loading @@ -915,6 +915,10 @@ type ModuleBase struct { // moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will // be included in the final module-info.json produced by Make. moduleInfoJSON *ModuleInfoJSON // outputFiles stores the output of a module by tag and is used to set // the OutputFilesProvider in GenerateBuildActions outputFiles OutputFilesInfo } func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { Loading Loading @@ -1996,6 +2000,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.buildParams = ctx.buildParams m.ruleParams = ctx.ruleParams m.variables = ctx.variables if m.outputFiles.DefaultOutputFiles != nil || m.outputFiles.TaggedOutputFiles != nil { SetProvider(ctx, OutputFilesProvider, m.outputFiles) } } func SetJarJarPrefixHandler(handler func(ModuleContext)) { Loading Loading @@ -2445,11 +2453,15 @@ func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) P } func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != nil { return outputFilesFromProvider, err } if outputFileProducer, ok := module.(OutputFileProducer); ok { paths, err := outputFileProducer.OutputFiles(tag) if err != nil { return nil, fmt.Errorf("failed to get output file from module %q: %s", pathContextName(ctx, module), err.Error()) return nil, fmt.Errorf("failed to get output file from module %q at tag %q: %s", pathContextName(ctx, module), tag, err.Error()) } return paths, nil } else if sourceFileProducer, ok := module.(SourceFileProducer); ok { Loading @@ -2459,9 +2471,53 @@ func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) paths := sourceFileProducer.Srcs() return paths, nil } else { return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module)) return nil, fmt.Errorf("module %q is not an OutputFileProducer or SourceFileProducer", pathContextName(ctx, module)) } } // This method uses OutputFilesProvider for output files // *inter-module-communication*. // If mctx module is the same as the param module the output files are obtained // from outputFiles property of module base, to avoid both setting and // reading OutputFilesProvider before GenerateBuildActions is finished. Also // only empty-string-tag is supported in this case. // If a module doesn't have the OutputFilesProvider, nil is returned. func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { // TODO: support OutputFilesProvider for singletons mctx, ok := ctx.(ModuleContext) if !ok { return nil, nil } if mctx.Module() != module { if outputFilesProvider, ok := OtherModuleProvider(mctx, module, OutputFilesProvider); ok { if tag == "" { return outputFilesProvider.DefaultOutputFiles, nil } else if taggedOutputFiles, hasTag := outputFilesProvider.TaggedOutputFiles[tag]; hasTag { return taggedOutputFiles, nil } else { return nil, fmt.Errorf("unsupported module reference tag %q", tag) } } } else { if tag == "" { return mctx.Module().base().outputFiles.DefaultOutputFiles, nil } else { return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag) } } // TODO: Add a check for param module not having OutputFilesProvider set return nil, nil } type OutputFilesInfo struct { // default output files when tag is an empty string "" DefaultOutputFiles Paths // the corresponding output files for given tags TaggedOutputFiles map[string]Paths } var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]() // Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to // specify that they can be used as a tool by a genrule module. Loading android/module_context.go +19 −0 Original line number Diff line number Diff line Loading @@ -212,6 +212,10 @@ type ModuleContext interface { // GenerateAndroidBuildActions. If it is called then the struct will be written out and included in // the module-info.json generated by Make, and Make will not generate its own data for this module. ModuleInfoJSON() *ModuleInfoJSON // SetOutputFiles stores the outputFiles to outputFiles property, which is used // to set the OutputFilesProvider later. SetOutputFiles(outputFiles Paths, tag string) } type moduleContext struct { Loading Loading @@ -707,6 +711,21 @@ func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON { return moduleInfoJSON } func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) { if tag == "" { if len(m.module.base().outputFiles.DefaultOutputFiles) > 0 { m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName()) } m.module.base().outputFiles.DefaultOutputFiles = outputFiles } else { if _, exists := m.module.base().outputFiles.TaggedOutputFiles[tag]; exists { m.ModuleErrorf("Module %s OutputFiles at tag %s cannot be overwritten", m.ModuleName(), tag) } else { m.module.base().outputFiles.TaggedOutputFiles[tag] = outputFiles } } } // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must // be tagged with `android:"path" to support automatic source module dependency resolution. // Loading android/paths.go +6 −12 Original line number Diff line number Diff line Loading @@ -565,21 +565,15 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag if aModule, ok := module.(Module); ok && !aModule.Enabled(ctx) { return nil, missingDependencyError{[]string{moduleName}} } if outProducer, ok := module.(OutputFileProducer); ok { outputFiles, err := outProducer.OutputFiles(tag) if err != nil { return nil, fmt.Errorf("path dependency %q: %s", path, err) } return outputFiles, nil } else if tag != "" { return nil, fmt.Errorf("path dependency %q is not an output file producing module", path) } else if goBinary, ok := module.(bootstrap.GoBinaryTool); ok { if goBinary, ok := module.(bootstrap.GoBinaryTool); ok && tag == "" { goBinaryPath := PathForGoBinary(ctx, goBinary) return Paths{goBinaryPath}, nil } else if srcProducer, ok := module.(SourceFileProducer); ok { return srcProducer.Srcs(), nil } outputFiles, err := outputFilesForModule(ctx, module, tag) if outputFiles != nil && err == nil { return outputFiles, nil } else { return nil, fmt.Errorf("path dependency %q is not a source file producing module", path) return nil, err } } Loading apex/apex.go +1 −1 Original line number Diff line number Diff line Loading @@ -2112,7 +2112,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } case bpfTag: if bpfProgram, ok := child.(bpf.BpfModule); ok { filesToCopy, _ := bpfProgram.OutputFiles("") filesToCopy := android.OutputFilesForModule(ctx, bpfProgram, "") apex_sub_dir := bpfProgram.SubDir() for _, bpfFile := range filesToCopy { vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram)) Loading bpf/bpf.go +2 −15 Original line number Diff line number Diff line Loading @@ -65,8 +65,6 @@ var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildC type BpfModule interface { android.Module OutputFiles(tag string) (android.Paths, error) // Returns the sub install directory if the bpf module is included by apex. SubDir() string } Loading Loading @@ -213,6 +211,8 @@ func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) { } android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()}) ctx.SetOutputFiles(bpf.objs, "") } func (bpf *bpf) AndroidMk() android.AndroidMkData { Loading Loading @@ -255,23 +255,10 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData { } } // Implements OutputFileFileProducer interface so that the obj output can be used in the data property // of other modules. func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) { switch tag { case "": return bpf.objs, nil default: return nil, fmt.Errorf("unsupported module reference tag %q", tag) } } func (bpf *bpf) SubDir() string { return bpf.properties.Sub_dir } var _ android.OutputFileProducer = (*bpf)(nil) func BpfFactory() android.Module { module := &bpf{} Loading Loading
android/module.go +59 −3 Original line number Diff line number Diff line Loading @@ -915,6 +915,10 @@ type ModuleBase struct { // moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will // be included in the final module-info.json produced by Make. moduleInfoJSON *ModuleInfoJSON // outputFiles stores the output of a module by tag and is used to set // the OutputFilesProvider in GenerateBuildActions outputFiles OutputFilesInfo } func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { Loading Loading @@ -1996,6 +2000,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.buildParams = ctx.buildParams m.ruleParams = ctx.ruleParams m.variables = ctx.variables if m.outputFiles.DefaultOutputFiles != nil || m.outputFiles.TaggedOutputFiles != nil { SetProvider(ctx, OutputFilesProvider, m.outputFiles) } } func SetJarJarPrefixHandler(handler func(ModuleContext)) { Loading Loading @@ -2445,11 +2453,15 @@ func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) P } func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != nil { return outputFilesFromProvider, err } if outputFileProducer, ok := module.(OutputFileProducer); ok { paths, err := outputFileProducer.OutputFiles(tag) if err != nil { return nil, fmt.Errorf("failed to get output file from module %q: %s", pathContextName(ctx, module), err.Error()) return nil, fmt.Errorf("failed to get output file from module %q at tag %q: %s", pathContextName(ctx, module), tag, err.Error()) } return paths, nil } else if sourceFileProducer, ok := module.(SourceFileProducer); ok { Loading @@ -2459,9 +2471,53 @@ func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) paths := sourceFileProducer.Srcs() return paths, nil } else { return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module)) return nil, fmt.Errorf("module %q is not an OutputFileProducer or SourceFileProducer", pathContextName(ctx, module)) } } // This method uses OutputFilesProvider for output files // *inter-module-communication*. // If mctx module is the same as the param module the output files are obtained // from outputFiles property of module base, to avoid both setting and // reading OutputFilesProvider before GenerateBuildActions is finished. Also // only empty-string-tag is supported in this case. // If a module doesn't have the OutputFilesProvider, nil is returned. func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { // TODO: support OutputFilesProvider for singletons mctx, ok := ctx.(ModuleContext) if !ok { return nil, nil } if mctx.Module() != module { if outputFilesProvider, ok := OtherModuleProvider(mctx, module, OutputFilesProvider); ok { if tag == "" { return outputFilesProvider.DefaultOutputFiles, nil } else if taggedOutputFiles, hasTag := outputFilesProvider.TaggedOutputFiles[tag]; hasTag { return taggedOutputFiles, nil } else { return nil, fmt.Errorf("unsupported module reference tag %q", tag) } } } else { if tag == "" { return mctx.Module().base().outputFiles.DefaultOutputFiles, nil } else { return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag) } } // TODO: Add a check for param module not having OutputFilesProvider set return nil, nil } type OutputFilesInfo struct { // default output files when tag is an empty string "" DefaultOutputFiles Paths // the corresponding output files for given tags TaggedOutputFiles map[string]Paths } var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]() // Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to // specify that they can be used as a tool by a genrule module. Loading
android/module_context.go +19 −0 Original line number Diff line number Diff line Loading @@ -212,6 +212,10 @@ type ModuleContext interface { // GenerateAndroidBuildActions. If it is called then the struct will be written out and included in // the module-info.json generated by Make, and Make will not generate its own data for this module. ModuleInfoJSON() *ModuleInfoJSON // SetOutputFiles stores the outputFiles to outputFiles property, which is used // to set the OutputFilesProvider later. SetOutputFiles(outputFiles Paths, tag string) } type moduleContext struct { Loading Loading @@ -707,6 +711,21 @@ func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON { return moduleInfoJSON } func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) { if tag == "" { if len(m.module.base().outputFiles.DefaultOutputFiles) > 0 { m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName()) } m.module.base().outputFiles.DefaultOutputFiles = outputFiles } else { if _, exists := m.module.base().outputFiles.TaggedOutputFiles[tag]; exists { m.ModuleErrorf("Module %s OutputFiles at tag %s cannot be overwritten", m.ModuleName(), tag) } else { m.module.base().outputFiles.TaggedOutputFiles[tag] = outputFiles } } } // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must // be tagged with `android:"path" to support automatic source module dependency resolution. // Loading
android/paths.go +6 −12 Original line number Diff line number Diff line Loading @@ -565,21 +565,15 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag if aModule, ok := module.(Module); ok && !aModule.Enabled(ctx) { return nil, missingDependencyError{[]string{moduleName}} } if outProducer, ok := module.(OutputFileProducer); ok { outputFiles, err := outProducer.OutputFiles(tag) if err != nil { return nil, fmt.Errorf("path dependency %q: %s", path, err) } return outputFiles, nil } else if tag != "" { return nil, fmt.Errorf("path dependency %q is not an output file producing module", path) } else if goBinary, ok := module.(bootstrap.GoBinaryTool); ok { if goBinary, ok := module.(bootstrap.GoBinaryTool); ok && tag == "" { goBinaryPath := PathForGoBinary(ctx, goBinary) return Paths{goBinaryPath}, nil } else if srcProducer, ok := module.(SourceFileProducer); ok { return srcProducer.Srcs(), nil } outputFiles, err := outputFilesForModule(ctx, module, tag) if outputFiles != nil && err == nil { return outputFiles, nil } else { return nil, fmt.Errorf("path dependency %q is not a source file producing module", path) return nil, err } } Loading
apex/apex.go +1 −1 Original line number Diff line number Diff line Loading @@ -2112,7 +2112,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } case bpfTag: if bpfProgram, ok := child.(bpf.BpfModule); ok { filesToCopy, _ := bpfProgram.OutputFiles("") filesToCopy := android.OutputFilesForModule(ctx, bpfProgram, "") apex_sub_dir := bpfProgram.SubDir() for _, bpfFile := range filesToCopy { vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram)) Loading
bpf/bpf.go +2 −15 Original line number Diff line number Diff line Loading @@ -65,8 +65,6 @@ var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildC type BpfModule interface { android.Module OutputFiles(tag string) (android.Paths, error) // Returns the sub install directory if the bpf module is included by apex. SubDir() string } Loading Loading @@ -213,6 +211,8 @@ func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) { } android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()}) ctx.SetOutputFiles(bpf.objs, "") } func (bpf *bpf) AndroidMk() android.AndroidMkData { Loading Loading @@ -255,23 +255,10 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData { } } // Implements OutputFileFileProducer interface so that the obj output can be used in the data property // of other modules. func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) { switch tag { case "": return bpf.objs, nil default: return nil, fmt.Errorf("unsupported module reference tag %q", tag) } } func (bpf *bpf) SubDir() string { return bpf.properties.Sub_dir } var _ android.OutputFileProducer = (*bpf)(nil) func BpfFactory() android.Module { module := &bpf{} Loading