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
diff --git a/Android.bp b/Android.bp
index c9a48b4..4db98f8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -81,6 +81,7 @@
"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 1c36279..eb9b0fc 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1462,39 +1462,60 @@
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 @@
// 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 0000000..c790a68
--- /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 1a12290..af7af59 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -39,14 +39,12 @@
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 ecc2d21..fa187fa 100644
--- a/android/path_properties_test.go
+++ b/android/path_properties_test.go
@@ -41,8 +41,10 @@
}
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 @@
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 da387a8..3915ff4 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -217,21 +217,23 @@
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 @@
}
// 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 @@
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 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 @@
}
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 b52d713..85c8d84 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -760,6 +760,45 @@
}
}
+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 @@
ctx := NewTestContext()
ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory))
+ ctx.RegisterModuleType("output_file_provider", ModuleFactoryAdaptor(pathForModuleSrcOutputFileProviderModuleFactory))
ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
fgBp := `
@@ -785,9 +825,18 @@
}
`
+ 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 @@
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 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",
@@ -871,6 +926,26 @@
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: `
test {
@@ -882,16 +957,16 @@
},
}
- 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",
@@ -924,6 +999,26 @@
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: `
test {
@@ -935,12 +1030,6 @@
},
}
- 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 e182641..a5b85c8 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 @@
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 51d0718..aed7d6f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -560,11 +560,16 @@
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 @@
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 dcbf9ad..90ec963 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -122,13 +122,18 @@
}
}
-// 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 09496fc..e61857d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -19,6 +19,7 @@
// is handled in builder.go
import (
+ "fmt"
"io"
"strconv"
"strings"
@@ -1925,11 +1926,16 @@
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) 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 559afcc..9aedebd 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -130,8 +130,12 @@
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 57da6b6..0ec7799 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -497,8 +497,13 @@
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 @@
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 31c6afe..bfbd98c 100644
--- a/java/java.go
+++ b/java/java.go
@@ -351,15 +351,20 @@
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 @@
}
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 @@
panic("Missing directory for system module dependency")
}
deps.systemModules = sm.outputFile
- default:
- ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
}
})