| // 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.common.base.Preconditions.checkNotNull; |
| import static com.google.common.base.Preconditions.checkState; |
| import static com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType.UNQUOTED; |
| import static com.google.devtools.build.lib.rules.java.JavaCompileActionBuilder.UTF8_ENVIRONMENT; |
| import static java.nio.charset.StandardCharsets.ISO_8859_1; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Sets; |
| import com.google.devtools.build.lib.actions.AbstractAction; |
| import com.google.devtools.build.lib.actions.ActionEnvironment; |
| import com.google.devtools.build.lib.actions.ActionExecutionContext; |
| import com.google.devtools.build.lib.actions.ActionOwner; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import com.google.devtools.build.lib.actions.CommandLines; |
| import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier; |
| import com.google.devtools.build.lib.actions.ExecutionRequirements; |
| import com.google.devtools.build.lib.actions.ParamFileInfo; |
| import com.google.devtools.build.lib.actions.PathMapper; |
| import com.google.devtools.build.lib.actions.ResourceSetOrBuilder; |
| import com.google.devtools.build.lib.actions.RunfilesSupplier; |
| import com.google.devtools.build.lib.actions.SpawnResult; |
| import com.google.devtools.build.lib.analysis.RuleContext; |
| import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; |
| import com.google.devtools.build.lib.analysis.actions.PathMappers; |
| import com.google.devtools.build.lib.analysis.actions.SpawnAction; |
| import com.google.devtools.build.lib.analysis.config.CoreOptionConverters.StrictDepsMode; |
| import com.google.devtools.build.lib.analysis.config.CoreOptions.OutputPathsMode; |
| 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.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; |
| import com.google.devtools.build.lib.packages.TargetUtils; |
| import com.google.devtools.build.lib.rules.java.JavaCompileAction.ProgressMessage; |
| import com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaClasspathMode; |
| import com.google.devtools.build.lib.rules.java.JavaPluginInfo.JavaPluginData; |
| import com.google.devtools.build.lib.util.OnDemandString; |
| import com.google.devtools.build.lib.view.proto.Deps; |
| import com.google.errorprone.annotations.CanIgnoreReturnValue; |
| import java.io.IOException; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Objects; |
| import java.util.stream.Stream; |
| 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 final class JavaHeaderCompileAction extends SpawnAction { |
| |
| private static final String DIRECT_CLASSPATH_MNEMONIC = "Turbine"; |
| |
| private final boolean insertDependencies; |
| private final NestedSet<Artifact> additionalArtifactsForPathMapping; |
| |
| private JavaHeaderCompileAction( |
| ActionOwner owner, |
| NestedSet<Artifact> tools, |
| NestedSet<Artifact> inputs, |
| Iterable<? extends Artifact> outputs, |
| ResourceSetOrBuilder resourceSetOrBuilder, |
| CommandLines commandLines, |
| ActionEnvironment env, |
| ImmutableMap<String, String> executionInfo, |
| CharSequence progressMessage, |
| RunfilesSupplier runfilesSupplier, |
| String mnemonic, |
| OutputPathsMode outputPathsMode, |
| boolean insertDependencies, |
| NestedSet<Artifact> additionalArtifactsForPathMapping) { |
| super( |
| owner, |
| tools, |
| inputs, |
| outputs, |
| resourceSetOrBuilder, |
| commandLines, |
| env, |
| executionInfo, |
| progressMessage, |
| runfilesSupplier, |
| mnemonic, |
| outputPathsMode); |
| this.insertDependencies = insertDependencies; |
| this.additionalArtifactsForPathMapping = additionalArtifactsForPathMapping; |
| } |
| |
| @Override |
| public NestedSet<Artifact> getAdditionalArtifactsForPathMapping() { |
| return additionalArtifactsForPathMapping; |
| } |
| |
| @Override |
| protected void afterExecute( |
| ActionExecutionContext context, List<SpawnResult> spawnResults, PathMapper pathMapper) { |
| SpawnResult spawnResult = Iterables.getOnlyElement(spawnResults); |
| Artifact outputDepsProto = Iterables.get(getOutputs(), 1); |
| try { |
| Deps.Dependencies fullOutputDeps = |
| JavaCompileAction.createFullOutputDeps( |
| spawnResult, |
| outputDepsProto, |
| getInputs(), |
| getAdditionalArtifactsForPathMapping(), |
| context, |
| pathMapper); |
| JavaCompileActionContext javaContext = context.getContext(JavaCompileActionContext.class); |
| if (insertDependencies && javaContext != null) { |
| javaContext.insertDependencies(outputDepsProto, fullOutputDeps); |
| } |
| } catch (IOException e) { |
| // Left empty. If we cannot read the .jdeps file now, we will read it later or throw an |
| // appropriate error then. |
| } |
| } |
| |
| public static Builder newBuilder(RuleContext ruleContext) { |
| return new Builder(ruleContext); |
| } |
| |
| /** Builder for {@link JavaHeaderCompileAction}. */ |
| public static final class Builder { |
| |
| private static final ParamFileInfo PARAM_FILE_INFO = |
| ParamFileInfo.builder(UNQUOTED).setCharset(ISO_8859_1).build(); |
| |
| private final RuleContext ruleContext; |
| |
| private Artifact outputJar; |
| // Only non-null before set. |
| private Artifact outputDepsProto; |
| @Nullable private Artifact manifestOutput; |
| @Nullable private Artifact gensrcOutputJar; |
| @Nullable private Artifact resourceOutputJar; |
| private ImmutableSet<Artifact> additionalOutputs = ImmutableSet.of(); |
| private ImmutableSet<Artifact> sourceFiles = ImmutableSet.of(); |
| private ImmutableList<Artifact> sourceJars = ImmutableList.of(); |
| private NestedSet<Artifact> classpathEntries = |
| NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); |
| private NestedSet<Artifact> bootclasspathEntries = |
| NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); |
| @Nullable private Label targetLabel; |
| @Nullable private String injectingRuleKind; |
| private StrictDepsMode strictJavaDeps = StrictDepsMode.OFF; |
| private NestedSet<Artifact> directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); |
| private NestedSet<Artifact> compileTimeDependencyArtifacts = |
| NestedSetBuilder.emptySet(Order.STABLE_ORDER); |
| private ImmutableList<String> javacOpts = ImmutableList.of(); |
| private boolean addTurbineHjarJavacOpt = false; |
| private JavaPluginData plugins = JavaPluginData.empty(); |
| |
| private ImmutableList<Artifact> additionalInputs = ImmutableList.of(); |
| private NestedSet<Artifact> toolsJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); |
| |
| private boolean enableHeaderCompilerDirect = true; |
| |
| private boolean enableDirectClasspath = true; |
| |
| private Builder(RuleContext ruleContext) { |
| this.ruleContext = ruleContext; |
| } |
| |
| /** Sets the output jdeps file. */ |
| @CanIgnoreReturnValue |
| public Builder setOutputDepsProto(Artifact outputDepsProto) { |
| this.outputDepsProto = checkNotNull(outputDepsProto); |
| return this; |
| } |
| |
| @CanIgnoreReturnValue |
| public Builder setManifestOutput(@Nullable Artifact manifestOutput) { |
| this.manifestOutput = manifestOutput; |
| return this; |
| } |
| |
| @CanIgnoreReturnValue |
| public Builder setGensrcOutputJar(@Nullable Artifact gensrcOutputJar) { |
| this.gensrcOutputJar = gensrcOutputJar; |
| return this; |
| } |
| |
| @CanIgnoreReturnValue |
| public Builder setResourceOutputJar(@Nullable Artifact resourceOutputJar) { |
| this.resourceOutputJar = resourceOutputJar; |
| return this; |
| } |
| |
| /** Sets the direct dependency artifacts. */ |
| @CanIgnoreReturnValue |
| 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. */ |
| @CanIgnoreReturnValue |
| public Builder setCompileTimeDependencyArtifacts(NestedSet<Artifact> dependencyArtifacts) { |
| checkNotNull(dependencyArtifacts, "dependencyArtifacts must not be null"); |
| this.compileTimeDependencyArtifacts = dependencyArtifacts; |
| return this; |
| } |
| |
| /** Sets Java compiler flags. */ |
| @CanIgnoreReturnValue |
| public Builder setJavacOpts(ImmutableList<String> javacOpts) { |
| this.javacOpts = checkNotNull(javacOpts); |
| return this; |
| } |
| |
| /** |
| * Adds {@code -Aexperimental_turbine_hjar} to Java compiler flags without creating an entirely |
| * new list. |
| */ |
| @CanIgnoreReturnValue |
| public Builder addTurbineHjarJavacOpt() { |
| this.addTurbineHjarJavacOpt = true; |
| return this; |
| } |
| |
| /** Sets the output jar. */ |
| @CanIgnoreReturnValue |
| public Builder setOutputJar(Artifact outputJar) { |
| checkNotNull(outputJar, "outputJar must not be null"); |
| this.outputJar = outputJar; |
| return this; |
| } |
| |
| @CanIgnoreReturnValue |
| public Builder setAdditionalOutputs(ImmutableSet<Artifact> outputs) { |
| checkNotNull(outputs, "outputs must not be null"); |
| this.additionalOutputs = outputs; |
| return this; |
| } |
| |
| /** Adds Java source files to compile. */ |
| @CanIgnoreReturnValue |
| public Builder setSourceFiles(ImmutableSet<Artifact> sourceFiles) { |
| checkNotNull(sourceFiles, "sourceFiles must not be null"); |
| this.sourceFiles = sourceFiles; |
| return this; |
| } |
| |
| /** Adds a jar archive of Java sources to compile. */ |
| @CanIgnoreReturnValue |
| public Builder setSourceJars(ImmutableList<Artifact> sourceJars) { |
| checkNotNull(sourceJars, "sourceJars must not be null"); |
| this.sourceJars = sourceJars; |
| return this; |
| } |
| |
| /** Sets the compilation classpath entries. */ |
| @CanIgnoreReturnValue |
| public Builder setClasspathEntries(NestedSet<Artifact> classpathEntries) { |
| checkNotNull(classpathEntries, "classpathEntries must not be null"); |
| this.classpathEntries = classpathEntries; |
| return this; |
| } |
| |
| /** Sets the compilation bootclasspath entries. */ |
| @CanIgnoreReturnValue |
| public Builder setBootclasspathEntries(NestedSet<Artifact> bootclasspathEntries) { |
| checkNotNull(bootclasspathEntries, "bootclasspathEntries must not be null"); |
| this.bootclasspathEntries = bootclasspathEntries; |
| return this; |
| } |
| |
| /** Sets the annotation processors classpath entries. */ |
| @CanIgnoreReturnValue |
| public Builder setPlugins(JavaPluginData plugins) { |
| checkNotNull(plugins, "plugins must not be null"); |
| checkState(this.plugins.isEmpty()); |
| this.plugins = plugins; |
| return this; |
| } |
| |
| /** Sets the label of the target being compiled. */ |
| @CanIgnoreReturnValue |
| public Builder setTargetLabel(@Nullable Label targetLabel) { |
| this.targetLabel = targetLabel; |
| return this; |
| } |
| |
| /** Sets the injecting rule kind of the target being compiled. */ |
| @CanIgnoreReturnValue |
| public Builder setInjectingRuleKind(@Nullable String injectingRuleKind) { |
| this.injectingRuleKind = injectingRuleKind; |
| return this; |
| } |
| |
| /** Sets the Strict Java Deps mode. */ |
| @CanIgnoreReturnValue |
| public Builder setStrictJavaDeps(StrictDepsMode strictJavaDeps) { |
| checkNotNull(strictJavaDeps, "strictJavaDeps must not be null"); |
| this.strictJavaDeps = strictJavaDeps; |
| return this; |
| } |
| |
| /** Sets additional inputs, e.g. for databinding support. */ |
| @CanIgnoreReturnValue |
| public Builder setAdditionalInputs(ImmutableList<Artifact> additionalInputs) { |
| checkNotNull(additionalInputs, "additionalInputs must not be null"); |
| this.additionalInputs = additionalInputs; |
| return this; |
| } |
| |
| /** Sets the tools jars. */ |
| @CanIgnoreReturnValue |
| public Builder setToolsJars(NestedSet<Artifact> toolsJars) { |
| checkNotNull(toolsJars, "toolsJars must not be null"); |
| this.toolsJars = toolsJars; |
| return this; |
| } |
| |
| @CanIgnoreReturnValue |
| public Builder enableHeaderCompilerDirect(boolean enableHeaderCompilerDirect) { |
| this.enableHeaderCompilerDirect = enableHeaderCompilerDirect; |
| return this; |
| } |
| |
| @CanIgnoreReturnValue |
| public Builder enableDirectClasspath(boolean enableDirectClasspath) { |
| this.enableDirectClasspath = enableDirectClasspath; |
| return this; |
| } |
| |
| /** Builds and registers the action for a header compilation. */ |
| public void build(JavaToolchainProvider javaToolchain) throws RuleErrorException { |
| 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(strictJavaDeps, "strictJavaDeps must not be null"); |
| checkNotNull(directJars, "directJars must not be null"); |
| checkNotNull( |
| compileTimeDependencyArtifacts, "compileTimeDependencyArtifacts must not be null"); |
| |
| // Invariant: if strictJavaDeps is OFF, then directJars and |
| // dependencyArtifacts are ignored |
| if (strictJavaDeps == StrictDepsMode.OFF) { |
| directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); |
| compileTimeDependencyArtifacts = NestedSetBuilder.emptySet(Order.STABLE_ORDER); |
| } |
| |
| // Enable the direct classpath optimization if there are no annotation processors. |
| // N.B. we only check if the processor classes are empty, we don't care if there is plugin |
| // data or dependencies if there are no annotation processors to run. This differs from |
| // javac where java_plugin may be used with processor_class unset to declare Error Prone |
| // plugins. |
| boolean useDirectClasspath = enableDirectClasspath && plugins.processorClasses().isEmpty(); |
| |
| // Use the optimized 'direct' implementation if it is available, and either there are no |
| // annotation processors or they are built in to the tool and listed in |
| // java_toolchain.header_compiler_direct_processors. |
| ImmutableSet<String> processorClasses = plugins.processorClasses().toSet(); |
| boolean useHeaderCompilerDirect = |
| enableHeaderCompilerDirect |
| && javaToolchain.getHeaderCompilerDirect() != null |
| && javaToolchain.getHeaderCompilerBuiltinProcessors().containsAll(processorClasses); |
| JavaConfiguration javaConfiguration = |
| ruleContext.getConfiguration().getFragment(JavaConfiguration.class); |
| JavaClasspathMode classpathMode = javaConfiguration.getReduceJavaClasspath(); |
| if (!Collections.disjoint( |
| processorClasses, javaToolchain.getReducedClasspathIncompatibleProcessors())) { |
| classpathMode = JavaClasspathMode.OFF; |
| } |
| |
| ActionEnvironment actionEnvironment = |
| ruleContext |
| .getConfiguration() |
| .getActionEnvironment() |
| .withAdditionalFixedVariables(UTF8_ENVIRONMENT); |
| |
| OnDemandString progressMessage = |
| new ProgressMessage( |
| /* prefix= */ "Compiling Java headers", |
| /* output= */ outputJar, |
| /* sourceFiles= */ sourceFiles, |
| /* sourceJars= */ sourceJars, |
| /* plugins= */ plugins); |
| |
| ImmutableSet.Builder<Artifact> outputs = |
| ImmutableSet.<Artifact>builder() |
| .add(outputJar) |
| .add(outputDepsProto) |
| .addAll(additionalOutputs); |
| Stream.of(gensrcOutputJar, resourceOutputJar, manifestOutput) |
| .filter(Objects::nonNull) |
| .forEachOrdered(outputs::add); |
| |
| NestedSetBuilder<Artifact> mandatoryInputsBuilder = |
| NestedSetBuilder.<Artifact>stableOrder() |
| .addAll(additionalInputs) |
| .addTransitive(bootclasspathEntries) |
| .addAll(sourceJars) |
| .addAll(sourceFiles) |
| .addTransitive(toolsJars); |
| |
| JavaToolchainTool headerCompiler = |
| useHeaderCompilerDirect |
| ? javaToolchain.getHeaderCompilerDirect() |
| : javaToolchain.getHeaderCompiler(); |
| // The header compiler is either a jar file that needs to be executed using |
| // `java -jar <path>`, or an executable that can be run directly. |
| headerCompiler.addInputs(javaToolchain, mandatoryInputsBuilder); |
| CustomCommandLine.Builder commandLine = |
| CustomCommandLine.builder() |
| .addExecPath("--output", outputJar) |
| .addExecPath("--gensrc_output", gensrcOutputJar) |
| .addExecPath("--resource_output", resourceOutputJar) |
| .addExecPath("--output_manifest_proto", manifestOutput) |
| .addExecPath("--output_deps", outputDepsProto) |
| .addExecPaths("--bootclasspath", bootclasspathEntries) |
| .addExecPaths("--sources", sourceFiles) |
| .addExecPaths("--source_jars", sourceJars) |
| .add("--injecting_rule_kind", injectingRuleKind); |
| |
| if (!javacOpts.isEmpty() || addTurbineHjarJavacOpt) { |
| commandLine.add("--javacopts"); |
| if (!javacOpts.isEmpty()) { |
| commandLine.addObject(javacOpts); |
| } |
| if (addTurbineHjarJavacOpt) { |
| commandLine.add("-Aexperimental_turbine_hjar"); |
| } |
| // terminate --javacopts with `--` to support javac flags that start with `--` |
| commandLine.add("--"); |
| } |
| |
| if (targetLabel != null) { |
| commandLine.add("--target_label"); |
| if (targetLabel.getRepository().isMain()) { |
| commandLine.addLabel(targetLabel); |
| } else { |
| // @-prefixed strings will be assumed to be params filenames and expanded, |
| // so add an extra @ to escape it. |
| commandLine.addPrefixedLabel("@", targetLabel); |
| } |
| } |
| |
| ImmutableMap.Builder<String, String> executionInfo = ImmutableMap.builder(); |
| executionInfo.putAll( |
| ruleContext |
| .getConfiguration() |
| .modifiedExecutionInfo( |
| ImmutableMap.of(ExecutionRequirements.SUPPORTS_PATH_MAPPING, "1"), |
| JavaCompileActionBuilder.MNEMONIC)); |
| executionInfo.putAll( |
| TargetUtils.getExecutionInfo( |
| ruleContext.getRule(), ruleContext.isAllowTagsPropagation())); |
| if (javaConfiguration.inmemoryJdepsFiles()) { |
| executionInfo.put( |
| ExecutionRequirements.REMOTE_EXECUTION_INLINE_OUTPUTS, |
| outputDepsProto.getExecPathString()); |
| } |
| |
| if (useDirectClasspath) { |
| NestedSet<Artifact> classpath; |
| NestedSet<Artifact> additionalArtifactsForPathMapping; |
| if (!directJars.isEmpty() || classpathEntries.isEmpty()) { |
| classpath = directJars; |
| // When using the direct classpath optimization, Turbine generates .jdeps entries based on |
| // the transitive dependency information packages into META-INF/TRANSITIVE. When path |
| // mapping is used, these entries may have been subject to it when they were generated. |
| // Since the contents of that directory are not unmapped, we need to instead unmap the |
| // paths emitted in the .jdeps file, which requires knowing the full list of artifact |
| // paths even if they aren't inputs to the current action. |
| // https://github.com/google/turbine/commit/f9f2decee04a3c651671f7488a7c9d7952df88c8 |
| additionalArtifactsForPathMapping = classpathEntries; |
| } else { |
| classpath = classpathEntries; |
| additionalArtifactsForPathMapping = NestedSetBuilder.emptySet(Order.STABLE_ORDER); |
| } |
| mandatoryInputsBuilder.addTransitive(classpath); |
| |
| commandLine.addExecPaths("--classpath", classpath); |
| commandLine.add("--reduce_classpath_mode", "NONE"); |
| |
| NestedSet<Artifact> allInputs = mandatoryInputsBuilder.build(); |
| CustomCommandLine executableLine = headerCompiler.getCommandLine(javaToolchain); |
| |
| ruleContext.registerAction( |
| new JavaHeaderCompileAction( |
| /* owner= */ ruleContext.getActionOwner(), |
| /* tools= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER), |
| /* inputs= */ allInputs, |
| /* outputs= */ outputs.build(), |
| /* resourceSetOrBuilder= */ AbstractAction.DEFAULT_RESOURCE_SET, |
| /* commandLines= */ CommandLines.builder() |
| .addCommandLine(executableLine) |
| .addCommandLine(commandLine.build(), PARAM_FILE_INFO) |
| .build(), |
| /* env= */ actionEnvironment, |
| /* executionInfo= */ ruleContext |
| .getConfiguration() |
| .modifiedExecutionInfo( |
| executionInfo.buildKeepingLast(), DIRECT_CLASSPATH_MNEMONIC), |
| /* progressMessage= */ progressMessage, |
| /* runfilesSupplier= */ EmptyRunfilesSupplier.INSTANCE, |
| |
| /* mnemonic= */ DIRECT_CLASSPATH_MNEMONIC, |
| /* outputPathsMode= */ PathMappers.getOutputPathsMode( |
| ruleContext.getConfiguration()), |
| // If classPathMode == BAZEL, also make sure to inject the dependencies to be |
| // available to downstream actions. Else just do enough work to locally create the |
| // full .jdeps from the .stripped .jdeps produced on the executor. |
| /* insertDependencies= */ classpathMode == JavaClasspathMode.BAZEL, |
| additionalArtifactsForPathMapping)); |
| return; |
| } |
| |
| // If we get here the action requires annotation processing, so add additional inputs and |
| // flags needed for the javac-based header compiler implementations that supports |
| // annotation processing. |
| |
| if (!useHeaderCompilerDirect) { |
| mandatoryInputsBuilder.addTransitive(plugins.processorClasspath()); |
| mandatoryInputsBuilder.addTransitive(plugins.data()); |
| } |
| |
| commandLine.addAll( |
| "--builtin_processors", |
| Sets.intersection( |
| plugins.processorClasses().toSet(), |
| javaToolchain.getHeaderCompilerBuiltinProcessors())); |
| commandLine.addAll("--processors", plugins.processorClasses()); |
| if (!useHeaderCompilerDirect) { |
| commandLine.addExecPaths("--processorpath", plugins.processorClasspath()); |
| } |
| if (strictJavaDeps != StrictDepsMode.OFF) { |
| commandLine.addExecPaths("--direct_dependencies", directJars); |
| } |
| |
| NestedSet<Artifact> mandatoryInputs = mandatoryInputsBuilder.build(); |
| |
| CustomCommandLine executableLine = headerCompiler.getCommandLine(javaToolchain); |
| |
| ruleContext.registerAction( |
| new JavaCompileAction( |
| /* compilationType= */ JavaCompileAction.CompilationType.TURBINE, |
| /* owner= */ ruleContext.getActionOwner(), |
| /* tools= */ toolsJars, |
| /* progressMessage= */ progressMessage, |
| /* mandatoryInputs= */ mandatoryInputs, |
| /* transitiveInputs= */ classpathEntries, |
| /* directJars= */ directJars, |
| /* outputs= */ outputs.build(), |
| /* executionInfo= */ executionInfo.buildKeepingLast(), |
| /* extraActionInfoSupplier= */ null, |
| /* executableLine= */ executableLine, |
| /* flagLine= */ commandLine.build(), |
| /* configuration= */ ruleContext.getConfiguration(), |
| /* dependencyArtifacts= */ compileTimeDependencyArtifacts, |
| /* outputDepsProto= */ outputDepsProto, |
| /* classpathMode= */ classpathMode)); |
| } |
| } |
| } |