aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar elenairina <elenairina@google.com>2017-09-19 13:20:17 +0200
committerGravatar László Csomor <laszlocsomor@google.com>2017-09-19 14:45:01 +0200
commit655a529db693e0d3c89a68ca81fc4858147b90f0 (patch)
treeb6b266a4076e8ea7ebc15e145db36a64b3bfa5a4 /src
parentf20ae6b20816df6a393c6e8352befba9b158fdf4 (diff)
Expose full compile time jars in Skylark
There are several use cases for using full compile time jars instead of ijars (scala macros cannot use ijar, kotlin dependencies, etc). This change allows creating a provider with or without creating interface jars for compile time, exposing the right full/interface jars on target[JavaInfo].compile_jars and target[JavaInfo].full_compile_jars. For more details see https://github.com/bazelbuild/bazel/issues/3528. Fixes #3528 RELNOTES: java_common.create_provider is now supported with creating ijars by default. This introduces incompatibilities for existing users. Please set use_ijar=False if you don't want to use ijars. PiperOrigin-RevId: 169222793
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java21
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java28
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java315
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java12
-rwxr-xr-xsrc/test/shell/bazel/bazel_java_test.sh117
11 files changed, 408 insertions, 155 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
index be6d6348cd..8a8ccc8ec1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
@@ -410,6 +410,13 @@ public class SkylarkActionFactory implements SkylarkValue {
envUnchecked, executionRequirementsUnchecked, inputManifestsUnchecked, builder);
}
+ /**
+ * Builds and registers a spawn action on the rule context.
+ */
+ public void buildAndRegisterSpawnAction(SpawnAction.Builder action) {
+ ruleContext.registerAction(action.build(ruleContext));
+ }
+
@SkylarkCallable(
name = "run_shell",
doc = "Creates an action that runs a shell command.",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
index cdafdb20fa..de257da513 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
@@ -141,7 +141,7 @@ public class AarImport implements RuleConfiguredTargetFactory {
common.setJavaCompilationArtifacts(
new JavaCompilationArtifacts.Builder()
.addRuntimeJar(mergedJar)
- .addCompileTimeJar(mergedJar)
+ .addCompileTimeJarAsFullJar(mergedJar)
.build());
return ruleBuilder
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 41c7fb5c17..1fd3e9aa63 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
@@ -419,7 +419,7 @@ public class AndroidCommon {
// We don't actually use the ijar. That is almost the same as the resource class jar
// except for <clinit>, but it takes time to build and waiting for that to build would
// just delay building the rest of the library.
- artifactsBuilder.addCompileTimeJar(resourceClassJar);
+ artifactsBuilder.addCompileTimeJarAsFullJar(resourceClassJar);
// Add the compiled resource jar as a declared output of the rule.
filesBuilder.add(resourceSourceJar);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
index f30705bba4..f9198eee58 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
@@ -43,13 +43,16 @@ public abstract class JavaCompilationArgs {
JavaCompilationArgs.create(
NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER),
NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER),
+ NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER),
NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER));
private static JavaCompilationArgs create(
NestedSet<Artifact> runtimeJars,
NestedSet<Artifact> compileTimeJars,
+ NestedSet<Artifact> fullCompileTimeJars,
NestedSet<Artifact> instrumentationMetadata) {
- return new AutoValue_JavaCompilationArgs(runtimeJars, compileTimeJars, instrumentationMetadata);
+ return new AutoValue_JavaCompilationArgs(
+ runtimeJars, compileTimeJars, fullCompileTimeJars, instrumentationMetadata);
}
/** Returns transitive runtime jars. */
@@ -58,6 +61,12 @@ public abstract class JavaCompilationArgs {
/** Returns transitive compile-time jars. */
public abstract NestedSet<Artifact> getCompileTimeJars();
+ /**
+ * Returns transitive full jars for compilation time: the full jars for every interface jar and
+ * all the full jars on the compiletime classpath.
+ */
+ public abstract NestedSet<Artifact> getFullCompileTimeJars();
+
/** Returns transitive instrumentation metadata jars. */
public abstract NestedSet<Artifact> getInstrumentationMetadata();
@@ -76,6 +85,8 @@ public abstract class JavaCompilationArgs {
NestedSetBuilder.naiveLinkOrder();
private final NestedSetBuilder<Artifact> compileTimeJarsBuilder =
NestedSetBuilder.naiveLinkOrder();
+ private final NestedSetBuilder<Artifact> fullCompileTimeJarsBuilder =
+ NestedSetBuilder.naiveLinkOrder();
private final NestedSetBuilder<Artifact> instrumentationMetadataBuilder =
NestedSetBuilder.naiveLinkOrder();
@@ -95,6 +106,7 @@ public abstract class JavaCompilationArgs {
addRuntimeJars(other.getRuntimeJars());
}
addCompileTimeJars(other.getCompileTimeJars());
+ addFullCompileTimeJars(other.getFullCompileTimeJars());
addInstrumentationMetadata(other.getInstrumentationMetadata());
return this;
}
@@ -122,8 +134,9 @@ public abstract class JavaCompilationArgs {
return this;
}
- public Builder addCompileTimeJar(Artifact compileTimeJar) {
+ public Builder addCompileTimeJarAsFullJar(Artifact compileTimeJar) {
this.compileTimeJarsBuilder.add(compileTimeJar);
+ this.fullCompileTimeJarsBuilder.add(compileTimeJar);
return this;
}
@@ -132,11 +145,26 @@ public abstract class JavaCompilationArgs {
return this;
}
+ public Builder addCompileTimeJar(Artifact compileTimeJar) {
+ this.compileTimeJarsBuilder.add(compileTimeJar);
+ return this;
+ }
+
+ public Builder addFullCompileTimeJars(Iterable<Artifact> fullCompileTimeJars) {
+ this.fullCompileTimeJarsBuilder.addAll(fullCompileTimeJars);
+ return this;
+ }
+
public Builder addTransitiveCompileTimeJars(NestedSet<Artifact> compileTimeJars) {
this.compileTimeJarsBuilder.addTransitive(compileTimeJars);
return this;
}
+ public Builder addTransitiveFullCompileTimeJars(NestedSet<Artifact> fullCompileTimeJars) {
+ this.fullCompileTimeJarsBuilder.addTransitive(fullCompileTimeJars);
+ return this;
+ }
+
public Builder addInstrumentationMetadata(Artifact instrumentationMetadata) {
this.instrumentationMetadataBuilder.add(instrumentationMetadata);
return this;
@@ -170,7 +198,7 @@ public abstract class JavaCompilationArgs {
NestedSet<Artifact> filesToBuild =
dep.getProvider(FileProvider.class).getFilesToBuild();
for (Artifact jar : FileType.filter(filesToBuild, JavaSemantics.JAR)) {
- addCompileTimeJar(jar);
+ addCompileTimeJarAsFullJar(jar);
addRuntimeJar(jar);
}
}
@@ -227,14 +255,15 @@ public abstract class JavaCompilationArgs {
}
/**
- * Includes the contents of another instance of JavaCompilationArgs.
+ * Includes the contents of another instance of {@link JavaCompilationArgs}.
*
- * @param args the JavaCompilationArgs instance
+ * @param args the {@link JavaCompilationArgs} instance
* @param type the classpath(s) to consider
*/
public Builder addTransitiveArgs(JavaCompilationArgs args, ClasspathType type) {
if (!ClasspathType.RUNTIME_ONLY.equals(type)) {
compileTimeJarsBuilder.addTransitive(args.getCompileTimeJars());
+ fullCompileTimeJarsBuilder.addTransitive(args.getFullCompileTimeJars());
}
if (!ClasspathType.COMPILE_ONLY.equals(type)) {
runtimeJarsBuilder.addTransitive(args.getRuntimeJars());
@@ -251,6 +280,7 @@ public abstract class JavaCompilationArgs {
return JavaCompilationArgs.create(
runtimeJarsBuilder.build(),
compileTimeJarsBuilder.build(),
+ fullCompileTimeJarsBuilder.build(),
instrumentationMetadataBuilder.build());
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java
index e18ded353a..a6d346a11e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.rules.java;
import com.google.auto.value.AutoValue;
+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;
@@ -47,6 +48,7 @@ public abstract class JavaCompilationArtifacts {
public abstract ImmutableList<Artifact> getRuntimeJars();
public abstract ImmutableList<Artifact> getCompileTimeJars();
+ abstract ImmutableList<Artifact> getFullCompileTimeJars();
public abstract ImmutableList<Artifact> getInstrumentationMetadata();
@Nullable public abstract Artifact getCompileTimeDependencyArtifact();
@Nullable public abstract Artifact getInstrumentedJar();
@@ -62,14 +64,17 @@ public abstract class JavaCompilationArtifacts {
public static final class Builder {
private final Set<Artifact> runtimeJars = new LinkedHashSet<>();
private final Set<Artifact> compileTimeJars = new LinkedHashSet<>();
+ private final Set<Artifact> fullCompileTimeJars = new LinkedHashSet<>();
private final Set<Artifact> instrumentationMetadata = new LinkedHashSet<>();
private Artifact compileTimeDependencies;
private Artifact instrumentedJar;
public JavaCompilationArtifacts build() {
+ Preconditions.checkState(fullCompileTimeJars.size() == compileTimeJars.size());
return new AutoValue_JavaCompilationArtifacts(
ImmutableList.copyOf(runtimeJars),
ImmutableList.copyOf(compileTimeJars),
+ ImmutableList.copyOf(fullCompileTimeJars),
ImmutableList.copyOf(instrumentationMetadata),
compileTimeDependencies,
instrumentedJar);
@@ -85,16 +90,28 @@ public abstract class JavaCompilationArtifacts {
return this;
}
- public Builder addCompileTimeJar(Artifact jar) {
+ public Builder addInterfaceJarWithFullJar(Artifact ijar, Artifact fullJar) {
+ this.compileTimeJars.add(ijar);
+ this.fullCompileTimeJars.add(fullJar);
+ return this;
+ }
+
+ public Builder addCompileTimeJarAsFullJar(Artifact jar) {
this.compileTimeJars.add(jar);
+ this.fullCompileTimeJars.add(jar);
return this;
}
- public Builder addCompileTimeJars(Iterable<Artifact> jars) {
+ public Builder addInterfaceJars(Iterable<Artifact> jars) {
Iterables.addAll(this.compileTimeJars, jars);
return this;
}
+ Builder addFullCompileTimeJars(Iterable<Artifact> jars) {
+ Iterables.addAll(this.fullCompileTimeJars, jars);
+ return this;
+ }
+
public Builder addInstrumentationMetadata(Artifact instrumentationMetadata) {
this.instrumentationMetadata.add(instrumentationMetadata);
return this;
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 a4d7cb9808..5c70ac72e5 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
@@ -610,14 +610,20 @@ public final class JavaCompilationHelper {
public Artifact createCompileTimeJarAction(
Artifact runtimeJar, JavaCompilationArtifacts.Builder builder) {
Artifact jar;
+ boolean isFullJar = false;
if (shouldUseHeaderCompilation()) {
jar = createHeaderCompilationAction(runtimeJar, builder);
} else if (getJavaConfiguration().getUseIjars()) {
jar = createIjarAction(ruleContext, javaToolchain, runtimeJar, false);
} else {
jar = runtimeJar;
+ isFullJar = true;
+ }
+ if (isFullJar) {
+ builder.addCompileTimeJarAsFullJar(jar);
+ } else {
+ builder.addInterfaceJarWithFullJar(jar, runtimeJar);
}
- builder.addCompileTimeJar(jar);
return jar;
}
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 280f8115bf..fc25da58c6 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
@@ -209,11 +209,12 @@ public class JavaImport implements RuleConfiguredTargetFactory {
private JavaCompilationArtifacts collectJavaArtifacts(
ImmutableList<Artifact> jars,
ImmutableList<Artifact> interfaceJars) {
- JavaCompilationArtifacts.Builder javaArtifactsBuilder = new JavaCompilationArtifacts.Builder();
- javaArtifactsBuilder.addRuntimeJars(jars);
- // interfaceJars Artifacts have proper owner labels
- javaArtifactsBuilder.addCompileTimeJars(interfaceJars);
- return javaArtifactsBuilder.build();
+ return new JavaCompilationArtifacts.Builder()
+ .addRuntimeJars(jars)
+ .addFullCompileTimeJars(jars)
+ // interfaceJars Artifacts have proper owner labels
+ .addInterfaceJars(interfaceJars)
+ .build();
}
private ImmutableList<Artifact> collectJars(RuleContext ruleContext) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
index 1524016978..cdcdc8081d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfo.java
@@ -201,7 +201,8 @@ public final class JavaInfo extends NativeInfo {
@SkylarkCallable(
name = "transitive_compile_time_jars",
- doc = "Depset of compile time jars recusrively required by this target",
+ doc = "Depset of compile time jars recusrively required by this target. See `compile_jars` "
+ + "for more details.",
structField = true
)
public SkylarkNestedSet getTransitiveCompileTimeJars() {
@@ -213,7 +214,13 @@ public final class JavaInfo extends NativeInfo {
@SkylarkCallable(
name = "compile_jars",
- doc = "Depset of compile time jars required by this target directly",
+ doc = "Returns the compile time jars required by this target directly. They can be: <ul>"
+ + "<li> interface jars (ijars), if an ijar tool was used, either by calling "
+ + "java_common.create_provider(use_ijar=True, ...) or by passing --use_ijars on the "
+ + "command line for native Java rules and `java_common.compile`</li>"
+ + "<li> normal full jars, if no ijar action was requested</li>"
+ + "<li> both ijars and normal full jars, if this provider was created by merging two or "
+ + "more providers created with different ijar requests </li> </ul>",
structField = true
)
public SkylarkNestedSet getCompileTimeJars() {
@@ -224,6 +231,23 @@ public final class JavaInfo extends NativeInfo {
}
@SkylarkCallable(
+ name = "full_compile_jars",
+ doc = "Returns the full compile time jars required by this target directly. They can be <ul>"
+ + "<li> the corresponding normal full jars of the ijars returned by `compile_jars`<li>"
+ + "<li> the normal full jars returned by `compile_jars`<li><ul>"
+ + "Note: `compile_jars` can return a mix of ijars and normal full jars. In that case, "
+ + "`full_compile_jars` returns the corresponding full jars of the ijars and the remaining"
+ + "normal full jars in `compile_jars`.",
+ structField = true
+ )
+ public SkylarkNestedSet getFullCompileTimeJars() {
+ return SkylarkNestedSet.of(
+ Artifact.class,
+ providers.getProvider(JavaCompilationArgsProvider.class)
+ .getJavaCompilationArgs().getFullCompileTimeJars());
+ }
+
+ @SkylarkCallable(
name = "source_jars",
doc = "Returns a list of jar files containing all the uncompiled source files (including "
+ "those generated by annotations) from the target itself, i.e. NOT including the sources of "
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index b30ef83511..aba401f91a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -19,10 +19,15 @@ 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.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.MiddlemanProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
+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.actions.SpawnAction.Builder;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
+import com.google.devtools.build.lib.analysis.skylark.SkylarkActionFactory;
import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -35,121 +40,187 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
import java.util.List;
+import javax.annotation.Nullable;
/** A module that contains Skylark utilities for Java support. */
@SkylarkModule(name = "java_common", doc = "Utilities for Java compilation support in Skylark.")
public class JavaSkylarkCommon {
private final JavaSemantics javaSemantics;
- public JavaSkylarkCommon(JavaSemantics javaSemantics) {
- this.javaSemantics = javaSemantics;
- }
-
- @SkylarkCallable(
- name = "provider",
- structField = true,
- doc = "Returns the Java declared provider. <br>"
- + "The same value is accessible as <code>JavaInfo</code>. <br>"
- + "Prefer using <code>JavaInfo</code> in new code."
- )
- public Provider getJavaProvider() {
- return JavaInfo.PROVIDER;
- }
-
@SkylarkCallable(
- name = "create_provider",
- documented = false,
- doc = "Create JavaInfo from pre-built jars. Note that compile_time_jars and "
- + "runtime_jars are not automatically merged into the recursive jars - if this is the "
- + "desired behaviour the user should merge the jars before creating the provider. "
- + "The recursive (compile/runtime) jars are the jars usually collected transitively from "
- + "dependencies.",
- parameters = {
- @Param(
- name = "compile_time_jars",
- positional = false,
- named = true,
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "[]"
- ),
- @Param(
- name = "runtime_jars",
- positional = false,
- named = true,
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "[]"
- ),
- @Param(
- name = "transitive_compile_time_jars",
- positional = false,
- named = true,
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "[]"
- ),
- @Param(
- name = "transitive_runtime_jars",
- positional = false,
- named = true,
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "[]"
- ),
- @Param(
- name = "source_jars",
- positional = false,
- named = true,
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "[]"
- )
- }
+ name = "create_provider",
+ doc = "Creates a JavaInfo from jars. compile_time/runtime_jars represent the outputs of the "
+ + "target providing a JavaInfo, while transitive_*_jars represent their dependencies."
+ + "<p>Note: compile_time_jars and runtime_jars are not automatically merged into the "
+ + "transitive jars (unless the given transitive_*_jars are empty) - if this is the "
+ + "desired behaviour the user should merge the jars before creating the provider."
+ + "<p>This function also creates actions to generate interface jars by default."
+ + "<p>When use_ijar is True, ijar will be run on the given compile_time_jars and the "
+ + "resulting interface jars will be stored as compile_jars, while the initila jars will "
+ + "be stored as full_compile_jars. "
+ + "<p>When use_ijar=False, the given compile_time_jars will be stored as both "
+ + "compile_jars and full_compile_jars. No actions are created. See JavaInfo#compile_jars "
+ + "and JavaInfo#full_compile_jars for more details."
+ + "<p>Currently only "
+ + "<a href='https://github.com/bazelbuild/bazel/tree/master/third_party/ijar'>ijar</a> is "
+ + "supported for generating interface jars. Header compilation is not yet supported."
+ ,
+ parameters = {
+ @Param(
+ name = "actions",
+ type = SkylarkActionFactory.class,
+ noneable = true,
+ defaultValue = "None",
+ doc = "The ctx.actions object, used to register the actions for creating the "
+ + "interface jars. Only set if use_ijar=True."
+ ),
+ @Param(
+ name = "compile_time_jars",
+ positional = false,
+ named = true,
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = Artifact.class,
+ defaultValue = "[]",
+ doc = "A list or a set of jars that should be used at compilation for a given target."
+ ),
+ @Param(
+ name = "runtime_jars",
+ positional = false,
+ named = true,
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = Artifact.class,
+ defaultValue = "[]",
+ doc = "A list or a set of jars that should be used at runtime for a given target."
+ ),
+ @Param(
+ name = "use_ijar",
+ positional = false,
+ named = true,
+ type = Boolean.class,
+ defaultValue = "True",
+ doc = "If True it will generate interface jars for every jar in compile_time_jars."
+ + "The generating interface jars will be stored as compile_jars and the initial "
+ + "(full) compile_time_jars will be stored as full_compile_jars."
+ + "If False the given compile_jars will be stored as both compile_jars and "
+ + "full_compile_jars."
+ ),
+ @Param(
+ name = "java_toolchain",
+ positional = false,
+ named = true,
+ type = ConfiguredTarget.class,
+ noneable = true,
+ defaultValue = "None",
+ doc = "A label pointing to a java_toolchain rule to be used for retrieving the ijar "
+ + "tool. Only set when use_ijar is True."
+ ),
+ @Param(
+ name = "transitive_compile_time_jars",
+ positional = false,
+ named = true,
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = Artifact.class,
+ defaultValue = "[]",
+ doc = "A list or set of compile time jars collected from the transitive closure of a "
+ + "rule."
+ ),
+ @Param(
+ name = "transitive_runtime_jars",
+ positional = false,
+ named = true,
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = Artifact.class,
+ defaultValue = "[]",
+ doc = "A list or set of runtime jars collected from the transitive closure of a rule."
+ ),
+ @Param(
+ name = "source_jars",
+ positional = false,
+ named = true,
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = Artifact.class,
+ defaultValue = "[]",
+ doc = "A list or set of output source jars that contain the uncompiled source files "
+ + "including the source files generated by annotation processors if the case."
+ )
+ }
)
public JavaInfo create(
+ @Nullable Object actionsUnchecked,
Object compileTimeJars,
Object runtimeJars,
+ Boolean useIjar,
+ @Nullable Object javaToolchainUnchecked,
Object transitiveCompileTimeJars,
Object transitiveRuntimeJars,
Object sourceJars)
throws EvalException {
NestedSet<Artifact> compileTimeJarsNestedSet = asArtifactNestedSet(compileTimeJars);
NestedSet<Artifact> runtimeJarsNestedSet = asArtifactNestedSet(runtimeJars);
+
+ JavaCompilationArgs.Builder javaCompilationArgsBuilder = JavaCompilationArgs.builder();
+ if (useIjar && !compileTimeJarsNestedSet.isEmpty()) {
+ if (!(actionsUnchecked instanceof SkylarkActionFactory)) {
+ throw new EvalException(null, "In java_common.create_provider the value of use_ijar is "
+ + "True. Make sure the first argument of the function is the ctx.actions object.");
+ }
+ if (!(javaToolchainUnchecked instanceof ConfiguredTarget)) {
+ throw new EvalException(null, "In java_common.create_provider the value of use_ijar is "
+ + "True. Make sure the java_toolchain argument is a valid java_toolchain Target.");
+ }
+ SkylarkActionFactory actions = (SkylarkActionFactory) actionsUnchecked;
+ ConfiguredTarget javaToolchain = (ConfiguredTarget) javaToolchainUnchecked;
+ javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJarsNestedSet);
+ for (Artifact compileJar : compileTimeJarsNestedSet) {
+ javaCompilationArgsBuilder.addCompileTimeJar(
+ buildIjar(actions, compileJar, javaToolchain)
+ );
+ }
+ } else {
+ javaCompilationArgsBuilder.addCompileTimeJars(compileTimeJarsNestedSet);
+ javaCompilationArgsBuilder.addFullCompileTimeJars(compileTimeJarsNestedSet);
+ }
+
+ JavaCompilationArgs javaCompilationArgs = javaCompilationArgsBuilder
+ .addTransitiveRuntimeJars(runtimeJarsNestedSet)
+ .build();
+
NestedSet<Artifact> transitiveCompileTimeJarsNestedSet =
asArtifactNestedSet(transitiveCompileTimeJars);
NestedSet<Artifact> transitiveRuntimeJarsNestedSet = asArtifactNestedSet(transitiveRuntimeJars);
- JavaCompilationArgs javaCompilationArgs =
- JavaCompilationArgs.builder()
- .addTransitiveCompileTimeJars(compileTimeJarsNestedSet)
- .addTransitiveRuntimeJars(runtimeJarsNestedSet)
- .build();
JavaCompilationArgs.Builder recursiveJavaCompilationArgs = JavaCompilationArgs.builder();
- if (transitiveCompileTimeJarsNestedSet.isEmpty() && transitiveRuntimeJarsNestedSet.isEmpty()) {
+ if (transitiveCompileTimeJarsNestedSet.isEmpty()) {
+ recursiveJavaCompilationArgs
+ .addTransitiveCompileTimeJars(javaCompilationArgs.getCompileTimeJars());
recursiveJavaCompilationArgs
- .addTransitiveCompileTimeJars(compileTimeJarsNestedSet)
- .addTransitiveRuntimeJars(runtimeJarsNestedSet);
+ .addTransitiveFullCompileTimeJars(javaCompilationArgs.getFullCompileTimeJars());
} else {
recursiveJavaCompilationArgs
- .addTransitiveCompileTimeJars(transitiveCompileTimeJarsNestedSet)
- .addTransitiveRuntimeJars(transitiveRuntimeJarsNestedSet);
+ .addTransitiveCompileTimeJars(transitiveCompileTimeJarsNestedSet);
+ }
+
+ if (transitiveRuntimeJarsNestedSet.isEmpty()) {
+ recursiveJavaCompilationArgs.addTransitiveRuntimeJars(runtimeJarsNestedSet);
+ } else {
+ recursiveJavaCompilationArgs.addTransitiveRuntimeJars(transitiveRuntimeJarsNestedSet);
}
JavaInfo javaInfo =
@@ -167,6 +238,21 @@ public class JavaSkylarkCommon {
return javaInfo;
}
+ public JavaSkylarkCommon(JavaSemantics javaSemantics) {
+ this.javaSemantics = javaSemantics;
+ }
+
+ @SkylarkCallable(
+ name = "provider",
+ structField = true,
+ doc = "Returns the Java declared provider. <br>"
+ + "The same value is accessible as <code>JavaInfo</code>. <br>"
+ + "Prefer using <code>JavaInfo</code> in new code."
+ )
+ public Provider getJavaProvider() {
+ return JavaInfo.PROVIDER;
+ }
+
/**
* Takes an Object that is either a SkylarkNestedSet or a SkylarkList of Artifacts and returns it
* as a NestedSet.
@@ -377,40 +463,27 @@ public class JavaSkylarkCommon {
.build();
}
- @SkylarkCallable(
- name = "build_ijar",
- documented = true,
- doc = "Builds and returns the ijar file for the given jar file.",
- mandatoryPositionals = 1,
- parameters = {
- @Param(
- name = "jar",
- positional = true,
- named = true,
- type = Artifact.class,
- doc = "The input .jar file for which an ijar will be built. Mandatory."
- ),
- @Param(
- name = "java_toolchain",
- positional = true,
- named = true,
- type = ConfiguredTarget.class,
- doc = "A label pointing to a java_toolchain rule to be used for this compilation. "
- + "Mandatory."
- ),
- }
- )
- public Artifact buildIjar(
- SkylarkRuleContext skylarkRuleContext,
- Artifact fullJar,
+ private static Artifact buildIjar(
+ SkylarkActionFactory actions,
+ Artifact inputJar,
ConfiguredTarget javaToolchain) throws EvalException {
- return JavaCompilationHelper.createIjarAction(
- skylarkRuleContext.getRuleContext(),
- getJavaToolchainProvider(javaToolchain),
- fullJar,
- /* addPrefix = */ true);
+ String ijarBasename = FileSystemUtils.removeExtension(inputJar.getFilename()) + "-ijar.jar";
+ Artifact interfaceJar = actions.declareFile(ijarBasename, inputJar);
+ FilesToRunProvider ijarTarget = getJavaToolchainProvider(javaToolchain).getIjar();
+ SpawnAction.Builder actionBuilder = new Builder()
+ .addInput(inputJar)
+ .addOutput(interfaceJar)
+ .setExecutable(ijarTarget)
+ .setProgressMessage("Extracting interface for jar %s", inputJar.getFilename())
+ .addCommandLine(CustomCommandLine.builder()
+ .addExecPath(inputJar)
+ .addExecPath(interfaceJar)
+ .build())
+ .useDefaultShellEnvironment()
+ .setMnemonic("JavaIjar");
+ actions.buildAndRegisterSpawnAction(actionBuilder);
+ return interfaceJar;
}
-
/**
* Creates a {@link JavaSourceJarsProvider} from the given list of source jars.
*/
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
index fe486d6bf0..4ed01420ba 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
@@ -272,6 +272,7 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
"def _impl(ctx):",
" my_provider = java_common.create_provider(",
" compile_time_jars = ctx.files.compile_time_jars,",
+ " use_ijar = False,",
" runtime_jars = ctx.files.runtime_jars,",
" transitive_compile_time_jars = ctx.files.transitive_compile_time_jars,",
" transitive_runtime_jars = ctx.files.transitive_runtime_jars,",
@@ -280,6 +281,7 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
"my_rule = rule(_impl, ",
" attrs = { ",
" 'compile_time_jars' : attr.label_list(allow_files=['.jar']),",
+ " 'full_compile_time_jars' : attr.label_list(allow_files=['.jar']),",
" 'runtime_jars': attr.label_list(allow_files=['.jar']),",
" 'transitive_compile_time_jars': attr.label_list(allow_files=['.jar']),",
" 'transitive_runtime_jars': attr.label_list(allow_files=['.jar']),",
@@ -300,6 +302,10 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
SkylarkNestedSet compileJars = info.getCompileTimeJars();
assertThat(prettyJarNames(compileJars.getSet(Artifact.class))).containsExactly("foo/liba.jar");
+ SkylarkNestedSet fullCompileJars = info.getFullCompileTimeJars();
+ assertThat(
+ prettyJarNames(fullCompileJars.getSet(Artifact.class))).containsExactly("foo/liba.jar");
+
SkylarkNestedSet transitiveCompileTimeJars = info.getTransitiveCompileTimeJars();
assertThat(prettyJarNames(
transitiveCompileTimeJars.getSet(Artifact.class))).containsExactly("foo/libc.jar");
@@ -316,6 +322,7 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
"def _impl(ctx):",
" my_provider = java_common.create_provider(",
" compile_time_jars = ctx.files.compile_time_jars,",
+ " use_ijar = False,",
" runtime_jars = [],",
" transitive_compile_time_jars = [],",
" transitive_runtime_jars = ctx.files.transitive_runtime_jars)",
@@ -339,7 +346,8 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
assertThat(prettyJarNames(compileJars.getSet(Artifact.class))).containsExactly("foo/liba.jar");
SkylarkNestedSet transitiveCompileTimeJars = info.getTransitiveCompileTimeJars();
- assertThat(prettyJarNames(transitiveCompileTimeJars.getSet(Artifact.class))).isEmpty();
+ assertThat(prettyJarNames(
+ transitiveCompileTimeJars.getSet(Artifact.class))).containsExactly("foo/liba.jar");
SkylarkNestedSet transitiveRuntimeJars = info.getTransitiveRuntimeJars();
assertThat(prettyJarNames(
@@ -353,6 +361,7 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
"def _impl(ctx):",
" my_provider = java_common.create_provider(",
" compile_time_jars = depset(ctx.files.compile_time_jars),",
+ " use_ijar = False,",
" runtime_jars = depset(ctx.files.runtime_jars),",
" transitive_compile_time_jars = depset(ctx.files.transitive_compile_time_jars),",
" transitive_runtime_jars = depset(ctx.files.transitive_runtime_jars),",
@@ -409,6 +418,7 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
" [dep[JavaInfo] for dep in ctx.attr.deps])",
" my_provider = java_common.create_provider(",
" compile_time_jars = depset(ctx.files.compile_time_jars),",
+ " use_ijar = False,",
" runtime_jars = depset(ctx.files.runtime_jars))",
" return [java_common.merge([my_provider, transitive_provider])]",
"my_rule = rule(_impl, ",
diff --git a/src/test/shell/bazel/bazel_java_test.sh b/src/test/shell/bazel/bazel_java_test.sh
index db6fc54ece..ee1842bbb0 100755
--- a/src/test/shell/bazel/bazel_java_test.sh
+++ b/src/test/shell/bazel/bazel_java_test.sh
@@ -1239,64 +1239,149 @@ EOF
expect_log "Using type com.google.sandwich.C from an indirect dependency"
}
-function test_java_common_build_ijar() {
+function test_java_common_create_provider_with_ijar() {
mkdir -p java/com/google/foo
touch java/com/google/foo/{BUILD,A.java,my_rule.bzl}
cat > java/com/google/foo/A.java << EOF
package com.google.foo;
class A {}
EOF
+
cat > java/com/google/foo/BUILD << EOF
load(":my_rule.bzl", "my_rule")
java_library(name = "a", srcs = ["A.java"])
-my_rule(name = "banana", jar = "liba.jar")
+my_rule(name = "banana", compile_time_jars = ["liba.jar"])
EOF
cat > java/com/google/foo/my_rule.bzl << EOF
def _impl(ctx):
- ijar = java_common.build_ijar(ctx, ctx.files.jar[0], ctx.attr._java_toolchain)
- print(ijar.path)
- return DefaultInfo(files = depset([ijar]))
+ provider = java_common.create_provider(
+ ctx.actions,
+ compile_time_jars = ctx.files.compile_time_jars,
+ java_toolchain = ctx.attr._java_toolchain
+ )
+ print(provider.compile_jars)
+ print(provider.full_compile_jars)
+ return DefaultInfo(files = provider.compile_jars)
my_rule = rule(
implementation = _impl,
attrs = {
- "jar": attr.label(allow_files=True),
+ "compile_time_jars": attr.label_list(allow_files=True),
"_java_toolchain": attr.label(default = Label("@bazel_tools//tools/jdk:toolchain")),
}
)
EOF
+
bazel build java/com/google/foo:banana >& "$TEST_log" || fail "Unexpected fail"
expect_log "liba-ijar.jar"
- unzip -l bazel-genfiles/java/com/google/foo/_ijar/banana/java/com/google/foo/liba-ijar.jar >> "$TEST_log"
+ unzip -l bazel-bin/java/com/google/foo/liba-ijar.jar >> "$TEST_log"
expect_log "00:00 com/google/foo/A.class"
}
-function test_java_common_create_empty_ijars() {
+function test_java_common_create_provider_without_ijar() {
+ mkdir -p java/com/google/foo
+ touch java/com/google/foo/{BUILD,A.java,my_rule.bzl}
+ cat > java/com/google/foo/A.java << EOF
+package com.google.foo;
+class A {}
+EOF
+
+ cat > java/com/google/foo/BUILD << EOF
+load(":my_rule.bzl", "my_rule")
+java_library(name = "a", srcs = ["A.java"])
+my_rule(name = "banana", compile_time_jars = ["liba.jar"])
+EOF
+
+ cat > java/com/google/foo/my_rule.bzl << EOF
+def _impl(ctx):
+ provider = java_common.create_provider(
+ use_ijar = False,
+ compile_time_jars = ctx.files.compile_time_jars,
+ )
+ print(provider.compile_jars)
+ return DefaultInfo(files = provider.compile_jars)
+
+my_rule = rule(
+ implementation = _impl,
+ attrs = {
+ "compile_time_jars": attr.label_list(allow_files=True),
+ }
+)
+EOF
+
+ bazel build java/com/google/foo:banana >& "$TEST_log" || fail "Unexpected failure"
+ expect_log "liba.jar"
+}
+
+function test_java_common_create_provider_with_ijar_unset_actions() {
+ mkdir -p java/com/google/foo
+ touch java/com/google/foo/{BUILD,A.java,my_rule.bzl}
+ cat > java/com/google/foo/A.java << EOF
+package com.google.foo;
+class A {}
+EOF
+
+ cat > java/com/google/foo/BUILD << EOF
+load(":my_rule.bzl", "my_rule")
+java_library(name = "a", srcs = ["A.java"])
+my_rule(name = "banana", compile_time_jars = ["liba.jar"])
+EOF
+
+ cat > java/com/google/foo/my_rule.bzl << EOF
+def _impl(ctx):
+ provider = java_common.create_provider(
+ compile_time_jars = ctx.files.compile_time_jars,
+ java_toolchain = ctx.attr._java_toolchain
+ )
+ return DefaultInfo(files = provider.compile_jars)
+
+my_rule = rule(
+ implementation = _impl,
+ attrs = {
+ "compile_time_jars": attr.label_list(allow_files=True),
+ "_java_toolchain": attr.label(default = Label("@bazel_tools//tools/jdk:toolchain")),
+ }
+)
+EOF
+
+ bazel build java/com/google/foo:banana >& "$TEST_log" && fail "Unexpected success"
+ expect_log "In java_common.create_provider the value of use_ijar is True. Make sure the first argument of the function is the ctx.actions object."
+}
+
+function test_java_common_create_provider_with_ijar_unset_java_toolchain() {
mkdir -p java/com/google/foo
- touch java/com/google/foo/{BUILD,a.jar,my_rule.bzl}
+ touch java/com/google/foo/{BUILD,A.java,my_rule.bzl}
+ cat > java/com/google/foo/A.java << EOF
+package com.google.foo;
+class A {}
+EOF
+
cat > java/com/google/foo/BUILD << EOF
load(":my_rule.bzl", "my_rule")
-exports_files(["a.jar"])
-my_rule(name = "banana", jar = "a.jar")
+java_library(name = "a", srcs = ["A.java"])
+my_rule(name = "banana", compile_time_jars = ["liba.jar"])
EOF
cat > java/com/google/foo/my_rule.bzl << EOF
def _impl(ctx):
- ijar = java_common.build_ijar(ctx, ctx.files.jar[0], ctx.attr._java_toolchain)
- print(ijar.path)
- return DefaultInfo(files = depset([ijar]))
+ provider = java_common.create_provider(
+ ctx.actions,
+ compile_time_jars = ctx.files.compile_time_jars,
+ )
+ return DefaultInfo(files = provider.compile_jars)
my_rule = rule(
implementation = _impl,
attrs = {
- "jar": attr.label(allow_files=True),
+ "compile_time_jars": attr.label_list(allow_files=True),
"_java_toolchain": attr.label(default = Label("@bazel_tools//tools/jdk:toolchain")),
}
)
EOF
+
bazel build java/com/google/foo:banana >& "$TEST_log" && fail "Unexpected success"
- expect_log "Unable to open Zip file java/com/google/foo/a.jar: Invalid argument"
+ expect_log "In java_common.create_provider the value of use_ijar is True. Make sure the java_toolchain argument is a valid java_toolchain Target."
}
run_suite "Java integration tests"