aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2016-10-07 19:41:45 +0000
committerGravatar Yue Gan <yueg@google.com>2016-10-10 09:54:31 +0000
commit341e5ddaecb44f9822d041ac6e01973e0ad06deb (patch)
treef1ec3d4a0f213f0243210922b86cc112b593c57a /src
parent9d16209de1f374fc252cc1cb6022516207d68699 (diff)
Refactor in preparation for adding minimum classpath optimization.
-- MOS_MIGRATED_REVID=135505849
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java391
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java347
4 files changed, 394 insertions, 350 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 33d1601a9c..4f3f63b8b0 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -827,7 +827,7 @@ java_library(
"rules/java/JavaConstraintProvider.java",
"rules/java/JavaExportsProvider.java",
"rules/java/JavaGenJarsProvider.java",
- "rules/java/JavaHeaderCompileActionBuilder.java",
+ "rules/java/JavaHeaderCompileAction.java",
"rules/java/JavaHelper.java",
"rules/java/JavaLibraryHelper.java",
"rules/java/JavaNativeLibraryProvider.java",
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 5e9471d39d..6b3731d33d 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
@@ -266,8 +266,8 @@ public final class JavaCompilationHelper extends BaseJavaCompilationHelper {
runtimeJar.getRoot());
JavaTargetAttributes attributes = getAttributes();
- JavaHeaderCompileActionBuilder builder =
- new JavaHeaderCompileActionBuilder(getRuleContext(), implicitAttributesSuffix);
+ JavaHeaderCompileAction.Builder builder =
+ new JavaHeaderCompileAction.Builder(getRuleContext(), implicitAttributesSuffix);
builder.addSourceFiles(attributes.getSourceFiles());
builder.addSourceJars(attributes.getSourceJars());
builder.setClasspathEntries(attributes.getCompileTimeClassPath());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java
new file mode 100644
index 0000000000..19e88ef76f
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java
@@ -0,0 +1,391 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.java;
+
+import static com.google.devtools.build.lib.util.Preconditions.checkNotNull;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
+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.ImmutableSet;
+import com.google.devtools.build.lib.actions.Action;
+import com.google.devtools.build.lib.actions.ActionOwner;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.ParameterFile;
+import com.google.devtools.build.lib.actions.ResourceSet;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.actions.CommandLine;
+import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
+import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.cmdline.Label;
+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.vfs.PathFragment;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/**
+ * Action for Java header compilation, to be used if --java_header_compilation is enabled.
+ *
+ * <p>The header compiler consumes the inputs of a java compilation, and produces an interface jar
+ * that can be used as a compile-time jar by upstream targets. The header interface jar is
+ * equivalent to the output of ijar, but unlike ijar the header compiler operates directly on Java
+ * source files instead post-processing the class outputs of the compilation. Compiling the
+ * interface jar from source moves javac off the build's critical path.
+ *
+ * <p>The implementation of the header compiler tool can be found under {@code
+ * //src/java_tools/buildjar/java/com/google/devtools/build/java/turbine}.
+ */
+public class JavaHeaderCompileAction extends SpawnAction {
+ private static final ResourceSet LOCAL_RESOURCES =
+ ResourceSet.createWithRamCpuIo(/*memoryMb=*/ 750.0, /*cpuUsage=*/ 0.5, /*ioUsage=*/ 0.0);
+
+ /**
+ * Constructs an action to compile a set of Java source files to a header interface jar.
+ *
+ * @param owner the action owner, typically a java_* RuleConfiguredTarget
+ * @param tools the set of files comprising the tool that creates the header interface jar
+ * @param inputs the set of input artifacts of the compile action
+ * @param outputs the outputs of the action
+ * @param commandLine the command line arguments for the java header compiler
+ * @param progressMessage the message printed during the progression of the build
+ */
+ protected JavaHeaderCompileAction(
+ ActionOwner owner,
+ Iterable<Artifact> tools,
+ Iterable<Artifact> inputs,
+ Iterable<Artifact> outputs,
+ CommandLine commandLine,
+ String progressMessage) {
+ super(
+ owner,
+ tools,
+ inputs,
+ outputs,
+ LOCAL_RESOURCES,
+ commandLine,
+ ImmutableMap.<String, String>of(),
+ ImmutableSet.<String>of(),
+ progressMessage,
+ "Turbine");
+ }
+
+ /** Builder class to construct Java header compilation actions. */
+ public static class Builder {
+
+ private final RuleContext ruleContext;
+ private final String implicitAttributesSuffix;
+
+ private Artifact outputJar;
+ @Nullable private Artifact outputDepsProto;
+ private final Collection<Artifact> sourceFiles = new ArrayList<>();
+ private final Collection<Artifact> sourceJars = new ArrayList<>();
+ private NestedSet<Artifact> classpathEntries
+ = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
+ private final List<Artifact> bootclasspathEntries = new ArrayList<>();
+ @Nullable private String ruleKind;
+ @Nullable private Label targetLabel;
+ private PathFragment tempDirectory;
+ private BuildConfiguration.StrictDepsMode strictJavaDeps
+ = BuildConfiguration.StrictDepsMode.OFF;
+ private NestedSet<Artifact> directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
+ private final List<Artifact> compileTimeDependencyArtifacts = new ArrayList<>();
+ private ImmutableList<String> javacOpts;
+ private final List<Artifact> processorPath = new ArrayList<>();
+ private final List<String> processorNames = new ArrayList<>();
+ private NestedSet<Artifact> javabaseInputs;
+ private Artifact javacJar;
+
+ public Builder(RuleContext ruleContext, String implicitAttributesSuffix) {
+ this.ruleContext = ruleContext;
+ this.implicitAttributesSuffix = implicitAttributesSuffix;
+ }
+
+ /** Sets the output jdeps file. */
+ public Builder setOutputDepsProto(@Nullable Artifact outputDepsProto) {
+ this.outputDepsProto = outputDepsProto;
+ return this;
+ }
+
+ /** Sets the direct dependency artifacts. */
+ public Builder setDirectJars(NestedSet<Artifact> directJars) {
+ checkNotNull(directJars, "directJars must not be null");
+ this.directJars = directJars;
+ return this;
+ }
+
+ /** Sets the .jdeps artifacts for direct dependencies. */
+ public Builder addCompileTimeDependencyArtifacts(
+ Collection<Artifact> dependencyArtifacts) {
+ checkNotNull(dependencyArtifacts, "dependencyArtifacts must not be null");
+ this.compileTimeDependencyArtifacts.addAll(dependencyArtifacts);
+ return this;
+ }
+
+ /** Sets Java compiler flags. */
+ public Builder setJavacOpts(ImmutableList<String> javacOpts) {
+ checkNotNull(javacOpts, "javacOpts must not be null");
+ this.javacOpts = javacOpts;
+ return this;
+ }
+
+ /** Sets the output jar. */
+ public Builder setOutputJar(Artifact outputJar) {
+ checkNotNull(outputJar, "outputJar must not be null");
+ this.outputJar = outputJar;
+ return this;
+ }
+
+ /** Adds a Java source file to compile. */
+ public Builder addSourceFile(Artifact sourceFile) {
+ checkNotNull(sourceFile, "sourceFile must not be null");
+ sourceFiles.add(sourceFile);
+ return this;
+ }
+
+ /** Adds Java source files to compile. */
+ public Builder addSourceFiles(Collection<Artifact> sourceFiles) {
+ checkNotNull(sourceFiles, "sourceFiles must not be null");
+ this.sourceFiles.addAll(sourceFiles);
+ return this;
+ }
+
+ /** Adds a jar archive of Java sources to compile. */
+ public Builder addSourceJars(Collection<Artifact> sourceJars) {
+ checkNotNull(sourceJars, "sourceJars must not be null");
+ this.sourceJars.addAll(sourceJars);
+ return this;
+ }
+
+ /** Sets the compilation classpath entries. */
+ public Builder setClasspathEntries(NestedSet<Artifact> classpathEntries) {
+ checkNotNull(classpathEntries, "classpathEntries must not be null");
+ this.classpathEntries = classpathEntries;
+ return this;
+ }
+
+ /** Sets the compilation bootclasspath entries. */
+ public Builder addAllBootclasspathEntries(
+ Collection<Artifact> bootclasspathEntries) {
+ checkNotNull(bootclasspathEntries, "bootclasspathEntries must not be null");
+ this.bootclasspathEntries.addAll(bootclasspathEntries);
+ return this;
+ }
+
+ /** Sets the compilation extclasspath entries. */
+ public Builder addAllExtClasspathEntries(
+ Collection<Artifact> extclasspathEntries) {
+ checkNotNull(extclasspathEntries, "extclasspathEntries must not be null");
+ // fold extclasspath entries into the bootclasspath; that's what javac ends up doing
+ this.bootclasspathEntries.addAll(extclasspathEntries);
+ return this;
+ }
+
+ /** Sets the annotation processors classpath entries. */
+ public Builder addProcessorPaths(Collection<Artifact> processorPaths) {
+ checkNotNull(processorPaths, "processorPaths must not be null");
+ this.processorPath.addAll(processorPaths);
+ return this;
+ }
+
+ /** Sets the fully-qualified class names of annotation processors to run. */
+ public Builder addProcessorNames(Collection<String> processorNames) {
+ checkNotNull(processorNames, "processorNames must not be null");
+ this.processorNames.addAll(processorNames);
+ return this;
+ }
+
+ /** Sets the kind of the build rule being compiled (e.g. {@code java_library}). */
+ public Builder setRuleKind(@Nullable String ruleKind) {
+ this.ruleKind = ruleKind;
+ return this;
+ }
+
+ /** Sets the label of the target being compiled. */
+ public Builder setTargetLabel(@Nullable Label targetLabel) {
+ this.targetLabel = targetLabel;
+ return this;
+ }
+
+ /**
+ * Sets the path to a temporary directory, e.g. for extracting sourcejar entries to before
+ * compilation.
+ */
+ public Builder setTempDirectory(PathFragment tempDirectory) {
+ checkNotNull(tempDirectory, "tempDirectory must not be null");
+ this.tempDirectory = tempDirectory;
+ return this;
+ }
+
+ /** Sets the Strict Java Deps mode. */
+ public Builder setStrictJavaDeps(BuildConfiguration.StrictDepsMode strictJavaDeps) {
+ checkNotNull(strictJavaDeps, "strictJavaDeps must not be null");
+ this.strictJavaDeps = strictJavaDeps;
+ return this;
+ }
+
+ /** Sets the javabase inputs. */
+ public Builder setJavaBaseInputs(NestedSet<Artifact> javabaseInputs) {
+ checkNotNull(javabaseInputs, "javabaseInputs must not be null");
+ this.javabaseInputs = javabaseInputs;
+ return this;
+ }
+
+ /** Sets the javac jar. */
+ public Builder setJavacJar(Artifact javacJar) {
+ checkNotNull(javacJar, "javacJar must not be null");
+ this.javacJar = javacJar;
+ return this;
+ }
+ /** Builds and registers the {@link JavaHeaderCompileAction} for a header compilation. */
+ public void build() {
+ checkNotNull(outputDepsProto, "outputDepsProto must not be null");
+ checkNotNull(sourceFiles, "sourceFiles must not be null");
+ checkNotNull(sourceJars, "sourceJars must not be null");
+ checkNotNull(classpathEntries, "classpathEntries must not be null");
+ checkNotNull(bootclasspathEntries, "bootclasspathEntries must not be null");
+ checkNotNull(tempDirectory, "tempDirectory must not be null");
+ checkNotNull(strictJavaDeps, "strictJavaDeps must not be null");
+ checkNotNull(directJars, "directJars must not be null");
+ checkNotNull(compileTimeDependencyArtifacts,
+ "compileTimeDependencyArtifacts must not be null");
+ checkNotNull(javacOpts, "javacOpts must not be null");
+ checkNotNull(processorPath, "processorPath must not be null");
+ checkNotNull(processorNames, "processorNames must not be null");
+
+ CommandLine commandLine = buildCommandLine();
+ // Invariant: if strictJavaDeps is OFF, then directJars and
+ // dependencyArtifacts are ignored
+ if (strictJavaDeps == BuildConfiguration.StrictDepsMode.OFF) {
+ directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
+ compileTimeDependencyArtifacts.clear();
+ }
+ JavaToolchainProvider javaToolchain =
+ ruleContext.getPrerequisite(
+ ":java_toolchain" + implicitAttributesSuffix,
+ RuleConfiguredTarget.Mode.TARGET,
+ JavaToolchainProvider.class);
+ List<String> jvmArgs =
+ ImmutableList.<String>builder()
+ .add("-Xverify:none")
+ .addAll(javaToolchain.getJvmOptions())
+ .add("-Xbootclasspath/p:" + javacJar.getExecPath().getPathString())
+ .build();
+ PathFragment paramFilePath = ParameterFile.derivePath(outputJar.getRootRelativePath());
+ Artifact paramsFile = ruleContext.getAnalysisEnvironment().getDerivedArtifact(
+ paramFilePath, outputJar.getRoot());
+ Action parameterFileWriteAction = new ParameterFileWriteAction(
+ ruleContext.getActionOwner(), paramsFile, commandLine,
+ ParameterFile.ParameterFileType.UNQUOTED, ISO_8859_1);
+ CommandLine turbineCommandLine = CustomCommandLine.builder()
+ .addPath(ruleContext.getHostConfiguration().getFragment(Jvm.class).getJavaExecutable())
+ .add(jvmArgs)
+ .addExecPath("-jar", javaToolchain.getHeaderCompiler())
+ .addPaths("@%s", paramsFile.getExecPath())
+
+ .build();
+ Iterable<Artifact> tools = ImmutableList.of(javacJar, javaToolchain.getHeaderCompiler());
+ JavaHeaderCompileAction javaHeaderCompileAction = new JavaHeaderCompileAction(
+ ruleContext.getActionOwner(),
+ tools,
+ NestedSetBuilder.<Artifact>stableOrder()
+ .addTransitive(javabaseInputs)
+ .addTransitive(classpathEntries)
+ .addAll(bootclasspathEntries)
+ .addAll(processorPath)
+ .addAll(sourceJars)
+ .addAll(sourceFiles)
+ .addTransitive(directJars)
+ .addAll(tools)
+ .addAll(compileTimeDependencyArtifacts)
+ .add(paramsFile)
+ .build(),
+ new ArrayList<>(Collections2.filter(Arrays.asList(
+ outputJar,
+ outputDepsProto), Predicates.notNull())),
+ turbineCommandLine,
+ "Compiling Java headers " + outputJar.prettyPrint() + " ("
+ + (sourceFiles.size() + sourceJars.size()) + " files)"
+ );
+ ruleContext.registerAction(parameterFileWriteAction, javaHeaderCompileAction);
+ }
+
+ /** Builds the header compiler command line. */
+ private CommandLine buildCommandLine() {
+ CustomCommandLine.Builder result = CustomCommandLine.builder();
+
+ result.addExecPath("--output", outputJar);
+
+ if (outputDepsProto != null) {
+ result.addExecPath("--output_deps", outputDepsProto);
+ }
+
+ result.add("--temp_dir").addPath(tempDirectory);
+
+ result.addExecPaths("--classpath", classpathEntries);
+ result.addExecPaths("--bootclasspath", bootclasspathEntries);
+
+ if (!processorNames.isEmpty()) {
+ result.add("--processors", processorNames);
+ }
+ if (!processorPath.isEmpty()) {
+ result.addExecPaths("--processorpath", processorPath);
+ }
+
+ result.addExecPaths("--sources", sourceFiles);
+
+ if (!sourceJars.isEmpty()) {
+ result.addExecPaths("--source_jars", sourceJars);
+ }
+
+ result.add("--javacopts", javacOpts);
+
+ if (ruleKind != null) {
+ result.add("--rule_kind");
+ result.add(ruleKind);
+ }
+ if (targetLabel != null) {
+ result.add("--target_label");
+ if (targetLabel.getPackageIdentifier().getRepository().isDefault()
+ || targetLabel.getPackageIdentifier().getRepository().isMain()) {
+ result.add(targetLabel.toString());
+ } else {
+ // @-prefixed strings will be assumed to be params filenames and expanded,
+ // so add an extra @ to escape it.
+ result.add("@" + targetLabel);
+ }
+ }
+
+ if (strictJavaDeps != BuildConfiguration.StrictDepsMode.OFF) {
+ result.add(new JavaCompileAction.JarsToTargetsArgv(classpathEntries, directJars));
+
+ if (!compileTimeDependencyArtifacts.isEmpty()) {
+ result.addExecPaths("--deps_artifacts", compileTimeDependencyArtifacts);
+ }
+ }
+
+ return result.build();
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java
deleted file mode 100644
index 8fb7823861..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2016 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.rules.java;
-
-import static com.google.devtools.build.lib.util.Preconditions.checkNotNull;
-
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.actions.ResourceSet;
-import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.actions.CommandLine;
-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;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode;
-import com.google.devtools.build.lib.cmdline.Label;
-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.vfs.PathFragment;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Nullable;
-
-/**
- * Builder for Java header compilation actions, to be used if --java_header_compilation is enabled.
- *
- * <p>The header compiler consumes the inputs of a java compilation, and produces an interface jar
- * that can be used as a compile-time jar by upstream targets. The header interface jar is
- * equivalent to the output of ijar, but unlike ijar the header compiler operates directly on Java
- * source files instead post-processing the class outputs of the compilation. Compiling the
- * interface jar from source moves javac off the build's critical path.
- *
- * <p>The implementation of the header compiler tool can be found under {@code
- * //src/java_tools/buildjar/java/com/google/devtools/build/java/turbine}.
- */
-public class JavaHeaderCompileActionBuilder {
-
- static final ResourceSet RESOURCE_SET =
- ResourceSet.createWithRamCpuIo(/*memoryMb=*/ 750.0, /*cpuUsage=*/ 0.5, /*ioUsage=*/ 0.0);
-
- private final RuleContext ruleContext;
- private final String implicitAttributesSuffix;
-
- private Artifact outputJar;
- @Nullable private Artifact outputDepsProto;
- private final Collection<Artifact> sourceFiles = new ArrayList<>();
- private final Collection<Artifact> sourceJars = new ArrayList<>();
- private NestedSet<Artifact> classpathEntries = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
- private List<Artifact> bootclasspathEntries = new ArrayList<>();
- @Nullable private String ruleKind;
- @Nullable private Label targetLabel;
- private PathFragment tempDirectory;
- private BuildConfiguration.StrictDepsMode strictJavaDeps = BuildConfiguration.StrictDepsMode.OFF;
- private NestedSet<Artifact> directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
- private List<Artifact> compileTimeDependencyArtifacts = new ArrayList<>();
- private ImmutableList<String> javacOpts;
- private List<Artifact> processorPath = new ArrayList<>();
- private List<String> processorNames = new ArrayList<>();
- private NestedSet<Artifact> javabaseInputs;
- private Artifact javacJar;
-
- /** Creates a builder using the configuration of the rule as the action configuration. */
- public JavaHeaderCompileActionBuilder(RuleContext ruleContext, String implicitAttributesSuffix) {
- this.ruleContext = ruleContext;
- this.implicitAttributesSuffix = implicitAttributesSuffix;
- }
-
- /** Sets the output jdeps file. */
- public JavaHeaderCompileActionBuilder setOutputDepsProto(@Nullable Artifact outputDepsProto) {
- this.outputDepsProto = outputDepsProto;
- return this;
- }
-
- /** Sets the direct dependency artifacts. */
- public JavaHeaderCompileActionBuilder setDirectJars(NestedSet<Artifact> directJars) {
- checkNotNull(directJars, "directJars must not be null");
- this.directJars = directJars;
- return this;
- }
-
- /** Sets the .jdeps artifacts for direct dependencies. */
- public JavaHeaderCompileActionBuilder addCompileTimeDependencyArtifacts(
- Collection<Artifact> dependencyArtifacts) {
- checkNotNull(dependencyArtifacts, "dependencyArtifacts must not be null");
- this.compileTimeDependencyArtifacts.addAll(dependencyArtifacts);
- return this;
- }
-
- /** Sets Java compiler flags. */
- public JavaHeaderCompileActionBuilder setJavacOpts(ImmutableList<String> javacOpts) {
- checkNotNull(javacOpts, "javacOpts must not be null");
- this.javacOpts = javacOpts;
- return this;
- }
-
- /** Sets the output jar. */
- public JavaHeaderCompileActionBuilder setOutputJar(Artifact outputJar) {
- checkNotNull(outputJar, "outputJar must not be null");
- this.outputJar = outputJar;
- return this;
- }
-
- /** Adds a Java source file to compile. */
- public JavaHeaderCompileActionBuilder addSourceFile(Artifact sourceFile) {
- checkNotNull(sourceFile, "sourceFile must not be null");
- sourceFiles.add(sourceFile);
- return this;
- }
-
- /** Adds Java source files to compile. */
- public JavaHeaderCompileActionBuilder addSourceFiles(Collection<Artifact> sourceFiles) {
- checkNotNull(sourceFiles, "sourceFiles must not be null");
- this.sourceFiles.addAll(sourceFiles);
- return this;
- }
-
- /** Adds a jar archive of Java sources to compile. */
- public JavaHeaderCompileActionBuilder addSourceJars(Collection<Artifact> sourceJars) {
- checkNotNull(sourceJars, "sourceJars must not be null");
- this.sourceJars.addAll(sourceJars);
- return this;
- }
-
- /** Sets the compilation classpath entries. */
- public JavaHeaderCompileActionBuilder setClasspathEntries(NestedSet<Artifact> classpathEntries) {
- checkNotNull(classpathEntries, "classpathEntries must not be null");
- this.classpathEntries = classpathEntries;
- return this;
- }
-
- /** Sets the compilation bootclasspath entries. */
- public JavaHeaderCompileActionBuilder addAllBootclasspathEntries(
- Collection<Artifact> bootclasspathEntries) {
- checkNotNull(bootclasspathEntries, "bootclasspathEntries must not be null");
- this.bootclasspathEntries.addAll(bootclasspathEntries);
- return this;
- }
-
- /** Sets the compilation extclasspath entries. */
- public JavaHeaderCompileActionBuilder addAllExtClasspathEntries(
- Collection<Artifact> extclasspathEntries) {
- checkNotNull(extclasspathEntries, "extclasspathEntries must not be null");
- // fold extclasspath entries into the bootclasspath; that's what javac ends up doing
- this.bootclasspathEntries.addAll(extclasspathEntries);
- return this;
- }
-
- /** Sets the annotation processors classpath entries. */
- public JavaHeaderCompileActionBuilder addProcessorPaths(Collection<Artifact> processorPaths) {
- checkNotNull(processorPaths, "processorPaths must not be null");
- this.processorPath.addAll(processorPaths);
- return this;
- }
-
- /** Sets the fully-qualified class names of annotation processors to run. */
- public JavaHeaderCompileActionBuilder addProcessorNames(Collection<String> processorNames) {
- checkNotNull(processorNames, "processorNames must not be null");
- this.processorNames.addAll(processorNames);
- return this;
- }
-
- /** Sets the kind of the build rule being compiled (e.g. {@code java_library}). */
- public JavaHeaderCompileActionBuilder setRuleKind(@Nullable String ruleKind) {
- this.ruleKind = ruleKind;
- return this;
- }
-
- /** Sets the label of the target being compiled. */
- public JavaHeaderCompileActionBuilder setTargetLabel(@Nullable Label targetLabel) {
- this.targetLabel = targetLabel;
- return this;
- }
-
- /**
- * Sets the path to a temporary directory, e.g. for extracting sourcejar entries to before
- * compilation.
- */
- public JavaHeaderCompileActionBuilder setTempDirectory(PathFragment tempDirectory) {
- checkNotNull(tempDirectory, "tempDirectory must not be null");
- this.tempDirectory = tempDirectory;
- return this;
- }
-
- /** Sets the Strict Java Deps mode. */
- public JavaHeaderCompileActionBuilder setStrictJavaDeps(StrictDepsMode strictJavaDeps) {
- checkNotNull(strictJavaDeps, "strictJavaDeps must not be null");
- this.strictJavaDeps = strictJavaDeps;
- return this;
- }
-
- /** Sets the javabase inputs. */
- public JavaHeaderCompileActionBuilder setJavaBaseInputs(NestedSet<Artifact> javabaseInputs) {
- checkNotNull(javabaseInputs, "javabaseInputs must not be null");
- this.javabaseInputs = javabaseInputs;
- return this;
- }
-
- /** Sets the javac jar. */
- public JavaHeaderCompileActionBuilder setJavacJar(Artifact javacJar) {
- checkNotNull(javacJar, "javacJar must not be null");
- this.javacJar = javacJar;
- return this;
- }
-
- /** Builds and registers the {@link SpawnAction} for a header compilation. */
- public void build() {
- checkNotNull(outputDepsProto, "outputDepsProto must not be null");
- checkNotNull(sourceFiles, "sourceFiles must not be null");
- checkNotNull(sourceJars, "sourceJars must not be null");
- checkNotNull(classpathEntries, "classpathEntries must not be null");
- checkNotNull(bootclasspathEntries, "bootclasspathEntries must not be null");
- checkNotNull(tempDirectory, "tempDirectory must not be null");
- checkNotNull(strictJavaDeps, "strictJavaDeps must not be null");
- checkNotNull(directJars, "directJars must not be null");
- checkNotNull(compileTimeDependencyArtifacts, "compileTimeDependencyArtifacts must not be null");
- checkNotNull(javacOpts, "javacOpts must not be null");
- checkNotNull(processorPath, "processorPath must not be null");
- checkNotNull(processorNames, "processorNames must not be null");
-
- // Invariant: if strictJavaDeps is OFF, then directJars and
- // dependencyArtifacts are ignored
- if (strictJavaDeps == BuildConfiguration.StrictDepsMode.OFF) {
- directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
- compileTimeDependencyArtifacts.clear();
- }
-
- SpawnAction.Builder builder = new SpawnAction.Builder();
-
- builder.addOutput(outputJar);
- if (outputDepsProto != null) {
- builder.addOutput(outputDepsProto);
- }
-
- // Always use a params file. The arguments (classpath in particular) may be so large that
- // comparing the command line length to the minimum param file size regresses analysis
- // performance (see b/29410356).
- builder.alwaysUseParameterFile(ParameterFileType.UNQUOTED);
- builder.setCommandLine(buildCommandLine());
-
- builder.addTransitiveInputs(javabaseInputs);
- builder.addTransitiveInputs(classpathEntries);
- builder.addInputs(bootclasspathEntries);
- builder.addInputs(processorPath);
- builder.addInputs(sourceJars);
- builder.addInputs(sourceFiles);
- builder.addTransitiveInputs(directJars);
- builder.addInputs(compileTimeDependencyArtifacts);
-
- builder.addTool(javacJar);
-
- JavaToolchainProvider javaToolchain =
- ruleContext.getPrerequisite(
- ":java_toolchain" + implicitAttributesSuffix, Mode.TARGET, JavaToolchainProvider.class);
- List<String> jvmArgs =
- ImmutableList.<String>builder()
- .addAll(javaToolchain.getJvmOptions())
- .add("-Xbootclasspath/p:" + javacJar.getExecPath().getPathString())
- .build();
- builder.setJarExecutable(
- ruleContext.getHostConfiguration().getFragment(Jvm.class).getJavaExecutable(),
- javaToolchain.getHeaderCompiler(),
- jvmArgs);
-
- builder.setResources(RESOURCE_SET);
-
- builder.setMnemonic("Turbine");
-
- int count = sourceFiles.size() + sourceJars.size();
- builder.setProgressMessage(
- "Compiling Java headers " + outputJar.prettyPrint() + " (" + count + " files)");
-
- ruleContext.registerAction(builder.build(ruleContext));
- }
-
- /** Builds the header compiler command line. */
- private CommandLine buildCommandLine() {
- CustomCommandLine.Builder result = CustomCommandLine.builder();
-
- result.addExecPath("--output", outputJar);
-
- if (outputDepsProto != null) {
- result.addExecPath("--output_deps", outputDepsProto);
- }
-
- result.add("--temp_dir").addPath(tempDirectory);
-
- result.addExecPaths("--classpath", classpathEntries);
- result.addExecPaths("--bootclasspath", bootclasspathEntries);
-
- if (!processorNames.isEmpty()) {
- result.add("--processors", processorNames);
- }
- if (!processorPath.isEmpty()) {
- result.addExecPaths("--processorpath", processorPath);
- }
-
- result.addExecPaths("--sources", sourceFiles);
-
- if (!sourceJars.isEmpty()) {
- result.addExecPaths("--source_jars", sourceJars);
- }
-
- result.add("--javacopts", javacOpts);
-
- if (ruleKind != null) {
- result.add("--rule_kind");
- result.add(ruleKind);
- }
- if (targetLabel != null) {
- result.add("--target_label");
- if (targetLabel.getPackageIdentifier().getRepository().isDefault()
- || targetLabel.getPackageIdentifier().getRepository().isMain()) {
- result.add(targetLabel.toString());
- } else {
- // @-prefixed strings will be assumed to be params filenames and expanded,
- // so add an extra @ to escape it.
- result.add("@" + targetLabel);
- }
- }
-
- if (strictJavaDeps != BuildConfiguration.StrictDepsMode.OFF) {
- result.add(new JavaCompileAction.JarsToTargetsArgv(classpathEntries, directJars));
-
- if (!compileTimeDependencyArtifacts.isEmpty()) {
- result.addExecPaths("--deps_artifacts", compileTimeDependencyArtifacts);
- }
- }
-
- return result.build();
- }
-}