From 41955e8895fe33022a6759b9739a2368b206c392 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 29 May 2019 14:40:35 -0700 Subject: [PATCH] Support tagged module references There are cases where a module needs to refer to an intermediate output of another module instead of its final output. For example, a module may want to use the .jar containing .class files from another module whose final output is a .jar containing classes.dex files. Support a new ":module{.tag}" format in any property that is annotated with `android:"path"`, which will query the target module for its ".tag" output(s). Test: path_properties_test.go, paths_test.go Test: no unexpected changes in build.ninja Change-Id: Icd3c9b0d83ff125771767c04046fcffb9fc3f65a --- Android.bp | 1 + android/module.go | 58 +++++++++---- android/module_test.go | 141 ++++++++++++++++++++++++++++++++ android/path_properties.go | 6 +- android/path_properties_test.go | 8 +- android/paths.go | 67 +++++++++------ android/paths_test.go | 113 ++++++++++++++++++++++--- android/prebuilt_test.go | 10 ++- apex/apex.go | 24 ++++-- bpf/bpf.go | 13 ++- cc/cc.go | 20 +++-- java/app_test.go | 8 +- java/droiddoc.go | 11 ++- java/java.go | 15 ++-- 14 files changed, 408 insertions(+), 87 deletions(-) create mode 100644 android/module_test.go diff --git a/Android.bp b/Android.bp index c9a48b4b7..4db98f851 100644 --- a/Android.bp +++ b/Android.bp @@ -81,6 +81,7 @@ bootstrap_go_package { "android/arch_test.go", "android/config_test.go", "android/expand_test.go", + "android/module_test.go", "android/namespace_test.go", "android/neverallow_test.go", "android/onceper_test.go", diff --git a/android/module.go b/android/module.go index 1c3627953..eb9b0fc2c 100644 --- a/android/module.go +++ b/android/module.go @@ -1462,39 +1462,60 @@ func findStringInSlice(str string, slice []string) int { return -1 } -func SrcIsModule(s string) string { +// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input +// was not a module reference. +func SrcIsModule(s string) (module string) { if len(s) > 1 && s[0] == ':' { return s[1:] } return "" } -type sourceDependencyTag struct { - blueprint.BaseDependencyTag +// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the +// module name and an empty string for the tag, or empty strings if the input was not a module reference. +func SrcIsModuleWithTag(s string) (module, tag string) { + if len(s) > 1 && s[0] == ':' { + module = s[1:] + if tagStart := strings.IndexByte(module, '{'); tagStart > 0 { + if module[len(module)-1] == '}' { + tag = module[tagStart+1 : len(module)-1] + module = module[:tagStart] + return module, tag + } + } + return module, "" + } + return "", "" } -var SourceDepTag sourceDependencyTag +type sourceOrOutputDependencyTag struct { + blueprint.BaseDependencyTag + tag string +} + +func sourceOrOutputDepTag(tag string) blueprint.DependencyTag { + return sourceOrOutputDependencyTag{tag: tag} +} + +var SourceDepTag = sourceOrOutputDepTag("") // Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles // using ":module" syntax, if any. // // Deprecated: tag the property with `android:"path"` instead. func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { - var deps []string set := make(map[string]bool) for _, s := range srcFiles { - if m := SrcIsModule(s); m != "" { - if _, found := set[m]; found { - ctx.ModuleErrorf("found source dependency duplicate: %q!", m) + if m, t := SrcIsModuleWithTag(s); m != "" { + if _, found := set[s]; found { + ctx.ModuleErrorf("found source dependency duplicate: %q!", s) } else { - set[m] = true - deps = append(deps, m) + set[s] = true + ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) } } } - - ctx.AddDependency(ctx.Module(), SourceDepTag, deps...) } // Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s @@ -1503,16 +1524,25 @@ func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { // Deprecated: tag the property with `android:"path"` instead. func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) { if s != nil { - if m := SrcIsModule(*s); m != "" { - ctx.AddDependency(ctx.Module(), SourceDepTag, m) + if m, t := SrcIsModuleWithTag(*s); m != "" { + ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) } } } +// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"` +// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property. type SourceFileProducer interface { Srcs() Paths } +// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"` +// using the ":module" syntax or ":module{.tag}" syntax and provides a list of otuput files to be used as if they were +// listed in the property. +type OutputFileProducer interface { + OutputFiles(tag string) (Paths, error) +} + type HostToolProvider interface { HostToolPath() OptionalPath } diff --git a/android/module_test.go b/android/module_test.go new file mode 100644 index 000000000..c790a6854 --- /dev/null +++ b/android/module_test.go @@ -0,0 +1,141 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package android + +import "testing" + +func TestSrcIsModule(t *testing.T) { + type args struct { + s string + } + tests := []struct { + name string + args args + wantModule string + }{ + { + name: "file", + args: args{ + s: "foo", + }, + wantModule: "", + }, + { + name: "module", + args: args{ + s: ":foo", + }, + wantModule: "foo", + }, + { + name: "tag", + args: args{ + s: ":foo{.bar}", + }, + wantModule: "foo{.bar}", + }, + { + name: "extra colon", + args: args{ + s: ":foo:bar", + }, + wantModule: "foo:bar", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotModule := SrcIsModule(tt.args.s); gotModule != tt.wantModule { + t.Errorf("SrcIsModule() = %v, want %v", gotModule, tt.wantModule) + } + }) + } +} + +func TestSrcIsModuleWithTag(t *testing.T) { + type args struct { + s string + } + tests := []struct { + name string + args args + wantModule string + wantTag string + }{ + { + name: "file", + args: args{ + s: "foo", + }, + wantModule: "", + wantTag: "", + }, + { + name: "module", + args: args{ + s: ":foo", + }, + wantModule: "foo", + wantTag: "", + }, + { + name: "tag", + args: args{ + s: ":foo{.bar}", + }, + wantModule: "foo", + wantTag: ".bar", + }, + { + name: "empty tag", + args: args{ + s: ":foo{}", + }, + wantModule: "foo", + wantTag: "", + }, + { + name: "extra colon", + args: args{ + s: ":foo:bar", + }, + wantModule: "foo:bar", + }, + { + name: "invalid tag", + args: args{ + s: ":foo{.bar", + }, + wantModule: "foo{.bar", + }, + { + name: "invalid tag 2", + args: args{ + s: ":foo.bar}", + }, + wantModule: "foo.bar}", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotModule, gotTag := SrcIsModuleWithTag(tt.args.s) + if gotModule != tt.wantModule { + t.Errorf("SrcIsModuleWithTag() gotModule = %v, want %v", gotModule, tt.wantModule) + } + if gotTag != tt.wantTag { + t.Errorf("SrcIsModuleWithTag() gotTag = %v, want %v", gotTag, tt.wantTag) + } + }) + } +} diff --git a/android/path_properties.go b/android/path_properties.go index 1a12290d3..af7af5940 100644 --- a/android/path_properties.go +++ b/android/path_properties.go @@ -39,14 +39,12 @@ func pathDepsMutator(ctx BottomUpMutatorContext) { pathProperties := pathPropertiesForPropertyStruct(ctx, ps) pathProperties = FirstUniqueStrings(pathProperties) - var deps []string for _, s := range pathProperties { - if m := SrcIsModule(s); m != "" { - deps = append(deps, m) + if m, t := SrcIsModuleWithTag(s); m != "" { + ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) } } - ctx.AddDependency(ctx.Module(), SourceDepTag, deps...) } } diff --git a/android/path_properties_test.go b/android/path_properties_test.go index ecc2d2122..fa187fa6f 100644 --- a/android/path_properties_test.go +++ b/android/path_properties_test.go @@ -41,8 +41,10 @@ func pathDepsMutatorTestModuleFactory() Module { } func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { - ctx.VisitDirectDepsWithTag(SourceDepTag, func(dep Module) { - p.sourceDeps = append(p.sourceDeps, ctx.OtherModuleName(dep)) + ctx.VisitDirectDeps(func(dep Module) { + if _, ok := ctx.OtherModuleDependencyTag(dep).(sourceOrOutputDependencyTag); ok { + p.sourceDeps = append(p.sourceDeps, ctx.OtherModuleName(dep)) + } }) } @@ -59,7 +61,7 @@ func TestPathDepsMutator(t *testing.T) { name: "foo", foo: ":a", bar: [":b"], - baz: ":c", + baz: ":c{.bar}", qux: ":d", }`, deps: []string{"a", "b", "c"}, diff --git a/android/paths.go b/android/paths.go index da387a8a7..3915ff414 100644 --- a/android/paths.go +++ b/android/paths.go @@ -217,21 +217,23 @@ func ExistentPathsForSources(ctx PathContext, paths []string) Paths { return ret } -// PathsForModuleSrc returns Paths rooted from the module's local source directory. It expands globs and references -// to SourceFileProducer modules using the ":name" syntax. Properties passed as the paths argument must have been -// annotated with struct tag `android:"path"` so that dependencies on SourceFileProducer modules will have already -// been handled by the path_properties mutator. If ctx.Config().AllowMissingDependencies() is true, then any missing -// SourceFileProducer dependencies will cause the module to be marked as having missing dependencies. +// PathsForModuleSrc returns Paths rooted from the module's local source directory. It expands globs, references to +// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the +// ":name{.tag}" syntax. Properties passed as the paths argument must have been annotated with struct tag +// `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the +// path_properties mutator. If ctx.Config().AllowMissingDependencies() is true then any missing SourceFileProducer or +// OutputFileProducer dependencies will cause the module to be marked as having missing dependencies. func PathsForModuleSrc(ctx ModuleContext, paths []string) Paths { return PathsForModuleSrcExcludes(ctx, paths, nil) } // PathsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding paths listed in -// the excludes arguments. It expands globs and references to SourceFileProducer modules in both paths and excludes -// using the ":name" syntax. Properties passed as the paths or excludes argument must have been annotated with struct -// tag `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the -// path_properties mutator. If ctx.Config().AllowMissingDependencies() is true, then any missing SourceFileProducer -// dependencies will cause the module to be marked as having missing dependencies. +// the excludes arguments. It expands globs, references to SourceFileProducer modules using the ":name" syntax, and +// references to OutputFileProducer modules using the ":name{.tag}" syntax. Properties passed as the paths or excludes +// argument must have been annotated with struct tag `android:"path"` so that dependencies on SourceFileProducer modules +// will have already been handled by the path_properties mutator. If ctx.Config().AllowMissingDependencies() is +// truethen any missing SourceFileProducer or OutputFileProducer dependencies will cause the module to be marked as +// having missing dependencies. func PathsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) Paths { ret, missingDeps := PathsAndMissingDepsForModuleSrcExcludes(ctx, paths, excludes) if ctx.Config().AllowMissingDependencies() { @@ -245,12 +247,13 @@ func PathsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) Path } // PathsAndMissingDepsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding -// paths listed in the excludes arguments, and a list of missing dependencies. It expands globs and references to -// SourceFileProducer modules in both paths and excludes using the ":name" syntax. Properties passed as the paths or -// excludes argument must have been annotated with struct tag `android:"path"` so that dependencies on -// SourceFileProducer modules will have already been handled by the path_properties mutator. If -// ctx.Config().AllowMissingDependencies() is true, then any missing SourceFileProducer dependencies will be returned, -// and they will NOT cause the module to be marked as having missing dependencies. +// paths listed in the excludes arguments, and a list of missing dependencies. It expands globs, references to +// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the +// ":name{.tag}" syntax. Properties passed as the paths or excludes argument must have been annotated with struct tag +// `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the +// path_properties mutator. If ctx.Config().AllowMissingDependencies() is true then any missing SourceFileProducer or +// OutputFileProducer dependencies will be returned, and they will NOT cause the module to be marked as having missing +// dependencies. func PathsAndMissingDepsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) (Paths, []string) { prefix := pathForModuleSrc(ctx).String() @@ -262,16 +265,24 @@ func PathsAndMissingDepsForModuleSrcExcludes(ctx ModuleContext, paths, excludes var missingExcludeDeps []string for _, e := range excludes { - if m := SrcIsModule(e); m != "" { - module := ctx.GetDirectDepWithTag(m, SourceDepTag) + if m, t := SrcIsModuleWithTag(e); m != "" { + module := ctx.GetDirectDepWithTag(m, sourceOrOutputDepTag(t)) if module == nil { missingExcludeDeps = append(missingExcludeDeps, m) continue } - if srcProducer, ok := module.(SourceFileProducer); ok { + if outProducer, ok := module.(OutputFileProducer); ok { + outputFiles, err := outProducer.OutputFiles(t) + if err != nil { + ctx.ModuleErrorf("path dependency %q: %s", e, err) + } + expandedExcludes = append(expandedExcludes, outputFiles.Strings()...) + } else if t != "" { + ctx.ModuleErrorf("path dependency %q is not an output file producing module", e) + } else if srcProducer, ok := module.(SourceFileProducer); ok { expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...) } else { - ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m) + ctx.ModuleErrorf("path dependency %q is not a source file producing module", e) } } else { expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e)) @@ -307,12 +318,20 @@ func (e missingDependencyError) Error() string { } func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (Paths, error) { - if m := SrcIsModule(s); m != "" { - module := ctx.GetDirectDepWithTag(m, SourceDepTag) + if m, t := SrcIsModuleWithTag(s); m != "" { + module := ctx.GetDirectDepWithTag(m, sourceOrOutputDepTag(t)) if module == nil { return nil, missingDependencyError{[]string{m}} } - if srcProducer, ok := module.(SourceFileProducer); ok { + if outProducer, ok := module.(OutputFileProducer); ok { + outputFiles, err := outProducer.OutputFiles(t) + if err != nil { + return nil, fmt.Errorf("path dependency %q: %s", s, err) + } + return outputFiles, nil + } else if t != "" { + return nil, fmt.Errorf("path dependency %q is not an output file producing module", s) + } else if srcProducer, ok := module.(SourceFileProducer); ok { moduleSrcs := srcProducer.Srcs() for _, e := range expandedExcludes { for j := 0; j < len(moduleSrcs); j++ { @@ -324,7 +343,7 @@ func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (P } return moduleSrcs, nil } else { - return nil, fmt.Errorf("path dependency %q is not a source file producing module", m) + return nil, fmt.Errorf("path dependency %q is not a source file producing module", s) } } else if pathtools.IsGlob(s) { paths := ctx.GlobFiles(pathForModuleSrc(ctx, s).String(), expandedExcludes) diff --git a/android/paths_test.go b/android/paths_test.go index b52d71337..85c8d84bc 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -760,6 +760,45 @@ func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleConte } } +type pathForModuleSrcOutputFileProviderModule struct { + ModuleBase + props struct { + Outs []string + Tagged []string + } + + outs Paths + tagged Paths +} + +func pathForModuleSrcOutputFileProviderModuleFactory() Module { + module := &pathForModuleSrcOutputFileProviderModule{} + module.AddProperties(&module.props) + InitAndroidModule(module) + return module +} + +func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) { + for _, out := range p.props.Outs { + p.outs = append(p.outs, PathForModuleOut(ctx, out)) + } + + for _, tagged := range p.props.Tagged { + p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged)) + } +} + +func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) { + switch tag { + case "": + return p.outs, nil + case ".tagged": + return p.tagged, nil + default: + return nil, fmt.Errorf("unsupported tag %q", tag) + } +} + type pathForModuleSrcTestCase struct { name string bp string @@ -776,6 +815,7 @@ func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSr ctx := NewTestContext() ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory)) + ctx.RegisterModuleType("output_file_provider", ModuleFactoryAdaptor(pathForModuleSrcOutputFileProviderModuleFactory)) ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory)) fgBp := ` @@ -785,9 +825,18 @@ func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSr } ` + ofpBp := ` + output_file_provider { + name: "b", + outs: ["gen/b"], + tagged: ["gen/c"], + } + ` + mockFS := map[string][]byte{ "fg/Android.bp": []byte(fgBp), "foo/Android.bp": []byte(test.bp), + "ofp/Android.bp": []byte(ofpBp), "fg/src/a": nil, "foo/src/b": nil, "foo/src/c": nil, @@ -799,7 +848,7 @@ func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSr ctx.MockFileSystem(mockFS) ctx.Register() - _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp"}) + _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp", "ofp/Android.bp"}) FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) FailIfErrored(t, errs) @@ -826,6 +875,12 @@ func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSr } func TestPathsForModuleSrc(t *testing.T) { + buildDir, err := ioutil.TempDir("", "soong_paths_for_module_src_test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(buildDir) + tests := []pathForModuleSrcTestCase{ { name: "path", @@ -870,6 +925,26 @@ func TestPathsForModuleSrc(t *testing.T) { srcs: []string{"fg/src/a"}, rels: []string{"src/a"}, }, + { + name: "output file provider", + bp: ` + test { + name: "foo", + srcs: [":b"], + }`, + srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"}, + rels: []string{"gen/b"}, + }, + { + name: "output file provider tagged", + bp: ` + test { + name: "foo", + srcs: [":b{.tagged}"], + }`, + srcs: []string{buildDir + "/.intermediates/ofp/b/gen/c"}, + rels: []string{"gen/c"}, + }, { name: "special characters glob", bp: ` @@ -882,16 +957,16 @@ func TestPathsForModuleSrc(t *testing.T) { }, } - buildDir, err := ioutil.TempDir("", "soong_paths_for_module_src_test") + testPathForModuleSrc(t, buildDir, tests) +} + +func TestPathForModuleSrc(t *testing.T) { + buildDir, err := ioutil.TempDir("", "soong_path_for_module_src_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(buildDir) - testPathForModuleSrc(t, buildDir, tests) -} - -func TestPathForModuleSrc(t *testing.T) { tests := []pathForModuleSrcTestCase{ { name: "path", @@ -923,6 +998,26 @@ func TestPathForModuleSrc(t *testing.T) { src: "fg/src/a", rel: "src/a", }, + { + name: "output file provider", + bp: ` + test { + name: "foo", + src: ":b", + }`, + src: buildDir + "/.intermediates/ofp/b/gen/b", + rel: "gen/b", + }, + { + name: "output file provider tagged", + bp: ` + test { + name: "foo", + src: ":b{.tagged}", + }`, + src: buildDir + "/.intermediates/ofp/b/gen/c", + rel: "gen/c", + }, { name: "special characters glob", bp: ` @@ -935,12 +1030,6 @@ func TestPathForModuleSrc(t *testing.T) { }, } - buildDir, err := ioutil.TempDir("", "soong_path_for_module_src_test") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(buildDir) - testPathForModuleSrc(t, buildDir, tests) } diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index e1826414d..a5b85c8c2 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -15,6 +15,7 @@ package android import ( + "fmt" "io/ioutil" "os" "testing" @@ -250,8 +251,13 @@ func (p *prebuiltModule) Prebuilt() *Prebuilt { return &p.prebuilt } -func (p *prebuiltModule) Srcs() Paths { - return Paths{p.src} +func (p *prebuiltModule) OutputFiles(tag string) (Paths, error) { + switch tag { + case "": + return Paths{p.src}, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) + } } type sourceModule struct { diff --git a/apex/apex.go b/apex/apex.go index 51d0718ad..aed7d6fd2 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -560,11 +560,16 @@ func (a *apexBundle) getCertString(ctx android.BaseContext) string { return String(a.properties.Certificate) } -func (a *apexBundle) Srcs() android.Paths { - if file, ok := a.outputFiles[imageApex]; ok { - return android.Paths{file} - } else { - return nil +func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + if file, ok := a.outputFiles[imageApex]; ok { + return android.Paths{file}, nil + } else { + return nil, nil + } + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) } } @@ -1383,8 +1388,13 @@ func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { p.properties.Source = src } -func (p *Prebuilt) Srcs() android.Paths { - return android.Paths{p.outputApex} +func (p *Prebuilt) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + return android.Paths{p.outputApex}, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) + } } func (p *Prebuilt) InstallFilename() string { diff --git a/bpf/bpf.go b/bpf/bpf.go index dcbf9adac..90ec963d1 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -122,13 +122,18 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData { } } -// Implements SourceFileProducer interface so that the obj output can be used in the data property +// Implements OutputFileFileProducer interface so that the obj output can be used in the data property // of other modules. -func (bpf *bpf) Srcs() android.Paths { - return bpf.objs +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) + } } -var _ android.SourceFileProducer = (*bpf)(nil) +var _ android.OutputFileProducer = (*bpf)(nil) func bpfFactory() android.Module { module := &bpf{} diff --git a/cc/cc.go b/cc/cc.go index 09496fc74..e61857d87 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -19,6 +19,7 @@ package cc // is handled in builder.go import ( + "fmt" "io" "strconv" "strings" @@ -1925,11 +1926,16 @@ func (c *Module) IntermPathForModuleOut() android.OptionalPath { return c.outputFile } -func (c *Module) Srcs() android.Paths { - if c.outputFile.Valid() { - return android.Paths{c.outputFile.Path()} +func (c *Module) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + if c.outputFile.Valid() { + return android.Paths{c.outputFile.Path()}, nil + } + return android.Paths{}, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) } - return android.Paths{} } func (c *Module) static() bool { @@ -2006,7 +2012,11 @@ func (c *Module) imageVariation() string { } func (c *Module) IDEInfo(dpInfo *android.IdeInfo) { - dpInfo.Srcs = append(dpInfo.Srcs, c.Srcs().Strings()...) + outputFiles, err := c.OutputFiles("") + if err != nil { + panic(err) + } + dpInfo.Srcs = append(dpInfo.Srcs, outputFiles.Strings()...) } func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) { diff --git a/java/app_test.go b/java/app_test.go index 559afcc7d..9aedebd76 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -130,8 +130,12 @@ func TestAppSplits(t *testing.T) { foo.Output(expectedOutput) } - if g, w := foo.Module().(*AndroidApp).Srcs().Strings(), expectedOutputs; !reflect.DeepEqual(g, w) { - t.Errorf("want Srcs() = %q, got %q", w, g) + outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("") + if err != nil { + t.Fatal(err) + } + if g, w := outputFiles.Strings(), expectedOutputs; !reflect.DeepEqual(g, w) { + t.Errorf(`want OutputFiles("") = %q, got %q`, w, g) } } diff --git a/java/droiddoc.go b/java/droiddoc.go index 57da6b621..0ec7799a8 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -497,8 +497,13 @@ type Javadoc struct { stubsSrcJar android.WritablePath } -func (j *Javadoc) Srcs() android.Paths { - return android.Paths{j.stubsSrcJar} +func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + return android.Paths{j.stubsSrcJar}, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) + } } func JavadocFactory() android.Module { @@ -519,7 +524,7 @@ func JavadocHostFactory() android.Module { return module } -var _ android.SourceFileProducer = (*Javadoc)(nil) +var _ android.OutputFileProducer = (*Javadoc)(nil) func (j *Javadoc) sdkVersion() string { return String(j.properties.Sdk_version) diff --git a/java/java.go b/java/java.go index 31c6afec8..bfbd98c8f 100644 --- a/java/java.go +++ b/java/java.go @@ -351,15 +351,20 @@ type Module struct { dexpreopter } -func (j *Module) Srcs() android.Paths { - return append(android.Paths{j.outputFile}, j.extraOutputFiles...) +func (j *Module) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) + } } func (j *Module) DexJarFile() android.Path { return j.dexJarFile } -var _ android.SourceFileProducer = (*Module)(nil) +var _ android.OutputFileProducer = (*Module)(nil) type Dependency interface { HeaderJars() android.Paths @@ -813,8 +818,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } default: switch tag { - case android.DefaultsDepTag, android.SourceDepTag: - // Nothing to do case systemModulesTag: if deps.systemModules != nil { panic("Found two system module dependencies") @@ -824,8 +827,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { panic("Missing directory for system module dependency") } deps.systemModules = sm.outputFile - default: - ctx.ModuleErrorf("depends on non-java module %q", otherName) } } })