Loading android/base_module_context.go +20 −16 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ type BaseModuleContext interface { // GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if // none exists. It panics if the dependency does not have the specified tag. It skips any // dependencies that are not an android.Module. GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module // GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified // name, or nil if none exists. If there are multiple dependencies on the same module it returns Loading @@ -129,13 +129,14 @@ type BaseModuleContext interface { // function, it may be invalidated by future mutators. VisitDirectDeps(visit func(Module)) // VisitDirectDeps calls visit for each direct dependency. If there are multiple // VisitDirectDepsProxy calls visit for each direct dependency. If there are multiple // direct dependencies on the same module visit will be called multiple times on that module // and OtherModuleDependencyTag will return a different tag for each. // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the // dependencies are disabled. // // The Module passed to the visit function should not be retained outside of the visit // The ModuleProxy passed to the visit function should not be retained outside of the visit // function, it may be invalidated by future mutators. VisitDirectDepsAllowDisabled(visit func(Module)) VisitDirectDepsProxy(visit func(proxy ModuleProxy)) // VisitDirectDepsProxyAllowDisabled calls visit for each direct dependency. If there are // multiple direct dependencies on the same module visit will be called multiple times on Loading Loading @@ -261,7 +262,9 @@ func (b *baseModuleContext) EqualModules(m1, m2 Module) bool { func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { return b.bp.OtherModuleName(getWrappedModule(m)) } func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) } func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(getWrappedModule(m)) } func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) { b.bp.OtherModuleErrorf(m, fmt, args...) } Loading Loading @@ -298,8 +301,11 @@ func (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value b.bp.SetProvider(provider, value) } func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { return b.bp.GetDirectDepWithTag(name, tag) func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module { if module := b.bp.GetDirectDepWithTag(name, tag); module != nil { return module.(Module) } return nil } func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext { Loading Loading @@ -464,18 +470,16 @@ func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) { }) } func (b *baseModuleContext) VisitDirectDepsAllowDisabled(visit func(Module)) { b.bp.VisitDirectDeps(func(module blueprint.Module) { visit(module.(Module)) func (b *baseModuleContext) VisitDirectDepsProxy(visit func(ModuleProxy)) { b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) { if aModule := b.validateAndroidModuleProxy(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { visit(*aModule) } }) } func (b *baseModuleContext) VisitDirectDepsProxyAllowDisabled(visit func(proxy ModuleProxy)) { b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) { visit(ModuleProxy{ module: module, }) }) b.bp.VisitDirectDepsProxy(visitProxyAdaptor(visit)) } func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { Loading android/module.go +37 −20 Original line number Diff line number Diff line Loading @@ -1834,6 +1834,12 @@ type InstallFilesInfo struct { var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]() type SourceFilesInfo struct { Srcs Paths } var SourceFilesInfoKey = blueprint.NewProvider[SourceFilesInfo]() type FinalModuleBuildTargetsInfo struct { // Used by buildTargetSingleton to create checkbuild and per-directory build targets // Only set on the final variant of each module Loading Loading @@ -2038,6 +2044,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) ctx.GetMissingDependencies() } if sourceFileProducer, ok := m.module.(SourceFileProducer); ok { SetProvider(ctx, SourceFilesInfoKey, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) } if ctx.IsFinalModule(m.module) { m.generateModuleTarget(ctx) if ctx.Failed() { Loading Loading @@ -2634,7 +2644,7 @@ type SourceFileProducer interface { // OutputFilesForModule returns the output file paths with the given tag. On error, including if the // module produced zero paths, it reports errors to the ctx and returns nil. func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths { func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) Loading @@ -2645,7 +2655,7 @@ func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) // OutputFileForModule returns the output file paths with the given tag. On error, including if the // module produced zero or multiple paths, it reports errors to the ctx and returns nil. func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path { func OutputFileForModule(ctx PathContext, module Module, tag string) Path { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) Loading Loading @@ -2678,48 +2688,55 @@ func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) P return paths[0] } func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { type OutputFilesProviderModuleContext interface { OtherModuleProviderContext Module() Module GetOutputFiles() OutputFilesInfo EqualModules(m1, m2 Module) bool } func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { return outputFilesFromProvider, err } if octx, ok := ctx.(OutputFilesProviderModuleContext); ok { if octx.EqualModules(octx.Module(), module) { if sourceFileProducer, ok := module.(SourceFileProducer); ok { return sourceFileProducer.Srcs(), nil } } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoKey); ok { if tag != "" { return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag) } paths := sourceFileProducer.Srcs() paths := sourceFiles.Srcs return paths, nil } else { return nil, fmt.Errorf("module %q is not a SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag) } } return nil, fmt.Errorf("module %q is not a SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag) } // 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. // If a module doesn't have the OutputFilesProvider, nil is returned. func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) { var outputFiles OutputFilesInfo fromProperty := false type OutputFilesProviderModuleContext interface { OtherModuleProviderContext Module() Module GetOutputFiles() OutputFilesInfo } if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx { if mctx.Module() != module { if !mctx.EqualModules(mctx.Module(), module) { outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider) } else { outputFiles = mctx.GetOutputFiles() fromProperty = true } } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta { providerData, _ := cta.otherModuleProvider(module, OutputFilesProvider) outputFiles, _ = providerData.(OutputFilesInfo) outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider) } else { return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx)) } Loading android/module_context.go +6 −4 Original line number Diff line number Diff line Loading @@ -16,13 +16,13 @@ package android import ( "fmt" "github.com/google/blueprint/depset" "path" "path/filepath" "slices" "strings" "github.com/google/blueprint" "github.com/google/blueprint/depset" "github.com/google/blueprint/proptools" ) Loading Loading @@ -439,9 +439,11 @@ func (m *moduleContext) GetMissingDependencies() []string { return missingDeps } func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { module, _ := m.getDirectDepInternal(name, tag) return module func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module { if module, _ := m.getDirectDepInternal(name, tag); module != nil { return module.(Module) } return nil } func (m *moduleContext) ModuleSubDir() string { Loading android/module_test.go +4 −0 Original line number Diff line number Diff line Loading @@ -998,6 +998,10 @@ func (p *pathContextAddMissingDependenciesWrapper) GetOutputFiles() OutputFilesI return OutputFilesInfo{} } func (p *pathContextAddMissingDependenciesWrapper) EqualModules(m1, m2 Module) bool { return m1 == m2 } func TestOutputFileForModule(t *testing.T) { testcases := []struct { name string Loading android/path_properties_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContex if p.props.Foo != "" { // Make sure there is only one dependency on a module listed in a property present in multiple property structs m := SrcIsModule(p.props.Foo) if GetModuleFromPathDep(ctx, m, "") == nil { if GetModuleProxyFromPathDep(ctx, m, "") == nil { ctx.ModuleErrorf("GetDirectDepWithTag failed") } } Loading Loading
android/base_module_context.go +20 −16 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ type BaseModuleContext interface { // GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if // none exists. It panics if the dependency does not have the specified tag. It skips any // dependencies that are not an android.Module. GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module // GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified // name, or nil if none exists. If there are multiple dependencies on the same module it returns Loading @@ -129,13 +129,14 @@ type BaseModuleContext interface { // function, it may be invalidated by future mutators. VisitDirectDeps(visit func(Module)) // VisitDirectDeps calls visit for each direct dependency. If there are multiple // VisitDirectDepsProxy calls visit for each direct dependency. If there are multiple // direct dependencies on the same module visit will be called multiple times on that module // and OtherModuleDependencyTag will return a different tag for each. // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the // dependencies are disabled. // // The Module passed to the visit function should not be retained outside of the visit // The ModuleProxy passed to the visit function should not be retained outside of the visit // function, it may be invalidated by future mutators. VisitDirectDepsAllowDisabled(visit func(Module)) VisitDirectDepsProxy(visit func(proxy ModuleProxy)) // VisitDirectDepsProxyAllowDisabled calls visit for each direct dependency. If there are // multiple direct dependencies on the same module visit will be called multiple times on Loading Loading @@ -261,7 +262,9 @@ func (b *baseModuleContext) EqualModules(m1, m2 Module) bool { func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { return b.bp.OtherModuleName(getWrappedModule(m)) } func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) } func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(getWrappedModule(m)) } func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) { b.bp.OtherModuleErrorf(m, fmt, args...) } Loading Loading @@ -298,8 +301,11 @@ func (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value b.bp.SetProvider(provider, value) } func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { return b.bp.GetDirectDepWithTag(name, tag) func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module { if module := b.bp.GetDirectDepWithTag(name, tag); module != nil { return module.(Module) } return nil } func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext { Loading Loading @@ -464,18 +470,16 @@ func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) { }) } func (b *baseModuleContext) VisitDirectDepsAllowDisabled(visit func(Module)) { b.bp.VisitDirectDeps(func(module blueprint.Module) { visit(module.(Module)) func (b *baseModuleContext) VisitDirectDepsProxy(visit func(ModuleProxy)) { b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) { if aModule := b.validateAndroidModuleProxy(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { visit(*aModule) } }) } func (b *baseModuleContext) VisitDirectDepsProxyAllowDisabled(visit func(proxy ModuleProxy)) { b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) { visit(ModuleProxy{ module: module, }) }) b.bp.VisitDirectDepsProxy(visitProxyAdaptor(visit)) } func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { Loading
android/module.go +37 −20 Original line number Diff line number Diff line Loading @@ -1834,6 +1834,12 @@ type InstallFilesInfo struct { var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]() type SourceFilesInfo struct { Srcs Paths } var SourceFilesInfoKey = blueprint.NewProvider[SourceFilesInfo]() type FinalModuleBuildTargetsInfo struct { // Used by buildTargetSingleton to create checkbuild and per-directory build targets // Only set on the final variant of each module Loading Loading @@ -2038,6 +2044,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) ctx.GetMissingDependencies() } if sourceFileProducer, ok := m.module.(SourceFileProducer); ok { SetProvider(ctx, SourceFilesInfoKey, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) } if ctx.IsFinalModule(m.module) { m.generateModuleTarget(ctx) if ctx.Failed() { Loading Loading @@ -2634,7 +2644,7 @@ type SourceFileProducer interface { // OutputFilesForModule returns the output file paths with the given tag. On error, including if the // module produced zero paths, it reports errors to the ctx and returns nil. func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) Paths { func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) Loading @@ -2645,7 +2655,7 @@ func OutputFilesForModule(ctx PathContext, module blueprint.Module, tag string) // OutputFileForModule returns the output file paths with the given tag. On error, including if the // module produced zero or multiple paths, it reports errors to the ctx and returns nil. func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) Path { func OutputFileForModule(ctx PathContext, module Module, tag string) Path { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) Loading Loading @@ -2678,48 +2688,55 @@ func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) P return paths[0] } func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { type OutputFilesProviderModuleContext interface { OtherModuleProviderContext Module() Module GetOutputFiles() OutputFilesInfo EqualModules(m1, m2 Module) bool } func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { return outputFilesFromProvider, err } if octx, ok := ctx.(OutputFilesProviderModuleContext); ok { if octx.EqualModules(octx.Module(), module) { if sourceFileProducer, ok := module.(SourceFileProducer); ok { return sourceFileProducer.Srcs(), nil } } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoKey); ok { if tag != "" { return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag) } paths := sourceFileProducer.Srcs() paths := sourceFiles.Srcs return paths, nil } else { return nil, fmt.Errorf("module %q is not a SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag) } } return nil, fmt.Errorf("module %q is not a SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag) } // 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. // If a module doesn't have the OutputFilesProvider, nil is returned. func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) { func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) { var outputFiles OutputFilesInfo fromProperty := false type OutputFilesProviderModuleContext interface { OtherModuleProviderContext Module() Module GetOutputFiles() OutputFilesInfo } if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx { if mctx.Module() != module { if !mctx.EqualModules(mctx.Module(), module) { outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider) } else { outputFiles = mctx.GetOutputFiles() fromProperty = true } } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta { providerData, _ := cta.otherModuleProvider(module, OutputFilesProvider) outputFiles, _ = providerData.(OutputFilesInfo) outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider) } else { return nil, fmt.Errorf("unsupported context %q in method outputFilesForModuleFromProvider", reflect.TypeOf(ctx)) } Loading
android/module_context.go +6 −4 Original line number Diff line number Diff line Loading @@ -16,13 +16,13 @@ package android import ( "fmt" "github.com/google/blueprint/depset" "path" "path/filepath" "slices" "strings" "github.com/google/blueprint" "github.com/google/blueprint/depset" "github.com/google/blueprint/proptools" ) Loading Loading @@ -439,9 +439,11 @@ func (m *moduleContext) GetMissingDependencies() []string { return missingDeps } func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module { module, _ := m.getDirectDepInternal(name, tag) return module func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module { if module, _ := m.getDirectDepInternal(name, tag); module != nil { return module.(Module) } return nil } func (m *moduleContext) ModuleSubDir() string { Loading
android/module_test.go +4 −0 Original line number Diff line number Diff line Loading @@ -998,6 +998,10 @@ func (p *pathContextAddMissingDependenciesWrapper) GetOutputFiles() OutputFilesI return OutputFilesInfo{} } func (p *pathContextAddMissingDependenciesWrapper) EqualModules(m1, m2 Module) bool { return m1 == m2 } func TestOutputFileForModule(t *testing.T) { testcases := []struct { name string Loading
android/path_properties_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContex if p.props.Foo != "" { // Make sure there is only one dependency on a module listed in a property present in multiple property structs m := SrcIsModule(p.props.Foo) if GetModuleFromPathDep(ctx, m, "") == nil { if GetModuleProxyFromPathDep(ctx, m, "") == nil { ctx.ModuleErrorf("GetDirectDepWithTag failed") } } Loading