aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2017-12-05 09:28:08 -0800
committerColin Cross <ccross@android.com>2017-12-06 03:55:20 +0000
commit5425090a4f006fb0de0a98fbd0dad66706e1638e (patch)
treecc4702674014d3826752d25ce31cbf0f69046abe
parent9cf27db425bd693ab17603bef740f2411363c3df (diff)
downloadbuild_soong-5425090a4f006fb0de0a98fbd0dad66706e1638e.tar.gz
build_soong-5425090a4f006fb0de0a98fbd0dad66706e1638e.tar.bz2
build_soong-5425090a4f006fb0de0a98fbd0dad66706e1638e.zip
Add java_genrules to use jars as inputs and outputs
Add a java_genrule that has the right multilib flags to be a dependency of a java rule. Make java libraries implement SourceFileProducer so that their classes jar can be used as an input to a java_genrule. Allow libs and static_libs dependencies to be a java_genrule. Test: TestJarGenrules Change-Id: Ib1b31ef9c0b7e72eeed2c9ecc4ce8a1088e0b1c9
-rw-r--r--Android.bp1
-rw-r--r--java/genrule.go35
-rw-r--r--java/java.go81
-rw-r--r--java/java_test.go55
4 files changed, 146 insertions, 26 deletions
diff --git a/Android.bp b/Android.bp
index 3e09add4..643e8df3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -218,6 +218,7 @@ bootstrap_go_package {
"java/app.go",
"java/builder.go",
"java/gen.go",
+ "java/genrule.go",
"java/jacoco.go",
"java/java.go",
"java/proto.go",
diff --git a/java/genrule.go b/java/genrule.go
new file mode 100644
index 00000000..80b70305
--- /dev/null
+++ b/java/genrule.go
@@ -0,0 +1,35 @@
+// Copyright 2017 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 java
+
+import (
+ "android/soong/android"
+ "android/soong/genrule"
+)
+
+func init() {
+ android.RegisterModuleType("java_genrule", genRuleFactory)
+}
+
+// java_genrule is a genrule that can depend on other java_* objects.
+// The cmd may be run multiple times, once for each of the different host/device
+// variations.
+func genRuleFactory() android.Module {
+ module := genrule.NewGenRule()
+
+ android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+
+ return module
+}
diff --git a/java/java.go b/java/java.go
index 4355200f..0a47db02 100644
--- a/java/java.go
+++ b/java/java.go
@@ -211,6 +211,12 @@ type Module struct {
compiledSrcJars android.Paths
}
+func (j *Module) Srcs() android.Paths {
+ return android.Paths{j.implementationJarFile}
+}
+
+var _ android.SourceFileProducer = (*Module)(nil)
+
type Dependency interface {
HeaderJars() android.Paths
ImplementationJars() android.Paths
@@ -446,6 +452,15 @@ type deps struct {
kotlinStdlib android.Paths
}
+func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
+ for _, f := range dep.Srcs() {
+ if f.Ext() != ".jar" {
+ ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
+ ctx.OtherModuleName(dep.(blueprint.Module)))
+ }
+ }
+}
+
func (j *Module) collectDeps(ctx android.ModuleContext) deps {
var deps deps
@@ -462,8 +477,46 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
- dep, _ := module.(Dependency)
- if dep == nil {
+ switch dep := module.(type) {
+ case Dependency:
+ switch tag {
+ case bootClasspathTag:
+ deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
+ case libTag:
+ deps.classpath = append(deps.classpath, dep.HeaderJars()...)
+ case staticLibTag:
+ deps.classpath = append(deps.classpath, dep.HeaderJars()...)
+ deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
+ deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
+ case frameworkResTag:
+ if ctx.ModuleName() == "framework" {
+ // framework.jar has a one-off dependency on the R.java and Manifest.java files
+ // generated by framework-res.apk
+ deps.srcJars = append(deps.srcJars, dep.(*AndroidApp).aaptSrcJar)
+ }
+ case kotlinStdlibTag:
+ deps.kotlinStdlib = dep.HeaderJars()
+ default:
+ panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
+ }
+
+ deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
+ case android.SourceFileProducer:
+ switch tag {
+ case libTag:
+ checkProducesJars(ctx, dep)
+ deps.classpath = append(deps.classpath, dep.Srcs()...)
+ case staticLibTag:
+ checkProducesJars(ctx, dep)
+ deps.classpath = append(deps.classpath, dep.Srcs()...)
+ deps.staticJars = append(deps.staticJars, dep.Srcs()...)
+ deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
+ case android.DefaultsDepTag, android.SourceDepTag:
+ // Nothing to do
+ default:
+ ctx.ModuleErrorf("dependency on genrule %q may only be in srcs, libs, or static_libs", otherName)
+ }
+ default:
switch tag {
case android.DefaultsDepTag, android.SourceDepTag:
// Nothing to do
@@ -479,31 +532,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
default:
ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
- return
- }
-
- switch tag {
- case bootClasspathTag:
- deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
- case libTag:
- deps.classpath = append(deps.classpath, dep.HeaderJars()...)
- case staticLibTag:
- deps.classpath = append(deps.classpath, dep.HeaderJars()...)
- deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
- deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
- case frameworkResTag:
- if ctx.ModuleName() == "framework" {
- // framework.jar has a one-off dependency on the R.java and Manifest.java files
- // generated by framework-res.apk
- deps.srcJars = append(deps.srcJars, dep.(*AndroidApp).aaptSrcJar)
- }
- case kotlinStdlibTag:
- deps.kotlinStdlib = dep.HeaderJars()
- default:
- panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
-
- deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
})
return deps
diff --git a/java/java_test.go b/java/java_test.go
index dbecc70b..58b27c30 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -67,6 +67,7 @@ func testContext(config android.Config, bp string,
ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory))
ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(SystemModulesFactory))
+ ctx.RegisterModuleType("java_genrule", android.ModuleFactoryAdaptor(genRuleFactory))
ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
ctx.RegisterModuleType("genrule", android.ModuleFactoryAdaptor(genrule.GenRuleFactory))
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
@@ -775,6 +776,60 @@ func TestSharding(t *testing.T) {
}
}
+func TestJarGenrules(t *testing.T) {
+ ctx := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+
+ java_genrule {
+ name: "jargen",
+ tool_files: ["b.java"],
+ cmd: "$(location b.java) $(in) $(out)",
+ out: ["jargen.jar"],
+ srcs: [":foo"],
+ }
+
+ java_library {
+ name: "bar",
+ static_libs: ["jargen"],
+ srcs: ["c.java"],
+ }
+
+ java_library {
+ name: "baz",
+ libs: ["jargen"],
+ srcs: ["c.java"],
+ }
+ `)
+
+ foo := ctx.ModuleForTests("foo", "android_common").Output("javac/foo.jar")
+ jargen := ctx.ModuleForTests("jargen", "android_common").Output("jargen.jar")
+ bar := ctx.ModuleForTests("bar", "android_common").Output("javac/bar.jar")
+ baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
+ barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
+
+ if len(jargen.Inputs) != 1 || jargen.Inputs[0].String() != foo.Output.String() {
+ t.Errorf("expected jargen inputs [%q], got %q", foo.Output.String(), jargen.Inputs.Strings())
+ }
+
+ if !strings.Contains(bar.Args["classpath"], jargen.Output.String()) {
+ t.Errorf("bar classpath %v does not contain %q", bar.Args["classpath"], jargen.Output.String())
+ }
+
+ if !strings.Contains(baz.Args["classpath"], jargen.Output.String()) {
+ t.Errorf("baz classpath %v does not contain %q", baz.Args["classpath"], jargen.Output.String())
+ }
+
+ if len(barCombined.Inputs) != 2 ||
+ barCombined.Inputs[0].String() != bar.Output.String() ||
+ barCombined.Inputs[1].String() != jargen.Output.String() {
+ t.Errorf("bar combined jar inputs %v is not [%q, %q]",
+ barCombined.Inputs.Strings(), bar.Output.String(), jargen.Output.String())
+ }
+}
+
func fail(t *testing.T, errs []error) {
if len(errs) > 0 {
for _, err := range errs {