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
This commit is contained in:
Colin Cross 2019-05-29 14:40:35 -07:00
parent 4c2c46f0a7
commit 41955e8895
14 changed files with 408 additions and 87 deletions

View File

@ -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",

View File

@ -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
}

141
android/module_test.go Normal file
View File

@ -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)
}
})
}
}

View File

@ -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...)
}
}

View File

@ -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"},

View File

@ -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)

View File

@ -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)
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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{}

View File

@ -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) {

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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)
}
}
})