aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java161
1 files changed, 149 insertions, 12 deletions
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 fec64a367a..9ae2dbee79 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
@@ -23,6 +23,8 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
+import com.google.devtools.build.lib.analysis.FileProvider;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
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;
@@ -34,6 +36,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaClasspathMode;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
+import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -50,8 +53,12 @@ import javax.annotation.Nullable;
* <p>
* Also supports the creation of resource and source only Jars.
*/
-public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
+public final class JavaCompilationHelper {
+ private final RuleContext ruleContext;
+ private final JavaToolchainProvider javaToolchain;
+ private final NestedSet<Artifact> hostJavabase;
+ private final Iterable<Artifact> jacocoInstrumentation;
private JavaTargetAttributes.Builder attributes;
private JavaTargetAttributes builtAttributes;
private final ImmutableList<String> customJavacOpts;
@@ -59,13 +66,18 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
private final List<Artifact> translations = new ArrayList<>();
private boolean translationsFrozen;
private final JavaSemantics semantics;
- private final String implicitAttributesSuffix;
+
+ private static final String DEFAULT_ATTRIBUTES_SUFFIX = "";
public JavaCompilationHelper(RuleContext ruleContext, JavaSemantics semantics,
ImmutableList<String> javacOpts, JavaTargetAttributes.Builder attributes,
- String implicitAttributesSuffix) {
- super(ruleContext, implicitAttributesSuffix);
- this.implicitAttributesSuffix = implicitAttributesSuffix;
+ JavaToolchainProvider javaToolchainProvider,
+ NestedSet<Artifact> hostJavabase,
+ Iterable<Artifact> jacocoInstrumentation) {
+ this.ruleContext = ruleContext;
+ this.javaToolchain = javaToolchainProvider;
+ this.hostJavabase = hostJavabase;
+ this.jacocoInstrumentation = jacocoInstrumentation;
this.attributes = attributes;
this.customJavacOpts = javacOpts;
this.customJavacJvmOpts = javaToolchain.getJvmOptions();
@@ -74,7 +86,10 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
public JavaCompilationHelper(RuleContext ruleContext, JavaSemantics semantics,
ImmutableList<String> javacOpts, JavaTargetAttributes.Builder attributes) {
- this(ruleContext, semantics, javacOpts, attributes, "");
+ this(ruleContext, semantics, javacOpts, attributes,
+ getJavaToolchainProvider(ruleContext),
+ getHostJavabaseInputsNonStatic(ruleContext),
+ getInstrumentationJars(ruleContext));
}
public JavaCompilationHelper(RuleContext ruleContext, JavaSemantics semantics,
@@ -138,7 +153,7 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
builder.setGensrcOutputJar(gensrcOutputJar);
builder.setOutputDepsProto(outputDepsProto);
builder.setMetadata(outputMetadata);
- builder.setInstrumentationJars(getInstrumentationJars());
+ builder.setInstrumentationJars(jacocoInstrumentation);
builder.addSourceFiles(attributes.getSourceFiles());
builder.addSourceJars(attributes.getSourceJars());
builder.setJavacOpts(customJavacOpts);
@@ -267,7 +282,7 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
JavaTargetAttributes attributes = getAttributes();
JavaHeaderCompileAction.Builder builder =
- new JavaHeaderCompileAction.Builder(getRuleContext(), implicitAttributesSuffix);
+ new JavaHeaderCompileAction.Builder(getRuleContext());
builder.addSourceFiles(attributes.getSourceFiles());
builder.addSourceJars(attributes.getSourceJars());
builder.setClasspathEntries(attributes.getCompileTimeClassPath());
@@ -287,9 +302,9 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
builder.setDirectJars(attributes.getDirectJars());
builder.setRuleKind(attributes.getRuleKind());
builder.setTargetLabel(attributes.getTargetLabel());
- builder.setJavaBaseInputs(getHostJavabaseInputsNonStatic(ruleContext));
+ builder.setJavaBaseInputs(hostJavabase);
builder.setJavacJar(javaToolchain.getJavac());
- builder.build();
+ builder.build(javaToolchain);
artifactBuilder.setCompileTimeDependencies(headerDeps);
return headerJar;
@@ -451,7 +466,7 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
JavaCompileAction.Builder builder = new JavaCompileAction.Builder(ruleContext, semantics);
builder.setJavaExecutable(
ruleContext.getHostConfiguration().getFragment(Jvm.class).getJavaExecutable());
- builder.setJavaBaseInputs(getHostJavabaseInputsNonStatic(ruleContext));
+ builder.setJavaBaseInputs(hostJavabase);
builder.setTargetLabel(ruleContext.getLabel());
return builder;
}
@@ -518,7 +533,7 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
if (shouldUseHeaderCompilation()) {
jar = createHeaderCompilationAction(runtimeJar, builder);
} else if (getJavaConfiguration().getUseIjars()) {
- jar = createIjarAction(runtimeJar, false);
+ jar = createIjarAction(ruleContext, javaToolchain, runtimeJar, false);
} else {
jar = runtimeJar;
}
@@ -631,4 +646,126 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
translationsFrozen = true;
return ImmutableList.copyOf(translations);
}
+
+ public static JavaToolchainProvider getJavaToolchainProvider(
+ RuleContext ruleContext, String implicitAttributesSuffix) {
+ return ruleContext.getPrerequisite(
+ ":java_toolchain" + implicitAttributesSuffix, Mode.TARGET, JavaToolchainProvider.class);
+ }
+
+ public static JavaToolchainProvider getJavaToolchainProvider(RuleContext ruleContext) {
+ return getJavaToolchainProvider(ruleContext, DEFAULT_ATTRIBUTES_SUFFIX);
+ }
+
+ /**
+ * Returns the artifacts required to invoke {@code javahome} relative binary
+ * in the action.
+ */
+ public static NestedSet<Artifact> getHostJavabaseInputsNonStatic(
+ RuleContext ruleContext, String implicitAttributesSuffix) {
+ // This must have a different name than above, because the middleman creation uses the rule's
+ // configuration, although it should use the host configuration.
+ return AnalysisUtils.getMiddlemanFor(ruleContext, ":host_jdk" + implicitAttributesSuffix);
+ }
+
+ public static NestedSet<Artifact> getHostJavabaseInputsNonStatic(RuleContext ruleContext) {
+ return getHostJavabaseInputsNonStatic(ruleContext, DEFAULT_ATTRIBUTES_SUFFIX);
+ }
+
+ /**
+ * Returns the instrumentation jar in the given semantics.
+ */
+ public static Iterable<Artifact> getInstrumentationJars(
+ RuleContext ruleContext, String implicitAttributesSuffix) {
+ TransitiveInfoCollection instrumentationTarget = ruleContext.getPrerequisite(
+ "$jacoco_instrumentation" + implicitAttributesSuffix, Mode.HOST);
+ if (instrumentationTarget == null) {
+ return ImmutableList.<Artifact>of();
+ }
+ return FileType.filter(
+ instrumentationTarget.getProvider(FileProvider.class).getFilesToBuild(),
+ JavaSemantics.JAR);
+ }
+
+ public static Iterable<Artifact> getInstrumentationJars(RuleContext ruleContext) {
+ return getInstrumentationJars(ruleContext, DEFAULT_ATTRIBUTES_SUFFIX);
+ }
+
+ /**
+ * Returns the javac bootclasspath artifacts from the given toolchain (if it has any) or the rule.
+ */
+ public static ImmutableList<Artifact> getBootClasspath(JavaToolchainProvider javaToolchain) {
+ return ImmutableList.copyOf(javaToolchain.getBootclasspath());
+ }
+
+ private ImmutableList<Artifact> getBootClasspath() {
+ return ImmutableList.copyOf(javaToolchain.getBootclasspath());
+ }
+
+ /**
+ * Returns the extdir artifacts.
+ */
+ private final ImmutableList<Artifact> getExtdirInputs() {
+ return ImmutableList.copyOf(javaToolchain.getExtclasspath());
+ }
+
+ /**
+ * Creates the Action that creates ijars from Jar files.
+ *
+ * @param inputJar the Jar to create the ijar for
+ * @param addPrefix whether to prefix the path of the generated ijar with the package and
+ * name of the current rule
+ * @return the Artifact to create with the Action
+ */
+ protected static Artifact createIjarAction(
+ RuleContext ruleContext,
+ JavaToolchainProvider javaToolchain,
+ Artifact inputJar, boolean addPrefix) {
+ Artifact interfaceJar = getIjarArtifact(ruleContext, inputJar, addPrefix);
+ FilesToRunProvider ijarTarget = javaToolchain.getIjar();
+ if (!ruleContext.hasErrors()) {
+ ruleContext.registerAction(new SpawnAction.Builder()
+ .addInput(inputJar)
+ .addOutput(interfaceJar)
+ .setExecutable(ijarTarget)
+ // On Windows, ijar.exe needs msys-2.0.dll and zlib1.dll in PATH.
+ // Use default shell environment so that those can be found.
+ // TODO(dslomov): revisit this. If ijar is not msys-dependent, this is not needed.
+ .useDefaultShellEnvironment()
+ .addArgument(inputJar.getExecPathString())
+ .addArgument(interfaceJar.getExecPathString())
+ .setProgressMessage("Extracting interface " + ruleContext.getLabel())
+ .setMnemonic("JavaIjar")
+ .build(ruleContext));
+ }
+ return interfaceJar;
+ }
+
+ private static Artifact getIjarArtifact(
+ RuleContext ruleContext, Artifact jar, boolean addPrefix) {
+ if (addPrefix) {
+ PathFragment ruleBase = ruleContext.getUniqueDirectory("_ijar");
+ PathFragment artifactDirFragment = jar.getRootRelativePath().getParentDirectory();
+ String ijarBasename = FileSystemUtils.removeExtension(jar.getFilename()) + "-ijar.jar";
+ return ruleContext.getDerivedArtifact(
+ ruleBase.getRelative(artifactDirFragment).getRelative(ijarBasename),
+ ruleContext.getConfiguration().getGenfilesDirectory(
+ ruleContext.getRule().getRepository()));
+ } else {
+ return derivedArtifact(ruleContext, jar, "", "-ijar.jar");
+ }
+ }
+
+ /**
+ * Creates a derived artifact from the given artifact by adding the given
+ * prefix and removing the extension and replacing it by the given suffix.
+ * The new artifact will have the same root as the given one.
+ */
+ private static Artifact derivedArtifact(
+ RuleContext ruleContext, Artifact artifact, String prefix, String suffix) {
+ PathFragment path = artifact.getRootRelativePath();
+ String basename = FileSystemUtils.removeExtension(path.getBaseName()) + suffix;
+ path = path.replaceName(prefix + basename);
+ return ruleContext.getDerivedArtifact(path, artifact.getRoot());
+ }
}