diff options
Diffstat (limited to 'src/main/java/com/google/devtools')
9 files changed, 296 insertions, 138 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. */ |