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