diff options
author | 2015-07-08 18:18:33 +0000 | |
---|---|---|
committer | 2015-07-10 17:15:23 +0000 | |
commit | d3f7eda5548fae0d9c022d9e1a0761b8e8ba22a6 (patch) | |
tree | 8cbca5cb9298446be3ac2c539526b7714a647790 /src/main/java/com/google/devtools/build/lib | |
parent | 525019b7bd8810ef8401ecb80247fa4226eba8c2 (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
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
14 files changed, 250 insertions, 69 deletions
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, |