aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Alex Humesky <ahumesky@google.com>2015-07-08 18:18:33 +0000
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-07-10 17:15:23 +0000
commitd3f7eda5548fae0d9c022d9e1a0761b8e8ba22a6 (patch)
tree8cbca5cb9298446be3ac2c539526b7714a647790
parent525019b7bd8810ef8401ecb80247fa4226eba8c2 (diff)
Adds gen jar and manifest proto outputs.
Adds a jar output to Java and Android rules which contains the class files for source files generated from Java annotation processors. For a java_binary foo, the jar will be foo-gen.jar, and for a java_library foo the jar will be libfoo-gen.jar, and similarly for Android. Also adds a binary serialized proto manifest file output to Java and Android rules which describes the contents of the output class jar of those rules, which is used to create the -gen.jar. See src/main/protobuf/java_compilation.proto. -- MOS_MIGRATED_REVID=97793715
-rwxr-xr-xcompile.sh2
-rwxr-xr-xscripts/bootstrap/bootstrap.sh1
-rwxr-xr-xscripts/get_all_bazel_paths.sh8
-rwxr-xr-xscripts/setup-eclipse.sh9
-rw-r--r--src/BUILD1
-rw-r--r--src/java_tools/buildjar/BUILD23
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/BUILD16
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java121
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptions.java90
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptionsParser.java56
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java29
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java93
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java13
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java2
-rw-r--r--src/test/shell/bazel/BUILD1
-rwxr-xr-xsrc/test/shell/bazel/test-setup.sh1
-rwxr-xr-xsrc/test/shell/bazel/testenv.sh1
-rw-r--r--tools/jdk/BUILD1
29 files changed, 577 insertions, 75 deletions
diff --git a/compile.sh b/compile.sh
index 30b97d0fac..581136d57d 100755
--- a/compile.sh
+++ b/compile.sh
@@ -106,6 +106,8 @@ if [ $DO_TOOLS_COMPILATION ]; then
tools/jdk/SingleJar_deploy.jar
bazel_bootstrap //src/java_tools/buildjar:JavaBuilder_deploy.jar \
tools/jdk/JavaBuilder_deploy.jar
+ bazel_bootstrap //src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass:GenClass_deploy.jar \
+ tools/jdk/GenClass_deploy.jar
if [[ $PLATFORM == "darwin" ]]; then
bazel_bootstrap //src/tools/xcode-common/java/com/google/devtools/build/xcode/actoolzip:actoolzip_deploy.jar \
tools/objc/precomp_actoolzip_deploy.jar
diff --git a/scripts/bootstrap/bootstrap.sh b/scripts/bootstrap/bootstrap.sh
index bd5721c49c..3c0f7ff222 100755
--- a/scripts/bootstrap/bootstrap.sh
+++ b/scripts/bootstrap/bootstrap.sh
@@ -32,6 +32,7 @@ fi
: ${JAVA_VERSION:="1.8"}
: ${BAZEL_ARGS="--singlejar_top=//src/java_tools/singlejar:bootstrap_deploy.jar \
--javabuilder_top=//src/java_tools/buildjar:bootstrap_deploy.jar \
+ --genclass_top=//src/java_tools/buildjar:bootstrap_genclass_deploy.jar \
--ijar_top=//third_party/ijar"}
function bazel_bootstrap() {
diff --git a/scripts/get_all_bazel_paths.sh b/scripts/get_all_bazel_paths.sh
index c945ea0a08..b64ff407e2 100755
--- a/scripts/get_all_bazel_paths.sh
+++ b/scripts/get_all_bazel_paths.sh
@@ -25,8 +25,12 @@ function query() {
}
# Compile bazel
-([ -f "output/bazel" ] && [ -f "tools/jdk/JavaBuilder_deploy.jar" ] && [ -f "tools/jdk/ijar" ] \
- && [ -f "tools/jdk/SingleJar_deploy.jar" ] && [ -e "tools/jdk/jdk" ]) || ./compile.sh >&2 || exit $?
+([ -f "output/bazel" ] \
+ && [ -f "tools/jdk/JavaBuilder_deploy.jar" ] \
+ && [ -f "tools/jdk/ijar" ] \
+ && [ -f "tools/jdk/SingleJar_deploy.jar" ] \
+ && [ -f "tools/jdk/GenClass_deploy.jar" ] \
+ && [ -e "tools/jdk/jdk" ]) || ./compile.sh >&2 || exit $?
# Build almost everything.
# //third_party/ijar/test/... is disabled due to #273.
diff --git a/scripts/setup-eclipse.sh b/scripts/setup-eclipse.sh
index 2dd01050c1..5bac977d26 100755
--- a/scripts/setup-eclipse.sh
+++ b/scripts/setup-eclipse.sh
@@ -30,9 +30,12 @@ EXTRA_JARS="bazel-bazel/external/local-jdk/lib/tools.jar"
cd $(dirname $(dirname "$0"))
# Compile bazel
-([ -f "output/bazel" ] && [ -f "tools/jdk/JavaBuilder_deploy.jar" ] \
- && [ -f "tools/jdk/ijar" ] && [ -f "tools/jdk/SingleJar_deploy.jar" ] \
- && [ -e "tools/jdk/jdk" ]) || ./compile.sh >&2 || exit $?
+([ -f "output/bazel" ] \
+ && [ -f "tools/jdk/JavaBuilder_deploy.jar" ] \
+ && [ -f "tools/jdk/ijar" ] \
+ && [ -f "tools/jdk/SingleJar_deploy.jar" ] \
+ && [ -f "tools/jdk/GenClass_deploy.jar" ] \
+ && [ -e "tools/jdk/jdk" ]) || ./compile.sh >&2 || exit $?
# Make the script use actual bazel
function bazel() {
diff --git a/src/BUILD b/src/BUILD
index 9397380dd0..ab3a8cdd87 100644
--- a/src/BUILD
+++ b/src/BUILD
@@ -105,6 +105,7 @@ filegroup(
name = "tools",
srcs = [
"//src/java_tools/buildjar:JavaBuilder_deploy.jar",
+ "//src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass:GenClass_deploy.jar",
"//src/java_tools/singlejar:SingleJar_deploy.jar",
"//third_party/ijar",
],
diff --git a/src/java_tools/buildjar/BUILD b/src/java_tools/buildjar/BUILD
index 28773711e8..a9f6276cf0 100644
--- a/src/java_tools/buildjar/BUILD
+++ b/src/java_tools/buildjar/BUILD
@@ -151,6 +151,21 @@ java_library(
deps = [":BazelJavaCompiler"],
)
+# JarHelper library for GenClass so it can create the gen jar.
+java_library(
+ name = "jarhelper",
+ srcs = [
+ "java/com/google/devtools/build/buildjar/JarCreator.java",
+ "java/com/google/devtools/build/buildjar/JarHelper.java",
+ ],
+ visibility = [
+ "//src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass:__pkg__",
+ ],
+ deps = [
+ "//third_party:guava",
+ ],
+)
+
# For the -Xbootclasspath option of the java_test of buildjar
genrule(
name = "langtools-test",
@@ -206,3 +221,11 @@ bootstrap_java_binary(
visibility = ["//visibility:public"],
deps = [":skylark-deps"],
)
+
+bootstrap_java_binary(
+ name = "bootstrap_genclass",
+ srcs = glob(["java/com/google/devtools/build/buildjar/genclass/*.java"]),
+ main_class = "com.google.devtools.build.buildjar.genclass.GenClass",
+ visibility = ["//visibility:public"],
+ deps = [":skylark-deps"],
+)
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/BUILD b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/BUILD
new file mode 100644
index 0000000000..c5e0e4b1fa
--- /dev/null
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/BUILD
@@ -0,0 +1,16 @@
+java_binary(
+ name = "GenClass",
+ main_class = "com.google.devtools.build.buildjar.genclass.GenClass",
+ visibility = ["//visibility:public"],
+ runtime_deps = [":genclass_lib"],
+)
+
+java_library(
+ name = "genclass_lib",
+ srcs = glob(["*.java"]),
+ deps = [
+ "//src/java_tools/buildjar:jarhelper",
+ "//src/main/protobuf:proto_java_compilation",
+ "//third_party:guava",
+ ],
+)
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java
new file mode 100644
index 0000000000..7ae607ae2b
--- /dev/null
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass.java
@@ -0,0 +1,121 @@
+// 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 com.google.devtools.build.buildjar.genclass;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.buildjar.JarCreator;
+import com.google.devtools.build.buildjar.proto.JavaCompilation.CompilationUnit;
+import com.google.devtools.build.buildjar.proto.JavaCompilation.Manifest;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * GenClass post-processes the output of a Java compilation, and produces
+ * a jar containing only the class files for sources that were generated
+ * by annotation processors.
+ */
+public class GenClass {
+
+ public static void main(String[] args) throws IOException {
+ GenClassOptions options = GenClassOptionsParser.parse(Arrays.asList(args));
+ Manifest manifest = readManifest(options.manifest());
+ extractGeneratedClasses(options.classJar(), manifest, options.tempDir());
+ writeOutputJar(options);
+ }
+
+ /**
+ * Reads the compilation manifest.
+ */
+ private static Manifest readManifest(Path path) throws IOException {
+ Manifest manifest;
+ try (InputStream inputStream = Files.newInputStream(path)) {
+ manifest = Manifest.parseFrom(inputStream);
+ }
+ return manifest;
+ }
+
+ /**
+ * For each top-level class in the compilation, determine the path prefix
+ * of classes corresponding to that compilation unit.
+ *
+ * <p>Prefixes are used to correctly handle inner classes, e.g. the top-level
+ * class "c.g.Foo" may correspond to "c/g/Foo.class" and also
+ * "c/g/Foo$Inner.class" or "c/g/Foo$0.class".
+ */
+ @VisibleForTesting
+ static ImmutableSet<String> getGeneratedPrefixes(Manifest manifest) {
+ ImmutableSet.Builder<String> prefixes = ImmutableSet.builder();
+ for (CompilationUnit unit : manifest.getCompilationUnitList()) {
+ if (!unit.getGeneratedByAnnotationProcessor()) {
+ continue;
+ }
+ String pkg;
+ if (unit.hasPkg()) {
+ pkg = unit.getPkg().replace('.', '/') + "/";
+ } else {
+ pkg = "";
+ }
+ for (String toplevel : unit.getTopLevelList()) {
+ prefixes.add(pkg + toplevel);
+ }
+ }
+ return prefixes.build();
+ }
+
+ /**
+ * Unzip all the class files that correspond to annotation processor-
+ * generated sources into the temporary directory.
+ */
+ private static void extractGeneratedClasses(Path classJar, Manifest manifest, Path tempDir)
+ throws IOException {
+ ImmutableSet<String> generatedPrefixes = getGeneratedPrefixes(manifest);
+ try (JarFile jar = new JarFile(classJar.toFile())) {
+ Enumeration<JarEntry> entries = jar.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ String name = entry.getName();
+ if (!name.endsWith(".class")) {
+ continue;
+ }
+ String prefix = name.substring(0, name.length() - ".class".length());
+ int idx = prefix.indexOf('$');
+ if (idx > 0) {
+ prefix = prefix.substring(0, idx);
+ }
+ if (generatedPrefixes.contains(prefix)) {
+ Files.createDirectories(tempDir.resolve(name).getParent());
+ Files.copy(jar.getInputStream(entry), tempDir.resolve(name));
+ }
+ }
+ }
+ }
+
+ /** Writes the generated class files to the output jar. */
+ private static void writeOutputJar(GenClassOptions options) throws IOException {
+ JarCreator output = new JarCreator(options.outputJar().toString());
+ output.setCompression(true);
+ output.setNormalize(true);
+ output.addDirectory(options.tempDir().toString());
+ output.execute();
+ }
+}
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptions.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptions.java
new file mode 100644
index 0000000000..58b6544aec
--- /dev/null
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptions.java
@@ -0,0 +1,90 @@
+// 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 com.google.devtools.build.buildjar.genclass;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.nio.file.Path;
+
+/** The options for a {@GenClass} action. */
+public final class GenClassOptions {
+
+ /** A builder for {@link GenClassOptions}. */
+ public static final class Builder {
+ private Path manifest;
+ private Path classJar;
+ private Path outputJar;
+ private Path tempDir;
+
+ public Builder() {}
+
+ public void setManifest(Path manifest) {
+ this.manifest = manifest;
+ }
+
+ public void setClassJar(Path classJar) {
+ this.classJar = classJar;
+ }
+
+ public void setOutputJar(Path outputJar) {
+ this.outputJar = outputJar;
+ }
+
+ public void setTempDir(Path tempDir) {
+ this.tempDir = tempDir;
+ }
+
+ GenClassOptions build() {
+ return new GenClassOptions(manifest, classJar, outputJar, tempDir);
+ }
+ }
+
+ private final Path manifest;
+ private final Path classJar;
+ private final Path outputJar;
+ private final Path tempDir;
+
+ private GenClassOptions(Path manifest, Path classJar, Path outputJar, Path tempDir) {
+ this.manifest = checkNotNull(manifest);
+ this.classJar = checkNotNull(classJar);
+ this.outputJar = checkNotNull(outputJar);
+ this.tempDir = checkNotNull(tempDir);
+ }
+
+ /** The path to the compilation manifest proto. */
+ public Path manifest() {
+ return manifest;
+ }
+
+ /** The path to the compilation's class jar. */
+ public Path classJar() {
+ return classJar;
+ }
+
+ /** The path to write the output to. */
+ public Path outputJar() {
+ return outputJar;
+ }
+
+ /** The path to the temp directory. */
+ public Path tempDir() {
+ return tempDir;
+ }
+
+ /** Returns a builder for {@link GenClassOptions}. */
+ public static Builder builder() {
+ return new Builder();
+ }
+}
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptionsParser.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptionsParser.java
new file mode 100644
index 0000000000..80fb6ed5c5
--- /dev/null
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClassOptionsParser.java
@@ -0,0 +1,56 @@
+// 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 com.google.devtools.build.buildjar.genclass;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Iterator;
+
+/** A command line parser for {@link GenClassOptions}. */
+public class GenClassOptionsParser {
+ public static GenClassOptions parse(Iterable<String> args) {
+ Iterator<String> it = args.iterator();
+ GenClassOptions.Builder builder = GenClassOptions.builder();
+
+ while (it.hasNext()) {
+ String arg = it.next();
+ switch (arg) {
+ case "--manifest_proto":
+ builder.setManifest(readPath(it));
+ break;
+ case "--class_jar":
+ builder.setClassJar(readPath(it));
+ break;
+ case "--output_jar":
+ builder.setOutputJar(readPath(it));
+ break;
+ case "--temp_dir":
+ builder.setTempDir(readPath(it));
+ break;
+ default:
+ throw new IllegalArgumentException(
+ String.format("Unexpected argument: '%s' in %s", arg, args));
+ }
+ }
+ return builder.build();
+ }
+
+ private static Path readPath(Iterator<String> it) {
+ if (!it.hasNext()) {
+ throw new IllegalArgumentException(String.format("Expected more arguments"));
+ }
+ return Paths.get(it.next());
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
index 00fe3c9f32..8a88e0d8b7 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
@@ -51,11 +51,18 @@ public class BazelJavaRuleClasses {
PackageNameConstraint.ANY_SEGMENT, "java", "javatests");
public static final ImplicitOutputsFunction JAVA_BINARY_IMPLICIT_OUTPUTS =
- fromFunctions(JavaSemantics.JAVA_BINARY_CLASS_JAR, JavaSemantics.JAVA_BINARY_SOURCE_JAR,
- JavaSemantics.JAVA_BINARY_DEPLOY_JAR, JavaSemantics.JAVA_BINARY_DEPLOY_SOURCE_JAR);
+ fromFunctions(
+ JavaSemantics.JAVA_BINARY_CLASS_JAR,
+ JavaSemantics.JAVA_BINARY_GEN_JAR,
+ JavaSemantics.JAVA_BINARY_SOURCE_JAR,
+ JavaSemantics.JAVA_BINARY_DEPLOY_JAR,
+ JavaSemantics.JAVA_BINARY_DEPLOY_SOURCE_JAR);
static final ImplicitOutputsFunction JAVA_LIBRARY_IMPLICIT_OUTPUTS =
- fromFunctions(JavaSemantics.JAVA_LIBRARY_CLASS_JAR, JavaSemantics.JAVA_LIBRARY_SOURCE_JAR);
+ fromFunctions(
+ JavaSemantics.JAVA_LIBRARY_CLASS_JAR,
+ JavaSemantics.JAVA_LIBRARY_GEN_JAR,
+ JavaSemantics.JAVA_LIBRARY_SOURCE_JAR);
/**
* Common attributes for rules that depend on ijar.
@@ -99,6 +106,8 @@ public class BazelJavaRuleClasses {
.value(env.getLabel(JavaSemantics.JAVABUILDER_LABEL)))
.add(attr("$singlejar", LABEL).cfg(HOST)
.value(env.getLabel(JavaSemantics.SINGLEJAR_LABEL)))
+ .add(attr("$genclass", LABEL).cfg(HOST)
+ .value(env.getLabel(JavaSemantics.GENCLASS_LABEL)))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
index 11aefb8d13..4ca8ca2ab7 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
@@ -239,6 +239,7 @@ public class BazelJavaSemantics implements JavaSemantics {
List<String> jvmFlags,
Artifact classJar,
Artifact srcJar,
+ Artifact genJar,
Artifact gensrcJar,
ImmutableMap<Artifact, Artifact> compilationToRuntimeJarMap,
JavaCompilationHelper helper,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index c856d52f23..e617bca52d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -248,8 +248,13 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
}
JavaTargetAttributes resourceClasses = androidCommon.init(
- javaSemantics, androidSemantics, resourceApk, AndroidIdlProvider.EMPTY,
- ruleContext.getConfiguration().isCodeCoverageEnabled(), true);
+ javaSemantics,
+ androidSemantics,
+ resourceApk,
+ AndroidIdlProvider.EMPTY,
+ ruleContext.getConfiguration().isCodeCoverageEnabled(),
+ true /* collectJavaCompilationArgs */,
+ AndroidRuleClasses.ANDROID_BINARY_GEN_JAR);
if (resourceClasses == null) {
return null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
index a0321a0dc2..8af0c76269 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
@@ -40,6 +40,7 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDe
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.android.AndroidResourcesProvider.ResourceContainer;
import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.MultidexMode;
@@ -243,8 +244,12 @@ public class AndroidCommon {
Artifact outputDepsProto =
javacHelper.createOutputDepsProtoArtifact(binaryResourcesJar, javaArtifactsBuilder);
- javacHelper.createCompileActionWithInstrumentation(binaryResourcesJar, null /* gensrcJar */,
- outputDepsProto, javaArtifactsBuilder);
+ javacHelper.createCompileActionWithInstrumentation(
+ binaryResourcesJar,
+ null /* manifestProtoOutput */,
+ null /* gensrcJar */,
+ outputDepsProto,
+ javaArtifactsBuilder);
}
private void createJarJarActions(
@@ -308,7 +313,8 @@ public class AndroidCommon {
public JavaTargetAttributes init(
JavaSemantics javaSemantics, AndroidSemantics androidSemantics,
ResourceApk resourceApk, AndroidIdlProvider transitiveIdlImportData,
- boolean addCoverageSupport, boolean collectJavaCompilationArgs) {
+ boolean addCoverageSupport, boolean collectJavaCompilationArgs,
+ SafeImplicitOutputsFunction genClassJarImplicitOutput) {
ImmutableList<Artifact> extraSources =
resourceApk.isLegacy() || resourceApk.getResourceJavaSrcJar() == null
? ImmutableList.<Artifact>of()
@@ -337,7 +343,8 @@ public class AndroidCommon {
}
initJava(
- helper, artifactsBuilder, collectJavaCompilationArgs, resourceApk.getResourceJavaSrcJar());
+ helper, artifactsBuilder, collectJavaCompilationArgs, resourceApk.getResourceJavaSrcJar(),
+ genClassJarImplicitOutput);
return helper.getAttributes();
}
@@ -420,7 +427,8 @@ public class AndroidCommon {
JavaCompilationHelper helper,
JavaCompilationArtifacts.Builder javaArtifactsBuilder,
boolean collectJavaCompilationArgs,
- @Nullable Artifact additionalSourceJar) {
+ @Nullable Artifact additionalSourceJar,
+ SafeImplicitOutputsFunction genClassJarImplicitOutput) {
NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.<Artifact>stableOrder();
if (additionalSourceJar != null) {
filesBuilder.add(additionalSourceJar);
@@ -453,9 +461,14 @@ public class AndroidCommon {
filesBuilder.add(classJar);
- // The gensrcJar is only created if the target uses annotation processing. Otherwise,
+ // The gensrc jar is created only if the target uses annotation processing. Otherwise,
// it is null, and the source jar action will not depend on the compile action.
gensrcJar = helper.createGensrcJar(classJar);
+ Artifact manifestProtoOutput = helper.createManifestProtoOutput(classJar);
+
+ // AndroidBinary will pass its -gen.jar output, and AndroidLibrary will pass its own.
+ Artifact genClassJar = ruleContext.getImplicitOutputArtifact(genClassJarImplicitOutput);
+ helper.createGenJarAction(classJar, manifestProtoOutput, genClassJar);
srcJar = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_LIBRARY_SOURCE_JAR);
helper.createSourceJarAction(srcJar, gensrcJar);
@@ -465,8 +478,8 @@ public class AndroidCommon {
if (outputDepsProto != null) {
compileTimeDependenciesBuilder.add(outputDepsProto);
}
- helper.createCompileActionWithInstrumentation(classJar, gensrcJar, outputDepsProto,
- javaArtifactsBuilder);
+ helper.createCompileActionWithInstrumentation(classJar, manifestProtoOutput, gensrcJar,
+ outputDepsProto, javaArtifactsBuilder);
compileTimeDependencyArtifacts = compileTimeDependenciesBuilder.build();
filesToBuild = filesBuilder.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
index 338282bc4e..fa40809201 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
@@ -37,6 +37,7 @@ import com.google.devtools.build.lib.rules.java.JavaCommon;
import com.google.devtools.build.lib.rules.java.JavaNeverlinkInfoProvider;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
+import com.google.devtools.build.lib.rules.java.JavaTargetAttributes;
import com.google.devtools.build.lib.rules.java.JavaUtil;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -94,8 +95,15 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory {
false,
null /* proguardCfgOut */);
- if (androidCommon.init(javaSemantics, androidSemantics,
- resourceApk, transitiveIdlImportData, false, true) == null) {
+ JavaTargetAttributes javaTargetAttributes = androidCommon.init(
+ javaSemantics,
+ androidSemantics,
+ resourceApk,
+ transitiveIdlImportData,
+ false /* addCoverageSupport */,
+ true /* collectJavaCompilationArgs */,
+ AndroidRuleClasses.ANDROID_LIBRARY_GEN_JAR);
+ if (javaTargetAttributes == null) {
return null;
}
@@ -144,8 +152,16 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory {
JavaCommon javaCommon = new JavaCommon(ruleContext, javaSemantics);
AndroidCommon androidCommon = new AndroidCommon(ruleContext, javaCommon);
ResourceApk resourceApk = ResourceApk.fromTransitiveResources(transitiveResources);
- if (androidCommon.init(javaSemantics, androidSemantics,
- resourceApk, transitiveIdlImportData, false, true) == null) {
+
+ JavaTargetAttributes javaTargetAttributes = androidCommon.init(
+ javaSemantics,
+ androidSemantics,
+ resourceApk,
+ transitiveIdlImportData,
+ false /* addCoverageSupport */,
+ true /* collectJavaCompilationArgs */,
+ AndroidRuleClasses.ANDROID_LIBRARY_GEN_JAR);
+ if (javaTargetAttributes == null) {
return null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index d14b307fed..fe2a2f9c46 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -65,6 +65,8 @@ public final class AndroidRuleClasses {
JavaSemantics.JAVA_LIBRARY_SOURCE_JAR;
public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_CLASS_JAR =
JavaSemantics.JAVA_LIBRARY_CLASS_JAR;
+ public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_GEN_JAR =
+ JavaSemantics.JAVA_LIBRARY_GEN_JAR;
public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_JACK_FILE =
fromTemplates("lib%{name}.jack");
public static final SafeImplicitOutputsFunction ANDROID_LIBRARY_AAR =
@@ -83,6 +85,8 @@ public final class AndroidRuleClasses {
fromTemplates("%{name}_unsigned.apk");
public static final SafeImplicitOutputsFunction ANDROID_BINARY_SIGNED_APK =
fromTemplates("%{name}_signed.apk");
+ public static final SafeImplicitOutputsFunction ANDROID_BINARY_GEN_JAR =
+ JavaSemantics.JAVA_BINARY_GEN_JAR;
public static final SafeImplicitOutputsFunction ANDROID_BINARY_DEPLOY_JAR =
fromTemplates("%{name}_deploy.jar");
public static final SafeImplicitOutputsFunction ANDROID_BINARY_PROGUARD_JAR =
@@ -211,10 +215,11 @@ public final class AndroidRuleClasses {
@Override
public Iterable<String> getImplicitOutputs(AttributeMap rule) {
boolean mapping = rule.get("proguard_generate_mapping", Type.BOOLEAN);
- List<SafeImplicitOutputsFunction> functions = Lists.newArrayListWithCapacity(6);
+ List<SafeImplicitOutputsFunction> functions = Lists.newArrayList();
functions.add(AndroidRuleClasses.ANDROID_BINARY_APK);
functions.add(AndroidRuleClasses.ANDROID_BINARY_UNSIGNED_APK);
functions.add(AndroidRuleClasses.ANDROID_BINARY_DEPLOY_JAR);
+ functions.add(AndroidRuleClasses.ANDROID_BINARY_GEN_JAR);
// The below is a hack to support configurable attributes (proguard_specs seems like
// too valuable an attribute to make nonconfigurable, and we don't currently
@@ -251,23 +256,25 @@ public final class AndroidRuleClasses {
new ImplicitOutputsFunction() {
@Override
public Iterable<String> getImplicitOutputs(AttributeMap attributes) {
+
+ ImmutableList.Builder<SafeImplicitOutputsFunction> implicitOutputs =
+ ImmutableList.builder();
+
+ implicitOutputs.add(
+ AndroidRuleClasses.ANDROID_LIBRARY_CLASS_JAR,
+ AndroidRuleClasses.ANDROID_LIBRARY_GEN_JAR,
+ AndroidRuleClasses.ANDROID_LIBRARY_SOURCE_JAR,
+ AndroidRuleClasses.ANDROID_LIBRARY_JACK_FILE,
+ AndroidRuleClasses.ANDROID_LIBRARY_AAR);
+
if (LocalResourceContainer.definesAndroidResources(attributes)) {
- return fromFunctions(
- AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR,
- AndroidRuleClasses.ANDROID_RESOURCES_APK,
- AndroidRuleClasses.ANDROID_LIBRARY_CLASS_JAR,
- AndroidRuleClasses.ANDROID_LIBRARY_JACK_FILE,
- AndroidRuleClasses.ANDROID_LIBRARY_SOURCE_JAR,
- AndroidRuleClasses.ANDROID_LIBRARY_AAR,
- AndroidRuleClasses.ANDROID_R_TXT)
- .getImplicitOutputs(attributes);
+ implicitOutputs.add(
+ AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR,
+ AndroidRuleClasses.ANDROID_RESOURCES_APK,
+ AndroidRuleClasses.ANDROID_R_TXT);
}
- return fromFunctions(
- AndroidRuleClasses.ANDROID_LIBRARY_CLASS_JAR,
- AndroidRuleClasses.ANDROID_LIBRARY_JACK_FILE,
- AndroidRuleClasses.ANDROID_LIBRARY_SOURCE_JAR,
- AndroidRuleClasses.ANDROID_LIBRARY_AAR)
- .getImplicitOutputs(attributes);
+
+ return fromFunctions(implicitOutputs.build()).getImplicitOutputs(attributes);
}
};
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
index 2a6b77f5ec..763bcf6acc 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
@@ -149,13 +149,18 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
common.setJavaCompilationArtifacts(javaArtifactsBuilder.build());
- // The gensrcJar is only created if the target uses annotation processing. Otherwise,
+ // The gensrc jar is created only if the target uses annotation processing. Otherwise,
// it is null, and the source jar action will not depend on the compile action.
Artifact gensrcJar = helper.createGensrcJar(classJar);
+ Artifact manifestProtoOutput = helper.createManifestProtoOutput(classJar);
- helper.createCompileAction(classJar, gensrcJar, outputDepsProto, instrumentationMetadata);
+ helper.createCompileAction(
+ classJar, manifestProtoOutput, gensrcJar, outputDepsProto, instrumentationMetadata);
helper.createSourceJarAction(srcJar, gensrcJar);
+ Artifact genClassJar = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_GEN_JAR);
+ helper.createGenJarAction(classJar, manifestProtoOutput, genClassJar);
+
common.setClassPathFragment(new ClasspathConfiguredFragment(
common.getJavaCompilationArtifacts(), attributes, false));
@@ -187,7 +192,7 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
RuleConfiguredTargetBuilder builder =
new RuleConfiguredTargetBuilder(ruleContext);
- semantics.addProviders(ruleContext, common, jvmFlags, classJar, srcJar, gensrcJar,
+ semantics.addProviders(ruleContext, common, jvmFlags, classJar, srcJar, genClassJar, gensrcJar,
ImmutableMap.<Artifact, Artifact>of(), helper, filesBuilder, builder);
NestedSet<Artifact> filesToBuild = filesBuilder.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
index 1cfecc6ed4..b570c46e27 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
@@ -21,9 +21,13 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -44,6 +48,12 @@ import javax.annotation.Nullable;
* Also supports the creation of resource and source only Jars.
*/
public class JavaCompilationHelper extends BaseJavaCompilationHelper {
+
+ /**
+ * Maximum memory to use for GenClass for generating the gen jar.
+ */
+ private static final String GENCLASS_MAX_MEMORY = "-Xmx64m";
+
private Artifact outputDepsProtoArtifact;
private JavaTargetAttributes.Builder attributes;
private JavaTargetAttributes builtAttributes;
@@ -79,14 +89,20 @@ public class JavaCompilationHelper extends BaseJavaCompilationHelper {
* Creates the Action that compiles Java source files.
*
* @param outputJar the class jar Artifact to create with the Action
+ * @param manifestProtoOutput the output artifact for the manifest proto emitted from JavaBuilder
* @param gensrcOutputJar the generated sources jar Artifact to create with the Action
* (null if no sources will be generated).
* @param outputDepsProto the compiler-generated jdeps file to create with the Action
* (null if not requested)
* @param outputMetadata metadata file (null if no instrumentation is needed).
*/
- public void createCompileAction(Artifact outputJar, @Nullable Artifact gensrcOutputJar,
- @Nullable Artifact outputDepsProto, @Nullable Artifact outputMetadata) {
+ public void createCompileAction(
+ Artifact outputJar,
+ Artifact manifestProtoOutput,
+ @Nullable Artifact gensrcOutputJar,
+ @Nullable Artifact outputDepsProto,
+ @Nullable Artifact outputMetadata) {
+
JavaTargetAttributes attributes = getAttributes();
JavaCompileAction.Builder builder = createJavaCompileActionBuilder(semantics);
builder.setClasspathEntries(attributes.getCompileTimeClassPath());
@@ -103,6 +119,7 @@ public class JavaCompilationHelper extends BaseJavaCompilationHelper {
builder.setJavaBuilderJar(getJavaBuilderJar());
builder.addTranslations(getTranslations());
builder.setOutputJar(outputJar);
+ builder.setManifestProtoOutput(manifestProtoOutput);
builder.setGensrcOutputJar(gensrcOutputJar);
builder.setOutputDepsProto(outputDepsProto);
builder.setMetadata(outputMetadata);
@@ -130,13 +147,22 @@ public class JavaCompilationHelper extends BaseJavaCompilationHelper {
* coverage.
*
* @param outputJar the class jar Artifact to create with the Action
+ * @param manifestProtoOutput the output artifact for the manifest proto emitted from JavaBuilder
* @param gensrcJar the generated sources jar Artifact to create with the Action
* @param outputDepsProto the compiler-generated jdeps file to create with the Action
* @param javaArtifactsBuilder the build to store the instrumentation metadata in
*/
- public void createCompileActionWithInstrumentation(Artifact outputJar, Artifact gensrcJar,
- Artifact outputDepsProto, JavaCompilationArtifacts.Builder javaArtifactsBuilder) {
- createCompileAction(outputJar, gensrcJar, outputDepsProto,
+ public void createCompileActionWithInstrumentation(
+ Artifact outputJar,
+ Artifact manifestProtoOutput,
+ @Nullable Artifact gensrcJar,
+ @Nullable Artifact outputDepsProto,
+ JavaCompilationArtifacts.Builder javaArtifactsBuilder) {
+ createCompileAction(
+ outputJar,
+ manifestProtoOutput,
+ gensrcJar,
+ outputDepsProto,
createInstrumentationMetadata(outputJar, javaArtifactsBuilder));
}
@@ -170,16 +196,17 @@ public class JavaCompilationHelper extends BaseJavaCompilationHelper {
}
/**
- * Returns the artifact for a jar file containing source files that were generated by an
- * annotation processor or null if no annotation processors are used.
+ * Returns the artifact for a jar file containing source files that were generated by
+ * annotation processors or null if no annotation processors are used.
*/
public Artifact createGensrcJar(@Nullable Artifact outputJar) {
- if (!usesAnnotationProcessing()) {
+ if (usesAnnotationProcessing()) {
+ return getAnalysisEnvironment().getDerivedArtifact(
+ FileSystemUtils.appendWithoutExtension(outputJar.getRootRelativePath(), "-gensrc"),
+ outputJar.getRoot());
+ } else {
return null;
}
- return getAnalysisEnvironment().getDerivedArtifact(
- FileSystemUtils.appendWithoutExtension(outputJar.getRootRelativePath(), "-gensrc"),
- outputJar.getRoot());
}
/**
@@ -190,9 +217,53 @@ public class JavaCompilationHelper extends BaseJavaCompilationHelper {
return getJavacOpts().contains("-processor") || !attributes.getProcessorNames().isEmpty();
}
+ /**
+ * Returns the artifact for the manifest proto emitted from JavaBuilder. For example, for a
+ * class jar foo.jar, returns "foo.jar_manifest_proto".
+ *
+ * @param outputJar The artifact for the class jar emitted form JavaBuilder
+ * @return The output artifact for the manifest proto emitted from JavaBuilder
+ */
+ public Artifact createManifestProtoOutput(Artifact outputJar) {
+ return getAnalysisEnvironment().getDerivedArtifact(
+ FileSystemUtils.appendExtension(outputJar.getRootRelativePath(), "_manifest_proto"),
+ outputJar.getRoot());
+ }
+
+ /**
+ * Creates the action for creating the gen jar.
+ *
+ * @param classJar The artifact for the class jar emitted from JavaBuilder
+ * @param manifestProto The artifact for the manifest proto emitted from JavaBuilder
+ * @param genClassJar The artifact for the gen jar to output
+ */
+ public void createGenJarAction(Artifact classJar, Artifact manifestProto,
+ Artifact genClassJar) {
+ getRuleContext().registerAction(new SpawnAction.Builder()
+ .addInput(manifestProto)
+ .addInput(classJar)
+ .addOutput(genClassJar)
+ .addTransitiveInputs(JavaCompilationHelper.getHostJavabaseInputs(getRuleContext()))
+ .setJarExecutable(
+ getRuleContext().getHostConfiguration().getFragment(Jvm.class).getJavaExecutable(),
+ getRuleContext().getPrerequisiteArtifact("$genclass", Mode.HOST),
+ ImmutableList.of("-client", GENCLASS_MAX_MEMORY))
+ .setCommandLine(CustomCommandLine.builder()
+ .addExecPath("--manifest_proto", manifestProto)
+ .addExecPath("--class_jar", classJar)
+ .addExecPath("--output_jar", genClassJar)
+ .add("--temp_dir").addPath(tempDir(genClassJar))
+ .build())
+ .useParameterFile(ParameterFileType.SHELL_QUOTED)
+ .setProgressMessage("Building genclass jar " + genClassJar.prettyPrint())
+ .setMnemonic("JavaSourceJar")
+ .build(getRuleContext()));
+ }
+
public Artifact getOutputDepsProtoArtifact() {
return outputDepsProtoArtifact;
}
+
/**
* Creates the jdeps file artifact if needed. Returns null if the target can't emit dependency
* information (i.e there is no compilation step, the target acts as an alias).
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java
index 6b9fcbb9a8..4b6b50bdb9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java
@@ -19,6 +19,8 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -64,6 +66,7 @@ import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
@@ -488,6 +491,7 @@ public class JavaCompileAction extends AbstractAction {
PathFragment tempDirectory,
Artifact outputJar,
Artifact gensrcOutputJar,
+ Artifact manifestProto,
boolean compressJar,
Artifact outputDepsProto,
final NestedSet<Artifact> classpath,
@@ -518,11 +522,18 @@ public class JavaCompileAction extends AbstractAction {
result.addExecPath("--output", outputJar);
}
- if (gensrcOutputJar != null) {
+ if (sourceGenDirectory != null) {
result.add("--sourcegendir").addPath(sourceGenDirectory);
+ }
+
+ if (gensrcOutputJar != null) {
result.addExecPath("--generated_sources_output", gensrcOutputJar);
}
+ if (manifestProto != null) {
+ result.addExecPath("--output_manifest_proto", manifestProto);
+ }
+
if (compressJar) {
result.add("--compress_jar");
}
@@ -730,6 +741,7 @@ public class JavaCompileAction extends AbstractAction {
private List<Artifact> javabaseInputs = ImmutableList.of();
private Artifact outputJar;
private Artifact gensrcOutputJar;
+ private Artifact manifestProtoOutput;
private Artifact outputDepsProto;
private Artifact paramFile;
private Artifact metadata;
@@ -829,19 +841,12 @@ public class JavaCompileAction extends AbstractAction {
Preconditions.checkState(javaExecutable.isAbsolute() ^ !javabaseInputs.isEmpty(),
javaExecutable);
- Collection<Artifact> outputs;
- ImmutableList.Builder<Artifact> outputsBuilder = ImmutableList.builder();
- outputsBuilder.add(outputJar);
- if (metadata != null) {
- outputsBuilder.add(metadata);
- }
- if (gensrcOutputJar != null) {
- outputsBuilder.add(gensrcOutputJar);
- }
- if (outputDepsProto != null) {
- outputsBuilder.add(outputDepsProto);
- }
- outputs = outputsBuilder.build();
+ Collection<Artifact> outputs = Collections2.filter(Arrays.asList(
+ outputJar,
+ metadata,
+ gensrcOutputJar,
+ manifestProtoOutput,
+ outputDepsProto), Predicates.notNull());
CustomCommandLine.Builder paramFileContentsBuilder = javaCompileCommandLine(
semantics,
@@ -851,6 +856,7 @@ public class JavaCompileAction extends AbstractAction {
tempDirectory,
outputJar,
gensrcOutputJar,
+ manifestProtoOutput,
compressJar,
outputDepsProto,
classpathEntries,
@@ -935,6 +941,11 @@ public class JavaCompileAction extends AbstractAction {
return this;
}
+ public Builder setManifestProtoOutput(Artifact manifestProtoOutput) {
+ this.manifestProtoOutput = manifestProtoOutput;
+ return this;
+ }
+
public Builder setOutputDepsProto(Artifact outputDepsProto) {
this.outputDepsProto = outputDepsProto;
return this;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
index 477563ff1e..77850f9a99 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java
@@ -111,8 +111,17 @@ public class JavaImport implements RuleConfiguredTargetFactory {
filesBuilder.addAll(jars);
semantics.addProviders(
- ruleContext, common, ImmutableList.<String>of(), null,
- srcJar, null, compilationToRuntimeJarMap.build(), helper, filesBuilder, ruleBuilder);
+ ruleContext,
+ common,
+ ImmutableList.<String>of(),
+ null /* classJar */,
+ srcJar /* srcJar */,
+ null /* genJar */,
+ null /* gensrcJar */,
+ compilationToRuntimeJarMap.build(),
+ helper,
+ filesBuilder,
+ ruleBuilder);
NestedSet<Artifact> filesToBuild = filesBuilder.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
index b22f172945..1355e6f23f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
@@ -117,14 +117,19 @@ public class JavaLibrary implements RuleConfiguredTargetFactory {
filesBuilder.add(classJar);
- // The gensrcJar is only created if the target uses annotation processing. Otherwise,
- // it is null, and the source jar action will not depend on the compile action.
+ // The gensrc jar is created only if the target uses annotation processing.
+ // Otherwise, it is null, and the source jar action will not depend on the compile action.
Artifact gensrcJar = helper.createGensrcJar(classJar);
+ Artifact manifestProtoOutput = helper.createManifestProtoOutput(classJar);
+
+ Artifact genClassJar = ruleContext.getImplicitOutputArtifact(
+ JavaSemantics.JAVA_LIBRARY_GEN_JAR);
+ helper.createGenJarAction(classJar, manifestProtoOutput, genClassJar);
Artifact outputDepsProto = helper.createOutputDepsProtoArtifact(classJar, javaArtifactsBuilder);
- helper.createCompileActionWithInstrumentation(classJar, gensrcJar, outputDepsProto,
- javaArtifactsBuilder);
+ helper.createCompileActionWithInstrumentation(classJar, manifestProtoOutput, gensrcJar,
+ outputDepsProto, javaArtifactsBuilder);
helper.createSourceJarAction(srcJar, gensrcJar);
if ((attributes.hasSourceFiles() || attributes.hasSourceJars()) && jar != null) {
@@ -209,7 +214,7 @@ public class JavaLibrary implements RuleConfiguredTargetFactory {
new RuleConfiguredTargetBuilder(ruleContext);
semantics.addProviders(
- ruleContext, common, ImmutableList.<String>of(), classJar, srcJar, gensrcJar,
+ ruleContext, common, ImmutableList.<String>of(), classJar, srcJar, genClassJar, gensrcJar,
ImmutableMap.<Artifact, Artifact>of(), helper, filesBuilder, builder);
NestedSet<Artifact> filesToBuild = filesBuilder.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
index a28d7fd1af..b8210e226c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
@@ -239,7 +239,12 @@ public final class JavaLibraryHelper {
JavaCompilationHelper helper =
new JavaCompilationHelper(ruleContext, semantics, javacOpts, attributes);
Artifact outputDepsProto = helper.createOutputDepsProtoArtifact(output, artifactsBuilder);
- helper.createCompileAction(output, null, outputDepsProto, null);
+ helper.createCompileAction(
+ output,
+ null /* manifestProtoOutput */,
+ null /* gensrcOutputJar */,
+ outputDepsProto,
+ null /* outputMetadata */);
helper.createCompileTimeJarAction(output, outputDepsProto, artifactsBuilder);
artifactsBuilder.addRuntimeJar(output);
JavaCompilationArtifacts compilationArtifacts = artifactsBuilder.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
index 0e42112b1f..32549643c2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java
@@ -46,6 +46,7 @@ public class JavaOptions extends FragmentOptions {
static final String DEFAULT_LANGTOOLS_EXTDIR = "//tools/jdk:extdir";
static final String DEFAULT_JAVABUILDER = "//tools/jdk:JavaBuilder_deploy.jar";
static final String DEFAULT_SINGLEJAR = "//tools/jdk:SingleJar_deploy.jar";
+ static final String DEFAULT_GENCLASS = "//tools/jdk:GenClass_deploy.jar";
static final String DEFAULT_JAVABASE = "//tools/jdk:jdk";
static final String DEFAULT_IJAR = "//tools/jdk:ijar";
static final String DEFAULT_TOOLCHAIN = "//tools/jdk:toolchain";
@@ -225,6 +226,13 @@ public class JavaOptions extends FragmentOptions {
help = "Label of the filegroup that contains the SingleJar jar.")
public Label singleJarTop;
+ @Option(name = "genclass_top",
+ defaultValue = DEFAULT_GENCLASS,
+ category = "version",
+ converter = LabelConverter.class,
+ help = "Label of the filegroup that contains the GenClass jar.")
+ public Label genClassTop;
+
@Option(name = "ijar_top",
defaultValue = DEFAULT_IJAR,
category = "version",
@@ -295,6 +303,7 @@ public class JavaOptions extends FragmentOptions {
host.javaBuilderTop = javaBuilderTop;
host.javaToolchain = javaToolchain;
host.singleJarTop = singleJarTop;
+ host.genClassTop = genClassTop;
host.iJarTop = iJarTop;
// Java builds often contain complicated code generators for which
@@ -316,6 +325,7 @@ public class JavaOptions extends FragmentOptions {
}
labelMap.put("javabuilder", javaBuilderTop);
labelMap.put("singlejar", singleJarTop);
+ labelMap.put("genclass", genClassTop);
labelMap.put("ijar", iJarTop);
labelMap.put("java_toolchain", javaToolchain);
labelMap.putAll("translation", getTranslationLabels());
@@ -333,6 +343,7 @@ public class JavaOptions extends FragmentOptions {
result.put("JAVAC_EXTDIR", ImmutableSet.of(javacExtdir));
result.put("JAVABUILDER", ImmutableSet.of(javaBuilderTop));
result.put("SINGLEJAR", ImmutableSet.of(singleJarTop));
+ result.put("GENCLASS", ImmutableSet.of(genClassTop));
result.put("IJAR", ImmutableSet.of(iJarTop));
result.put("JAVA_TOOLCHAIN", ImmutableSet.of(javaToolchain));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
index a68dcd46d2..5f17262706 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
@@ -55,12 +55,18 @@ public interface JavaSemantics {
public static final SafeImplicitOutputsFunction JAVA_LIBRARY_CLASS_JAR =
fromTemplates("lib%{name}.jar");
+ public static final SafeImplicitOutputsFunction JAVA_LIBRARY_GEN_JAR =
+ fromTemplates("lib%{name}-gen.jar");
public static final SafeImplicitOutputsFunction JAVA_LIBRARY_SOURCE_JAR =
fromTemplates("lib%{name}-src.jar");
+
public static final SafeImplicitOutputsFunction JAVA_BINARY_CLASS_JAR =
fromTemplates("%{name}.jar");
+ public static final SafeImplicitOutputsFunction JAVA_BINARY_GEN_JAR =
+ fromTemplates("%{name}-gen.jar");
public static final SafeImplicitOutputsFunction JAVA_BINARY_SOURCE_JAR =
fromTemplates("%{name}-src.jar");
+
public static final SafeImplicitOutputsFunction JAVA_BINARY_DEPLOY_JAR =
fromTemplates("%{name}_deploy.jar");
public static final SafeImplicitOutputsFunction JAVA_BINARY_DEPLOY_SOURCE_JAR =
@@ -119,6 +125,12 @@ public interface JavaSemantics {
public static final String SINGLEJAR_LABEL = "//tools/defaults:singlejar";
/**
+ * Label of the GenClass JAR used for creating the jar for classes from sources generated from
+ * annotation processors.
+ */
+ public static final String GENCLASS_LABEL = "//tools/defaults:genclass";
+
+ /**
* Label of pseudo-cc_binary that tells Blaze a java target's JAVABIN is never to be replaced by
* the contents of --java_launcher; only the JDK's launcher will ever be used.
*/
@@ -279,6 +291,7 @@ public interface JavaSemantics {
List<String> jvmFlags,
Artifact classJar,
Artifact srcJar,
+ Artifact genJar,
Artifact gensrcJar,
ImmutableMap<Artifact, Artifact> compilationToRuntimeJarMap,
JavaCompilationHelper helper,
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
index 8a66f0f006..7c922494e2 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
@@ -56,7 +56,7 @@ public class BazelAnalysisMock extends AnalysisMock {
// "dummy" is needed so that RedirectChaser stops here
"filegroup(name='java', srcs = ['jdk/jre/bin/java', 'dummy'])",
"exports_files(['JavaBuilder_deploy.jar','SingleJar_deploy.jar',",
- " 'JavaBuilderCanary_deploy.jar', 'ijar'])");
+ " 'JavaBuilderCanary_deploy.jar', 'ijar', 'GenClass_deploy.jar'])");
config.create("tools/cpp/BUILD",
"filegroup(name = 'toolchain', srcs = [':cc-compiler-local', ':empty'])",
"cc_toolchain(name = 'cc-compiler-k8', all_files = ':empty', compiler_files = ':empty',",
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index 116b1367e6..3880ce0258 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -21,6 +21,7 @@ filegroup(
"//external:jdk-default",
"//src:bazel",
"//src/java_tools/buildjar:JavaBuilder_deploy.jar",
+ "//src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass:GenClass_deploy.jar",
"//src/java_tools/singlejar:SingleJar_deploy.jar",
"//src/test/shell:bashunit",
"//third_party:srcs",
diff --git a/src/test/shell/bazel/test-setup.sh b/src/test/shell/bazel/test-setup.sh
index 21eb3772fc..1d71f29d08 100755
--- a/src/test/shell/bazel/test-setup.sh
+++ b/src/test/shell/bazel/test-setup.sh
@@ -212,6 +212,7 @@ function create_new_workspace() {
ln -s "${javabuilder_path}" tools/jdk/JavaBuilder_deploy.jar
ln -s "${singlejar_path}" tools/jdk/SingleJar_deploy.jar
+ ln -s "${genclass_path}" tools/jdk/GenClass_deploy.jar
ln -s "${ijar_path}" tools/jdk/ijar
setup_android_support
diff --git a/src/test/shell/bazel/testenv.sh b/src/test/shell/bazel/testenv.sh
index 12afe3635f..44d15f35c0 100755
--- a/src/test/shell/bazel/testenv.sh
+++ b/src/test/shell/bazel/testenv.sh
@@ -41,6 +41,7 @@ EXTRA_BAZELRC="build --java_langtools=//tools/jdk:test-langtools"
javabuilder_path="${TEST_SRCDIR}/src/java_tools/buildjar/JavaBuilder_deploy.jar"
langtools_path="${TEST_SRCDIR}/third_party/java/jdk/langtools/javac.jar"
singlejar_path="${TEST_SRCDIR}/src/java_tools/singlejar/SingleJar_deploy.jar"
+genclass_path="${TEST_SRCDIR}/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/genclass/GenClass_deploy.jar"
ijar_path="${TEST_SRCDIR}/third_party/ijar/ijar"
# Third-party
diff --git a/tools/jdk/BUILD b/tools/jdk/BUILD
index de26dd9ecd..e15e8bf175 100644
--- a/tools/jdk/BUILD
+++ b/tools/jdk/BUILD
@@ -82,6 +82,7 @@ exports_files([
"JavaBuilder_deploy.jar",
"ijar",
"SingleJar_deploy.jar",
+ "GenClass_deploy.jar",
])
filegroup(