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