diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis')
6 files changed, 253 insertions, 270 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java index bfc88bea31..e3139b4ab0 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java @@ -715,15 +715,6 @@ public final class CustomCommandLine extends CommandLine { } /** - * Concatenates the passed prefix string and the object's string representation. - * - * <p>Prefer {@link Builder#addPrefixed}, as it will be more memory efficient. - */ - Builder addWithDynamicPrefix(String prefix, @Nullable Object arg) { - return addPrefixedInternal(prefix, arg); - } - - /** * Adds the passed strings to the command line. * * <p>If you are converting long lists or nested sets of a different type to string lists, diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/ParamFileHelper.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/ParamFileHelper.java deleted file mode 100644 index 01781d422c..0000000000 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/ParamFileHelper.java +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2014 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.analysis.actions; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.actions.ActionOwner; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.CommandLineExpansionException; -import com.google.devtools.build.lib.actions.ParameterFile; -import com.google.devtools.build.lib.analysis.AnalysisEnvironment; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; -import com.google.devtools.build.lib.util.Preconditions; -import com.google.devtools.build.lib.vfs.PathFragment; -import java.util.List; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * A command-line implementation that wraps another command line and puts the arguments in a - * parameter file if necessary - * - * <p>The Linux kernel has a limit for the command line length, and that can be easily reached - * if, for example, a command is listing all its inputs on the command line. - */ -@Immutable -public final class ParamFileHelper { - - /** - * Returns a params file artifact or null for a given command description. - * - * <p>Returns null if parameter files are not to be used according to paramFileInfo, or if the - * command line is short enough that a parameter file is not needed. - * - * <p>Make sure to add the returned artifact (if not null) as an input of the corresponding - * action. - * - * @param executableArgs leading arguments that should never be wrapped in a parameter file - * @param commandLine a {@link CommandLine} that provides the arguments (in addition to - * executableArgs) - * @param paramFileInfo parameter file information - * @param configuration the configuration - * @param analysisEnvironment the analysis environment - * @param outputs outputs of the action (used to construct a filename for the params file) - */ - static Artifact getParamsFileMaybe( - List<String> executableArgs, - CommandLine commandLine, - @Nullable ParamFileInfo paramFileInfo, - BuildConfiguration configuration, - AnalysisEnvironment analysisEnvironment, - Iterable<Artifact> outputs) { - if (paramFileInfo == null) { - return null; - } - if (!paramFileInfo.always() - && getParamFileSize(executableArgs, commandLine) < configuration.getMinParamFileSize()) { - return null; - } - - Artifact output = Iterables.getFirst(outputs, null); - Preconditions.checkNotNull(output); - PathFragment paramFilePath = ParameterFile.derivePath(output.getRootRelativePath()); - return analysisEnvironment.getDerivedArtifact(paramFilePath, output.getRoot()); - } - - /** - * Creates a command line using an external params file. - * - * <p>Call this with the result of {@link #getParamsFileMaybe} if it is not null. - * - * @param executableArgs leading arguments that should never be wrapped in a parameter file - * @param paramFileInfo parameter file information - * @param parameterFile the output parameter file artifact - */ - public static CommandLine createWithParamsFile( - ImmutableList<String> executableArgs, ParamFileInfo paramFileInfo, Artifact parameterFile) { - return CustomCommandLine.builder() - .addAll(executableArgs) - // This is actually a constant, but there is no way to suppress the warning - .addWithDynamicPrefix(paramFileInfo.getFlag(), parameterFile) - .build(); - } - - /** - * Creates an action to write the parameter file. - * - * @param commandLine a {@link CommandLine} that provides the arguments (in addition to - * executableArgs) - * @param owner owner of the action - * @param parameterFile the output parameter file artifact - * @param paramFileInfo parameter file information - */ - public static ParameterFileWriteAction createParameterFileWriteAction( - CommandLine commandLine, - ActionOwner owner, - Artifact parameterFile, - ParamFileInfo paramFileInfo) { - return new ParameterFileWriteAction( - owner, parameterFile, commandLine, paramFileInfo.getFileType(), paramFileInfo.getCharset()); - } - - /** - * Creates a command line without using a params file. - * - * <p>Call this if {@link #getParamsFileMaybe} returns null. - * - * @param executableArgs leading arguments that should never be wrapped in a parameter file - * @param commandLine a {@link CommandLine} that provides the arguments (in addition to - * executableArgs) - */ - public static CommandLine createWithoutParamsFile( - List<String> executableArgs, CommandLine commandLine) { - if (executableArgs.isEmpty()) { - return commandLine; - } - return CommandLine.concat(ImmutableList.copyOf(executableArgs), commandLine); - } - - /** Estimates the params file size for the given arguments. */ - private static int getParamFileSize(List<String> executableArgs, CommandLine commandLine) { - try { - Iterable<String> actualArguments = commandLine.arguments(); - return getParamFileSize(executableArgs) + getParamFileSize(actualArguments); - } catch (CommandLineExpansionException e) { - // CommandLineExpansionException is thrown deterministically. We can ignore - // it here and pretend that a params file is not necessary at this stage, - // and an error will be thrown later at execution time. - return 0; - } - } - - private static int getParamFileSize(Iterable<String> args) { - int size = 0; - for (String s : args) { - size += s.length() + 1; - } - return size; - } -} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/ParamFileInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/ParamFileInfo.java index 32ec7a8506..33a9245c2b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/ParamFileInfo.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/ParamFileInfo.java @@ -14,6 +14,8 @@ package com.google.devtools.build.lib.analysis.actions; +import static java.nio.charset.StandardCharsets.ISO_8859_1; + import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; import com.google.devtools.build.lib.util.Preconditions; import com.google.errorprone.annotations.CompileTimeConstant; @@ -32,11 +34,7 @@ public final class ParamFileInfo { private final String flag; private final boolean always; - public ParamFileInfo( - ParameterFileType fileType, - Charset charset, - @CompileTimeConstant String flag, - boolean always) { + private ParamFileInfo(ParameterFileType fileType, Charset charset, String flag, boolean always) { this.fileType = Preconditions.checkNotNull(fileType); this.charset = Preconditions.checkNotNull(charset); this.flag = Preconditions.checkNotNull(flag); @@ -88,4 +86,42 @@ public final class ParamFileInfo { && flag.equals(other.flag) && always == other.always; } + + public static Builder builder(ParameterFileType parameterFileType) { + return new Builder(parameterFileType); + } + + /** Builder for a ParamFileInfo. */ + public static class Builder { + private final ParameterFileType fileType; + private Charset charset = ISO_8859_1; + private String flag = "@"; + private boolean always; + + private Builder(ParameterFileType fileType) { + this.fileType = fileType; + } + + /** Sets the encoding to write the parameter file with. */ + public Builder setCharset(Charset charset) { + this.charset = charset; + return this; + } + + /** Sets a prefix to use for the flag that is passed to original command. */ + public Builder setFlag(@CompileTimeConstant String flag) { + this.flag = flag; + return this; + } + + /** Set whether the parameter file is always used, regardless of parameter file length. */ + public Builder setUseAlways(boolean always) { + this.always = always; + return this; + } + + public ParamFileInfo build() { + return new ParamFileInfo(fileType, charset, flag, always); + } + } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java index 8f690a47a4..ac9aa7266a 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java @@ -14,8 +14,6 @@ package com.google.devtools.build.lib.analysis.actions; -import static java.nio.charset.StandardCharsets.ISO_8859_1; - import com.google.common.annotations.VisibleForTesting; import com.google.common.base.CharMatcher; import com.google.common.collect.ImmutableList; @@ -31,6 +29,7 @@ import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.ActionOwner; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; import com.google.devtools.build.lib.actions.BaseSpawn; import com.google.devtools.build.lib.actions.CommandAction; import com.google.devtools.build.lib.actions.CommandLineExpansionException; @@ -38,7 +37,7 @@ import com.google.devtools.build.lib.actions.CompositeRunfilesSupplier; import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier; import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.actions.ExecutionInfoSpecifier; -import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; +import com.google.devtools.build.lib.actions.ParameterFile; import com.google.devtools.build.lib.actions.ResourceSet; import com.google.devtools.build.lib.actions.RunfilesSupplier; import com.google.devtools.build.lib.actions.Spawn; @@ -62,7 +61,6 @@ import com.google.errorprone.annotations.CompileTimeConstant; import com.google.errorprone.annotations.FormatMethod; import com.google.errorprone.annotations.FormatString; import com.google.protobuf.GeneratedMessage.GeneratedExtension; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; @@ -521,6 +519,17 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie */ public static class Builder { + private static class CommandLineAndParamFileInfo { + private final CommandLine commandLine; + @Nullable private final ParamFileInfo paramFileInfo; + + private CommandLineAndParamFileInfo( + CommandLine commandLine, @Nullable ParamFileInfo paramFileInfo) { + this.commandLine = commandLine; + this.paramFileInfo = paramFileInfo; + } + } + private final NestedSetBuilder<Artifact> toolsBuilder = NestedSetBuilder.stableOrder(); private final NestedSetBuilder<Artifact> inputsBuilder = NestedSetBuilder.stableOrder(); private final List<Artifact> outputs = new ArrayList<>(); @@ -535,10 +544,9 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie private PathFragment executable; // executableArgs does not include the executable itself. private List<String> executableArgs; - @Nullable private CommandLine commandLine; + private List<CommandLineAndParamFileInfo> commandLines = new ArrayList<>(); private CharSequence progressMessage; - private ParamFileInfo paramFileInfo = null; private String mnemonic = "Unknown"; protected ExtraActionInfoSupplier<?> extraActionInfoSupplier = null; private boolean disableSandboxing = false; @@ -566,9 +574,8 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie this.executableArgs = (other.executableArgs != null) ? Lists.newArrayList(other.executableArgs) : null; - this.commandLine = other.commandLine; + this.commandLines = Lists.newArrayList(other.commandLines); this.progressMessage = other.progressMessage; - this.paramFileInfo = other.paramFileInfo; this.mnemonic = other.mnemonic; } @@ -598,37 +605,91 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie @VisibleForTesting @CheckReturnValue public Action[] build(ActionOwner owner, AnalysisEnvironment analysisEnvironment, BuildConfiguration configuration) { - CommandLine commandLine = this.commandLine != null ? this.commandLine : CommandLine.EMPTY; - // Check to see if we need to use param file. - Artifact paramsFile = ParamFileHelper.getParamsFileMaybe( - buildExecutableArgs(configuration.getShellExecutable()), - commandLine, - paramFileInfo, - configuration, - analysisEnvironment, - outputs); - - // If param file is to be used, set up the param file write action as well. - ParameterFileWriteAction paramFileWriteAction = null; - if (paramsFile != null) { - paramFileWriteAction = - ParamFileHelper.createParameterFileWriteAction( - commandLine, owner, paramsFile, paramFileInfo); + List<Action> paramFileActions = new ArrayList<>(commandLines.size()); + CommandLine actualCommandLine = + buildCommandLine(owner, analysisEnvironment, configuration, paramFileActions); + Action[] actions = new Action[1 + paramFileActions.size()]; + Action spawnAction = + buildSpawnAction(owner, actualCommandLine, configuration.getActionEnvironment()); + actions[0] = spawnAction; + for (int i = 0; i < paramFileActions.size(); ++i) { + actions[i + 1] = paramFileActions.get(i); } + return actions; + } - List<Action> actions = new ArrayList<>(2); - actions.add( - buildSpawnAction( - owner, - commandLine, - configuration.getActionEnvironment(), - configuration.getShellExecutable(), - paramsFile)); - if (paramFileWriteAction != null) { - actions.add(paramFileWriteAction); + private CommandLine buildCommandLine( + ActionOwner owner, + AnalysisEnvironment analysisEnvironment, + BuildConfiguration configuration, + List<Action> paramFileActions) { + ImmutableList<String> executableArgs = + buildExecutableArgs(configuration.getShellExecutable()); + boolean hasConditionalParamFile = + commandLines.stream().anyMatch(c -> c.paramFileInfo != null && !c.paramFileInfo.always()); + boolean spillToParamFiles = false; + if (hasConditionalParamFile) { + int totalLen = getParamFileSize(executableArgs); + for (CommandLineAndParamFileInfo commandLineAndParamFileInfo : commandLines) { + totalLen += getCommandLineSize(commandLineAndParamFileInfo.commandLine); + } + // To reduce implementation complexity we either spill all or none of the param files. + spillToParamFiles = totalLen > configuration.getMinParamFileSize(); } + // We a name based on the output, starting at <output>-2.params + // and then incrementing + int paramFileNameSuffix = 2; + SpawnActionCommandLine.Builder result = new SpawnActionCommandLine.Builder(); + result.addExecutableArguments(executableArgs); + for (CommandLineAndParamFileInfo commandLineAndParamFileInfo : commandLines) { + CommandLine commandLine = commandLineAndParamFileInfo.commandLine; + ParamFileInfo paramFileInfo = commandLineAndParamFileInfo.paramFileInfo; + boolean useParamsFile = + paramFileInfo != null && (paramFileInfo.always() || spillToParamFiles); + if (useParamsFile) { + Artifact output = Iterables.getFirst(outputs, null); + Preconditions.checkNotNull(output); + PathFragment paramFilePath = + ParameterFile.derivePath( + output.getRootRelativePath(), Integer.toString(paramFileNameSuffix)); + Artifact paramFile = + analysisEnvironment.getDerivedArtifact(paramFilePath, output.getRoot()); + inputsBuilder.add(paramFile); + ParameterFileWriteAction paramFileWriteAction = + new ParameterFileWriteAction( + owner, + paramFile, + commandLine, + paramFileInfo.getFileType(), + paramFileInfo.getCharset()); + paramFileActions.add(paramFileWriteAction); + ++paramFileNameSuffix; + result.addParamFile(paramFile, paramFileInfo); + } else { + result.addCommandLine(commandLine); + } + } + return result.build(); + } + + private static int getCommandLineSize(CommandLine commandLine) { + try { + Iterable<String> actualArguments = commandLine.arguments(); + return getParamFileSize(actualArguments); + } catch (CommandLineExpansionException e) { + // CommandLineExpansionException is thrown deterministically. We can ignore + // it here and pretend that a params file is not necessary at this stage, + // and an error will be thrown later at execution time. + return 0; + } + } - return actions.toArray(new Action[actions.size()]); + private static int getParamFileSize(Iterable<String> args) { + int size = 0; + for (String s : args) { + size += s.length() + 1; // Account for the space character + } + return size; } /** @@ -643,26 +704,11 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie * * @param owner the {@link ActionOwner} for the SpawnAction * @param configEnv the config's action environment to use. May be null if not used. - * @param defaultShellExecutable the default shell executable path. May be null if not used. - * @param paramsFile the parameter file for the SpawnAction. May be null if not used. * @return the SpawnAction and any actions required by it, with the first item always being the * SpawnAction itself. */ SpawnAction buildSpawnAction( - ActionOwner owner, - CommandLine commandLine, - @Nullable ActionEnvironment configEnv, - @Nullable PathFragment defaultShellExecutable, - @Nullable Artifact paramsFile) { - ImmutableList<String> argv = buildExecutableArgs(defaultShellExecutable); - CommandLine actualCommandLine; - if (paramsFile != null) { - inputsBuilder.add(paramsFile); - actualCommandLine = ParamFileHelper.createWithParamsFile(argv, paramFileInfo, paramsFile); - } else { - actualCommandLine = ParamFileHelper.createWithoutParamsFile(argv, commandLine); - } - + ActionOwner owner, CommandLine commandLine, @Nullable ActionEnvironment configEnv) { NestedSet<Artifact> tools = toolsBuilder.build(); // Tools are by definition a subset of the inputs, so make sure they're present there, too. @@ -692,7 +738,7 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie inputsAndTools, ImmutableList.copyOf(outputs), resourceSet, - actualCommandLine, + commandLine, isShellCommand, env, ImmutableMap.copyOf(executionInfo), @@ -702,6 +748,21 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie mnemonic); } + /** + * Builds the command line, forcing no params file. + * + * <p>This method is invoked by {@link SpawnActionTemplate} in the execution phase. + */ + CommandLine buildCommandLineWithoutParamsFiles() { + SpawnActionCommandLine.Builder result = new SpawnActionCommandLine.Builder(); + ImmutableList<String> executableArgs = buildExecutableArgs(null); + result.addExecutableArguments(executableArgs); + for (CommandLineAndParamFileInfo commandLineAndParamFileInfo : commandLines) { + result.addCommandLine(commandLineAndParamFileInfo.commandLine); + } + return result.build(); + } + /** Creates a SpawnAction. */ protected SpawnAction createSpawnAction( ActionOwner owner, @@ -1062,15 +1123,36 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie } /** - * Sets a delegate to compute the command line at a later time. + * Adds a delegate to compute the command line at a later time. + * + * <p>The arguments are added after the executable arguments. If you add multiple command lines, + * they are expanded in the corresponding order. + * + * <p>The main intention of this method is to save memory by allowing client-controlled sharing + * between actions and configured targets. Objects passed to this method MUST be immutable. + * + * <p>See also {@link CustomCommandLine}. + */ + public Builder addCommandLine(CommandLine commandLine) { + this.commandLines.add(new CommandLineAndParamFileInfo(commandLine, null)); + return this; + } + + /** + * Adds a delegate to compute the command line at a later time, optionally spilled to a params + * file. + * + * <p>The arguments are added after the executable arguments. If you add multiple command lines, + * they are expanded in the corresponding order. If the command line is spilled to a params + * file, it is replaced with an argument pointing to the param file. * * <p>The main intention of this method is to save memory by allowing client-controlled sharing * between actions and configured targets. Objects passed to this method MUST be immutable. * * <p>See also {@link CustomCommandLine}. */ - public Builder setCommandLine(CommandLine commandLine) { - this.commandLine = commandLine; + public Builder addCommandLine(CommandLine commandLine, @Nullable ParamFileInfo paramFileInfo) { + this.commandLines.add(new CommandLineAndParamFileInfo(commandLine, paramFileInfo)); return this; } @@ -1207,50 +1289,80 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie return this; } - /** - * Enable use of a parameter file and set the encoding to ISO-8859-1 (latin1). - * - * <p>In order to use parameter files, at least one output artifact must be specified. - */ - public Builder useParameterFile(ParameterFileType parameterFileType) { - return useParameterFile(parameterFileType, ISO_8859_1, "@"); + public Builder disableSandboxing() { + this.disableSandboxing = true; + return this; } + } - /** - * Force the use of a parameter file and set the encoding to ISO-8859-1 (latin1). - * - * <p>In order to use parameter files, at least one output artifact must be specified. - */ - public Builder alwaysUseParameterFile(ParameterFileType parameterFileType) { - return useParameterFile(parameterFileType, ISO_8859_1, "@", /*always=*/ true); + /** + * Command line implementation that optimises for containing executable args, command lines, and + * command lines spilled to param files. + */ + private static class SpawnActionCommandLine extends CommandLine { + private final Object[] values; + + SpawnActionCommandLine(Object[] values) { + this.values = values; } - /** - * Enable or disable the use of a parameter file, set the encoding to the given value, and - * specify the argument prefix to use in passing the parameter file name to the tool. - * - * <p>The default argument prefix is "@". In order to use parameter files, at least one output - * artifact must be specified. - */ - public Builder useParameterFile( - ParameterFileType parameterFileType, - Charset charset, - @CompileTimeConstant String flagPrefix) { - return useParameterFile(parameterFileType, charset, flagPrefix, /*always=*/ false); - } - - private Builder useParameterFile( - ParameterFileType parameterFileType, - Charset charset, - @CompileTimeConstant String flagPrefix, - boolean always) { - paramFileInfo = new ParamFileInfo(parameterFileType, charset, flagPrefix, always); - return this; + @Override + public Iterable<String> arguments() throws CommandLineExpansionException { + return expandArguments(null); } - public Builder disableSandboxing() { - this.disableSandboxing = true; - return this; + @Override + public Iterable<String> arguments(ArtifactExpander artifactExpander) + throws CommandLineExpansionException { + return expandArguments(artifactExpander); + } + + private Iterable<String> expandArguments(@Nullable ArtifactExpander artifactExpander) + throws CommandLineExpansionException { + ImmutableList.Builder<String> result = ImmutableList.builder(); + int count = values.length; + for (int i = 0; i < count; ++i) { + Object value = values[i]; + if (value instanceof String) { + result.add((String) value); + } else if (value instanceof Artifact) { + Artifact paramFile = (Artifact) value; + String flag = (String) values[++i]; + result.add(flag + paramFile.getExecPathString()); + } else if (value instanceof CommandLine) { + CommandLine commandLine = (CommandLine) value; + if (artifactExpander != null) { + result.addAll(commandLine.arguments(artifactExpander)); + } else { + result.addAll(commandLine.arguments()); + } + } + } + return result.build(); + } + + private static class Builder { + private List<Object> values = new ArrayList<>(); + + Builder addExecutableArguments(ImmutableList<String> executableArguments) { + values.addAll(executableArguments); + return this; + } + + Builder addParamFile(Artifact paramFile, ParamFileInfo paramFileInfo) { + values.add(paramFile); + values.add(paramFileInfo.getFlag()); + return this; + } + + Builder addCommandLine(CommandLine commandLine) { + values.add(commandLine); + return this; + } + + SpawnActionCommandLine build() { + return new SpawnActionCommandLine(values.toArray()); + } } } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java index db40f23f51..0b35944581 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplate.java @@ -121,17 +121,13 @@ public final class SpawnActionTemplate implements ActionTemplate<SpawnAction> { CommandLine commandLine = commandLineTemplate.evaluateTreeFileArtifacts( ImmutableList.of(inputTreeFileArtifact, outputTreeFileArtifact)); - actionBuilder.setCommandLine(commandLine); + actionBuilder.addCommandLine(commandLine); // Note that we pass in nulls below because SpawnActionTemplate does not support param file, and // it does not use any default value for executable or shell environment. They must be set // explicitly via builder method #setExecutable and #setEnvironment. return actionBuilder.buildSpawnAction( - getOwner(), - commandLine, - /*configEnv=*/ null, - /*defaultShellExecutable=*/ null, - /*paramsFile=*/ null); + getOwner(), actionBuilder.buildCommandLineWithoutParamsFiles(), /*configEnv=*/ null); } /** @@ -206,7 +202,7 @@ public final class SpawnActionTemplate implements ActionTemplate<SpawnAction> { @Override public Iterable<String> getClientEnvironmentVariables() { return spawnActionBuilder - .buildSpawnAction(getOwner(), CommandLine.of(ImmutableList.of()), null, null, null) + .buildSpawnAction(getOwner(), CommandLine.of(ImmutableList.of()), null) .getClientEnvironmentVariables(); } 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 8b134bb86b..be6d6348cd 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 @@ -382,10 +382,10 @@ public class SkylarkActionFactory implements SkylarkValue { SkylarkList skylarkList = ((SkylarkList) arguments); @SuppressWarnings("unchecked") List<String> argumentsContents = skylarkList.getContents(String.class, "arguments"); - builder.setCommandLine(CustomCommandLine.builder().addAll(argumentsContents).build()); + builder.addCommandLine(CustomCommandLine.builder().addAll(argumentsContents).build()); } else { Args args = (Args) arguments; - builder.setCommandLine(args.build()); + builder.addCommandLine(args.build()); } if (executableUnchecked instanceof Artifact) { Artifact executable = (Artifact) executableUnchecked; @@ -564,10 +564,10 @@ public class SkylarkActionFactory implements SkylarkValue { @SuppressWarnings("unchecked") List<String> argumentsContents = argumentList.getContents(String.class, "arguments"); commandLine.addAll(argumentsContents); - builder.setCommandLine(commandLine.build()); + builder.addCommandLine(commandLine.build()); } else { Args args = (Args) arguments; - builder.setCommandLine(CommandLine.concat(ImmutableList.of(""), args.build())); + builder.addCommandLine(CommandLine.concat(ImmutableList.of(""), args.build())); } if (commandUnchecked instanceof String) { |