diff options
51 files changed, 539 insertions, 509 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) { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java index 1aed86d599..08cfb612e8 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java @@ -317,7 +317,7 @@ public class BazelPythonSemantics implements PythonSemantics { .addOutput(zipFile) .setExecutable(zipper) .useDefaultShellEnvironment() - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("cC") .addExecPath(zipFile) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java index c4c194bcb7..c3c6365152 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarGeneratorBuilder.java @@ -25,6 +25,7 @@ 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.ActionConstructionContext; import com.google.devtools.build.lib.analysis.actions.CommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.rules.android.ResourceContainer.ResourceType; import com.google.devtools.build.lib.util.OS; @@ -127,6 +128,7 @@ public class AarGeneratorBuilder { args.add("--throwOnResourceConflict"); } + ParamFileInfo paramFileInfo = null; if (OS.getCurrent() == OS.WINDOWS) { // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting @@ -136,7 +138,7 @@ public class AarGeneratorBuilder { // list-type and list-of-list-type flags that use such problematic separators in favor of // multi-value flags (to remove one level of listing) and by changing all list separators to a // platform-safe character (= comma). - builder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); + paramFileInfo = ParamFileInfo.builder(ParameterFileType.UNQUOTED).setUseAlways(true).build(); } ruleContext.registerAction( @@ -144,7 +146,7 @@ public class AarGeneratorBuilder { .useDefaultShellEnvironment() .addInputs(ImmutableList.<Artifact>copyOf(ins)) .addOutputs(ImmutableList.<Artifact>copyOf(outs)) - .setCommandLine(CommandLine.of(args)) + .addCommandLine(CommandLine.of(args), paramFileInfo) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Building AAR package for %s", ruleContext.getLabel()) 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 e3d5a12733..389abc0e91 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 @@ -182,7 +182,7 @@ public class AarImport implements RuleConfiguredTargetFactory { .setProgressMessage("Extracting %s from %s", filename, aar.getFilename()) .addInput(aar) .addOutput(outputArtifact) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("x", aar) .addPath("-d", outputArtifact.getExecPath().getParentDirectory()) @@ -201,7 +201,7 @@ public class AarImport implements RuleConfiguredTargetFactory { .setMnemonic("AarResourcesExtractor") .addInput(aar) .addOutput(outputTree) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--input_aar", aar) .addExecPath("--output_res_dir", outputTree) @@ -221,7 +221,7 @@ public class AarImport implements RuleConfiguredTargetFactory { .addInput(aar) .addOutput(jarsTreeArtifact) .addOutput(singleJarParamFile) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--input_aar", aar) .addExecPath("--output_dir", jarsTreeArtifact) @@ -238,7 +238,7 @@ public class AarImport implements RuleConfiguredTargetFactory { .addInput(jarsTreeArtifact) .addOutput(mergedJar) .addInput(paramFile) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--output", mergedJar) .add("--dont_change_compression") @@ -259,7 +259,7 @@ public class AarImport implements RuleConfiguredTargetFactory { .setProgressMessage("Filtering AAR native libs by architecture") .addInput(aar) .addOutput(outputZip) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--input_aar", aar) .add("--cpu", ruleContext.getConfiguration().getCpu()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java index 3a5d8d35ce..310c7f655b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java @@ -21,6 +21,7 @@ import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; 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.ParamFileInfo; 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.CompilationMode; @@ -108,8 +109,8 @@ public final class AndroidAaptActionHelper { .setExecutable( ruleContext.getExecutablePrerequisite("$android_aapt_java_generator", Mode.HOST)) .addOutput(javaSourcesJar) - .setCommandLine(CommandLine.of(args)) - .useParameterFile(ParameterFileType.UNQUOTED) + .addCommandLine( + CommandLine.of(args), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setProgressMessage("Generating Java resources") .setMnemonic("AaptJavaGenerator"); if (rTxt != null) { @@ -149,8 +150,8 @@ public final class AndroidAaptActionHelper { .addOutput(apk) .setExecutable( ruleContext.getExecutablePrerequisite("$android_aapt_apk_generator", Mode.HOST)) - .setCommandLine(CommandLine.of(args)) - .useParameterFile(ParameterFileType.UNQUOTED) + .addCommandLine( + CommandLine.of(args), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setProgressMessage("Generating apk resources") .setMnemonic("AaptResourceApk") .build(ruleContext)); @@ -277,8 +278,9 @@ public final class AndroidAaptActionHelper { .addOutputs(outputs.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_aapt_apk_generator", Mode.HOST)) - .setCommandLine(CommandLine.of(aaptCommand)) - .useParameterFile(ParameterFileType.UNQUOTED) + .addCommandLine( + CommandLine.of(aaptCommand), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setProgressMessage("Generating Proguard configuration for resources") .setMnemonic("AaptProguardConfiguration") .build(ruleContext)); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java index c45aeecc7e..067a45a1dd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java @@ -529,7 +529,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { || getMultidexMode(ruleContext) == MultidexMode.LEGACY) { commandLine.add("--keep-main-dex"); } - rexActionBuilder.setCommandLine(commandLine.build()); + rexActionBuilder.addCommandLine(commandLine.build()); ruleContext.registerAction(rexActionBuilder.build(ruleContext)); } else { finalDexes = dexingOutput.classesDexZip; @@ -1036,7 +1036,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { .setExecutable(ruleContext.getExecutablePrerequisite("$merge_dexzips", Mode.HOST)) .addInputs(shardDexes) .addOutput(classesDex) - .setCommandLine(mergeCommandLine) + .addCommandLine(mergeCommandLine) .build(ruleContext)); if (incrementalDexing.contains(AndroidBinaryType.MULTIDEX_SHARDED)) { // Using the deploy jar for java resources gives better "bazel mobile-install" performance @@ -1140,7 +1140,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { dexmerger.addInput(mainDexList); commandLine.addExecPath("--main-dex-list", mainDexList); } - dexmerger.setCommandLine(commandLine.build()); + dexmerger.addCommandLine(commandLine.build()); ruleContext.registerAction(dexmerger.build(ruleContext)); } @@ -1320,7 +1320,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { } } - shardAction.setCommandLine(shardCommandLine.build()); + shardAction.addCommandLine(shardCommandLine.build()); ruleContext.registerAction(shardAction.build(ruleContext)); return javaResourceJar; } @@ -1354,7 +1354,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { .setMnemonic("TrimDexZip") .addInput(inputZip) .addOutput(outputZip) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("--exclude_build_data") .add("--dont_change_compression") @@ -1420,7 +1420,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { androidSemantics.addMainDexListActionArguments( ruleContext, streamlinedBuilder, streamlinedCommandLine, proguardOutputMap); - streamlinedBuilder.setCommandLine(streamlinedCommandLine.build()); + streamlinedBuilder.addCommandLine(streamlinedCommandLine.build()); ruleContext.registerAction(streamlinedBuilder.build(ruleContext)); // Create the main dex classes list. @@ -1435,7 +1435,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { .addOutput(mainDexList) .addInput(strippedJar) .addInput(jar) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath(mainDexList) .addExecPath(strippedJar) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java index b99940c493..7d3f5001d2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java @@ -28,6 +28,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -160,12 +161,12 @@ public final class AndroidBinaryMobileInstall { ruleContext.getExecutablePrerequisite("$build_incremental_dexmanifest", Mode.HOST)) .addOutput(incrementalDexManifest) .addInputs(dexingOutput.shardDexZips) - .useParameterFile(ParameterFileType.UNQUOTED) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath(incrementalDexManifest) .addExecPaths(dexingOutput.shardDexZips) - .build()) + .build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .build(ruleContext)); Artifact stubData = ruleContext.getImplicitOutputArtifact( @@ -277,7 +278,7 @@ public final class AndroidBinaryMobileInstall { .setExecutable(ruleContext.getExecutablePrerequisite("$strip_resources", Mode.HOST)) .addInput(resourceApk.getArtifact()) .addOutput(splitMainApkResources) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--input_resource_apk", resourceApk.getArtifact()) .addExecPath("--output_resource_apk", splitMainApkResources) @@ -450,7 +451,7 @@ public final class AndroidBinaryMobileInstall { } } - builder.setCommandLine(commandLine.build()); + builder.addCommandLine(commandLine.build()); ruleContext.registerAction(builder.build(ruleContext)); } @@ -485,7 +486,7 @@ public final class AndroidBinaryMobileInstall { commandLine.addExecPath("--split_apk", splitApk); } - builder.setCommandLine(commandLine.build()); + builder.addCommandLine(commandLine.build()); ruleContext.registerAction(builder.build(ruleContext)); } @@ -504,7 +505,7 @@ public final class AndroidBinaryMobileInstall { .addOutput(splitResources) .addInput(splitManifest) .addInput(sdk.getAndroidJar()) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("package") .addExecPath("-F", splitResources) 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 d590dd635c..7a116e0815 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 @@ -230,7 +230,7 @@ public class AndroidCommon { .addOutput(classesDex) .setProgressMessage("Converting %s to dex format", jarToDex.getExecPathString()) .setMnemonic("AndroidDexer") - .setCommandLine(commandLine.build()) + .addCommandLine(commandLine.build()) .setResources(ResourceSet.createWithRamCpuIo(4096.0, 5.0, 0.0)); if (mainDexList != null) { builder.addInput(mainDexList); @@ -508,7 +508,7 @@ public class AndroidCommon { .addInput(jarJarRuleFile) .addInput(binaryResourcesJar) .addOutput(resourcesJar) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("process") .addExecPath(jarJarRuleFile) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java index 22952e03b6..7eec313f4a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDevice.java @@ -337,7 +337,7 @@ public class AndroidDevice implements RuleConfiguredTargetFactory { spawnBuilder.addInput(defaultProperties.get()); commandLine.addPrefixedExecPath("--default_properties_file=", defaultProperties.get()); } - spawnBuilder.setCommandLine(commandLine.build()); + spawnBuilder.addCommandLine(commandLine.build()); ruleContext.registerAction(spawnBuilder.build(ruleContext)); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java index 2524c03f59..4d556025d6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java @@ -22,6 +22,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -333,7 +334,7 @@ public class AndroidIdlHelper { .addOutput(idlClassJar) .addOutput(idlSourceJar) .setExecutable(ruleContext.getExecutablePrerequisite("$idlclass", Mode.HOST)) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--manifest_proto", manifestProtoOutput) .addExecPath("--class_jar", classJar) @@ -342,8 +343,8 @@ public class AndroidIdlHelper { .add("--temp_dir") .addPath(idlTempDir) .addExecPaths(ImmutableList.copyOf(generatedIdlJavaFiles)) - .build()) - .useParameterFile(ParameterFileType.SHELL_QUOTED) + .build(), + ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build()) .setProgressMessage("Building idl jars %s", idlClassJar.prettyPrint()) .setMnemonic("AndroidIdlJars") .build(ruleContext)); @@ -372,7 +373,7 @@ public class AndroidIdlHelper { .addOutput(output) .setProgressMessage("Android IDL generation") .setMnemonic("AndroidIDLGenerate") - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("-b") // Fail if trying to compile a parcelable. .addAll(importArgs) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java index 29b96b66c4..039b91a88a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java @@ -47,7 +47,7 @@ public final class AndroidManifestMergeHelper { .setExecutable(ruleContext.getPrerequisite("$android_manifest_merge_tool", Mode.HOST)) .setProgressMessage("Merging Android Manifests") .setMnemonic("AndroidManifestMerger") - .setCommandLine(commandLine.build()) + .addCommandLine(commandLine.build()) .build(ruleContext)); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java index 0d39a8696d..fe0b68f22e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java @@ -22,6 +22,7 @@ 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.ActionConstructionContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.android.ResourceContainerConverter.Builder.SeparatorType; @@ -182,20 +183,16 @@ public class AndroidResourceMergingActionBuilder { } SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); - - if (OS.getCurrent() == OS.WINDOWS) { - // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special - // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting - // semantics are very complicated (more so than in Bash), so let's just always use a parameter - // file. - // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating - // list-type and list-of-list-type flags that use such problematic separators in favor of - // multi-value flags (to remove one level of listing) and by changing all list separators to a - // platform-safe character (= comma). - spawnActionBuilder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); - } else { - spawnActionBuilder.useParameterFile(ParameterFileType.UNQUOTED); - } + ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.UNQUOTED); + // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special + // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting + // semantics are very complicated (more so than in Bash), so let's just always use a parameter + // file. + // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating + // list-type and list-of-list-type flags that use such problematic separators in favor of + // multi-value flags (to remove one level of listing) and by changing all list separators to a + // platform-safe character (= comma). + paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS); // Create the spawn action. ruleContext.registerAction( @@ -203,7 +200,7 @@ public class AndroidResourceMergingActionBuilder { .useDefaultShellEnvironment() .addTransitiveInputs(inputs.build()) .addOutputs(ImmutableList.copyOf(outs)) - .setCommandLine(builder.build()) + .addCommandLine(builder.build(), paramFileInfo.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Merging Android resources for %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java index 6a0f7a6061..bd10d0b449 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java @@ -26,6 +26,7 @@ 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.ActionConstructionContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -145,19 +146,16 @@ public class AndroidResourceParsingActionBuilder { builder.addExecPath("--output", output); SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); - if (OS.getCurrent() == OS.WINDOWS) { - // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special - // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting - // semantics are very complicated (more so than in Bash), so let's just always use a parameter - // file. - // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating - // list-type and list-of-list-type flags that use such problematic separators in favor of - // multi-value flags (to remove one level of listing) and by changing all list separators to a - // platform-safe character (= comma). - spawnActionBuilder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); - } else { - spawnActionBuilder.useParameterFile(ParameterFileType.UNQUOTED); - } + ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.UNQUOTED); + // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special + // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting + // semantics are very complicated (more so than in Bash), so let's just always use a parameter + // file. + // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating + // list-type and list-of-list-type flags that use such problematic separators in favor of + // multi-value flags (to remove one level of listing) and by changing all list separators to a + // platform-safe character (= comma). + paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS); // Create the spawn action. ruleContext.registerAction( @@ -165,7 +163,7 @@ public class AndroidResourceParsingActionBuilder { .useDefaultShellEnvironment() .addTransitiveInputs(inputs.build()) .addOutputs(ImmutableList.of(output)) - .setCommandLine(builder.build()) + .addCommandLine(builder.build(), paramFileInfo.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Parsing Android resources for %s", ruleContext.getLabel()) @@ -198,11 +196,12 @@ public class AndroidResourceParsingActionBuilder { // Create the spawn action. ruleContext.registerAction( new SpawnAction.Builder() - .useParameterFile(ParameterFileType.UNQUOTED) .useDefaultShellEnvironment() .addTransitiveInputs(inputs.build()) .addOutputs(ImmutableList.copyOf(outs)) - .setCommandLine(flatFileBuilder.build()) + .addCommandLine( + flatFileBuilder.build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Compiling Android resources for %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java index 50cfa8acb3..ac051ea20c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import java.util.ArrayList; import java.util.List; @@ -193,12 +194,12 @@ public class AndroidResourceValidatorActionBuilder { ruleContext.registerAction( new SpawnAction.Builder() - .useParameterFile(ParameterFileType.UNQUOTED) .useDefaultShellEnvironment() .addTool(sdk.getAapt2()) .addInputs(inputs.build()) .addOutputs(outs.build()) - .setCommandLine(builder.build()) + .addCommandLine( + builder.build(), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage( @@ -269,12 +270,12 @@ public class AndroidResourceValidatorActionBuilder { // Create the spawn action. ruleContext.registerAction( spawnActionBuilder - .useParameterFile(ParameterFileType.UNQUOTED) .useDefaultShellEnvironment() .addTool(sdk.getAapt()) .addInputs(inputs.build()) .addOutputs(ImmutableList.copyOf(outs)) - .setCommandLine(builder.build()) + .addCommandLine( + builder.build(), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Validating Android resources for %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java index 6fd04a2088..57f9a4ff57 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.Builder; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; @@ -278,19 +279,16 @@ public class AndroidResourcesProcessorBuilder { configureCommonFlags(outs, inputs, builder); - if (OS.getCurrent() == OS.WINDOWS) { - // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special - // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting - // semantics are very complicated (more so than in Bash), so let's just always use a parameter - // file. - // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating - // list-type and list-of-list-type flags that use such problematic separators in favor of - // multi-value flags (to remove one level of listing) and by changing all list separators to a - // platform-safe character (= comma). - this.spawnActionBuilder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); - } else { - this.spawnActionBuilder.useParameterFile(ParameterFileType.UNQUOTED); - } + ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.UNQUOTED); + // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special + // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting + // semantics are very complicated (more so than in Bash), so let's just always use a parameter + // file. + // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating + // list-type and list-of-list-type flags that use such problematic separators in favor of + // multi-value flags (to remove one level of listing) and by changing all list separators to a + // platform-safe character (= comma). + paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS); // Create the spawn action. ruleContext.registerAction( @@ -300,7 +298,7 @@ public class AndroidResourcesProcessorBuilder { .addTool(sdk.getAapt2()) .addTransitiveInputs(inputs.build()) .addOutputs(ImmutableList.<Artifact>copyOf(outs)) - .setCommandLine(builder.build()) + .addCommandLine(builder.build(), paramFileInfo.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Processing Android resources for %s", ruleContext.getLabel()) @@ -344,19 +342,16 @@ public class AndroidResourcesProcessorBuilder { builder.addExecPath("--aapt", sdk.getAapt().getExecutable()); configureCommonFlags(outs, inputs, builder); - if (OS.getCurrent() == OS.WINDOWS) { - // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special - // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting - // semantics are very complicated (more so than in Bash), so let's just always use a parameter - // file. - // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating - // list-type and list-of-list-type flags that use such problematic separators in favor of - // multi-value flags (to remove one level of listing) and by changing all list separators to a - // platform-safe character (= comma). - this.spawnActionBuilder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); - } else { - this.spawnActionBuilder.useParameterFile(ParameterFileType.UNQUOTED); - } + ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.UNQUOTED); + // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special + // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting + // semantics are very complicated (more so than in Bash), so let's just always use a parameter + // file. + // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating + // list-type and list-of-list-type flags that use such problematic separators in favor of + // multi-value flags (to remove one level of listing) and by changing all list separators to a + // platform-safe character (= comma). + paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS); // Create the spawn action. ruleContext.registerAction( @@ -366,7 +361,7 @@ public class AndroidResourcesProcessorBuilder { .addTool(sdk.getAapt()) .addTransitiveInputs(inputs.build()) .addOutputs(ImmutableList.copyOf(outs)) - .setCommandLine(builder.build()) + .addCommandLine(builder.build(), paramFileInfo.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Processing Android resources for %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApkActionsBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApkActionsBuilder.java index bd1f60e25a..c7abbb81f6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ApkActionsBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApkActionsBuilder.java @@ -229,7 +229,7 @@ public class ApkActionsBuilder { commandLine.addExecPath(classesDex); } - actionBuilder.setCommandLine(commandLine.build()); + actionBuilder.addCommandLine(commandLine.build()); ruleContext.registerAction(actionBuilder.build(ruleContext)); } @@ -303,7 +303,7 @@ public class ApkActionsBuilder { .setProgressMessage("Extracting Java resources from deploy jar for %s", apkName) .addInput(javaResourceZip) .addOutput(extractedJavaResourceZip) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath(javaResourceZip) .addExecPath(extractedJavaResourceZip) @@ -338,9 +338,9 @@ public class ApkActionsBuilder { singleJarCommandLine.addAll("--nocompress_suffixes", noCompressExtensions); } - compressedApkActionBuilder.setCommandLine(compressedApkCommandLine.build()); + compressedApkActionBuilder.addCommandLine(compressedApkCommandLine.build()); ruleContext.registerAction(compressedApkActionBuilder.build(ruleContext)); - singleJarActionBuilder.setCommandLine(singleJarCommandLine.build()); + singleJarActionBuilder.addCommandLine(singleJarCommandLine.build()); ruleContext.registerAction(singleJarActionBuilder.build(ruleContext)); } @@ -355,7 +355,7 @@ public class ApkActionsBuilder { .setMnemonic("AndroidZipAlign") .addInput(inputApk) .addOutput(zipAlignedApk) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("-p") // memory page aligment for stored shared object files .add("4") @@ -382,7 +382,7 @@ public class ApkActionsBuilder { .addInput(signingKey) .addOutput(signedAndZipalignedApk) .addInput(unsignedApk) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("sign") .add("--ks") diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java index 91579b6f0e..97028a01d4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java @@ -89,7 +89,7 @@ public final class ApplicationManifest { commandLine.add("--override_package", overridePackage); } - builder.setCommandLine(commandLine.build()); + builder.addCommandLine(commandLine.build()); ruleContext.registerAction(builder.build(ruleContext)); return new ApplicationManifest(ruleContext, result, targetAaptVersion); } @@ -123,7 +123,7 @@ public final class ApplicationManifest { commandLine.add("--override_package", overridePackage); } - builder.setCommandLine(commandLine.build()); + builder.addCommandLine(commandLine.build()); ruleContext.registerAction(builder.build(ruleContext)); return new ApplicationManifest(ruleContext, stubManifest, targetAaptVersion); @@ -142,7 +142,7 @@ public final class ApplicationManifest { .setMnemonic("InjectInstantRunStubApplication") .addInput(manifest) .addOutput(stubManifest) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("--mode=instant_run") .addExecPath("--input_manifest", manifest) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java b/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java index bf5491f132..b3db32e1ac 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java @@ -401,7 +401,7 @@ public final class DexArchiveAspect extends NativeAspectClass implements Configu .addOutput(result) .setMnemonic("Desugar") .setProgressMessage("Desugaring %s for Android", jar.prettyPrint()) - .setCommandLine(CustomCommandLine.builder().addPrefixedExecPath("@", paramFile).build()) + .addCommandLine(CustomCommandLine.builder().addPrefixedExecPath("@", paramFile).build()) .build(ruleContext)); return result; } @@ -453,7 +453,7 @@ public final class DexArchiveAspect extends NativeAspectClass implements Configu .setMnemonic("DexBuilder") .setProgressMessage( "Dexing %s with applicable dexopts %s", jar.prettyPrint(), incrementalDexopts) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder().addPrefixedExecPath("@", paramFile).build()); if (getAndroidConfig(ruleContext).useWorkersWithDexbuilder()) { dexbuilder.setExecutionInfo(ExecutionRequirements.WORKER_MODE_ENABLED); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java index 185953c5c1..b0e9e66bee 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.analysis.FilesToRunProvider; 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.CustomCommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; @@ -89,11 +90,11 @@ public class LibraryRGeneratorActionBuilder { SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); ruleContext.registerAction( spawnActionBuilder - .useParameterFile(ParameterFileType.UNQUOTED) .useDefaultShellEnvironment() .addTransitiveInputs(inputs.build()) .addOutputs(ImmutableList.<Artifact>of(rJavaClassJar)) - .setCommandLine(builder.build()) + .addCommandLine( + builder.build(), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setExecutable(executable) .setProgressMessage("Generating Library R Classes: %s", ruleContext.getLabel()) .setMnemonic("LibraryRClassGenerator") diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java index 1203a2faab..91ee23e75b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ManifestMergerActionBuilder.java @@ -23,6 +23,7 @@ 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.ActionConstructionContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -131,26 +132,23 @@ public class ManifestMergerActionBuilder { outputs.add(logOut); } - if (OS.getCurrent() == OS.WINDOWS) { - // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special - // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting - // semantics are very complicated (more so than in Bash), so let's just always use a parameter - // file. - // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating - // list-type and list-of-list-type flags that use such problematic separators in favor of - // multi-value flags (to remove one level of listing) and by changing all list separators to a - // platform-safe character (= comma). - spawnActionBuilder.alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED); - } else { - spawnActionBuilder.useParameterFile(ParameterFileType.SHELL_QUOTED); - } + ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED); + // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special + // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting + // semantics are very complicated (more so than in Bash), so let's just always use a parameter + // file. + // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating + // list-type and list-of-list-type flags that use such problematic separators in favor of + // multi-value flags (to remove one level of listing) and by changing all list separators to a + // platform-safe character (= comma). + paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS); ruleContext.registerAction( this.spawnActionBuilder .useDefaultShellEnvironment() .addTransitiveInputs(inputs.build()) .addOutputs(outputs.build()) - .setCommandLine(builder.build()) + .addCommandLine(builder.build(), paramFileInfo.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Merging manifest for %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java index 137bd653cb..dd79c8fbb7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java @@ -24,12 +24,12 @@ 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.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; 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.rules.android.AndroidConfiguration.AndroidAaptVersion; -import com.google.devtools.build.lib.util.OS; import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; @@ -121,27 +121,13 @@ public class RClassGeneratorActionBuilder { // Create the spawn action. SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); - if (OS.getCurrent() == OS.WINDOWS) { - // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special - // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting - // semantics are very complicated (more so than in Bash), so let's just always use a parameter - // file. - // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating - // list-type and list-of-list-type flags that use such problematic separators in favor of - // multi-value flags (to remove one level of listing) and by changing all list separators to a - // platform-safe character (= comma). - spawnActionBuilder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); - } else { - spawnActionBuilder.useParameterFile(ParameterFileType.SHELL_QUOTED); - } - ruleContext.registerAction( spawnActionBuilder - .useParameterFile(ParameterFileType.SHELL_QUOTED) .useDefaultShellEnvironment() .addTransitiveInputs(inputs.build()) .addOutputs(ImmutableList.<Artifact>copyOf(outs)) - .setCommandLine(builder.build()) + .addCommandLine( + builder.build(), ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Generating R Classes: %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java index 4bae0bc02c..7434e3429a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java @@ -239,7 +239,7 @@ public class ResourceShrinkerActionBuilder { .addTool(aapt) .addInputs(inputs.build()) .addOutputs(outputs.build()) - .setCommandLine(commandLine.build()) + .addCommandLine(commandLine.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Shrinking resources for %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java index e752d82108..1eaa346cf3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java @@ -20,6 +20,7 @@ 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.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -92,26 +93,23 @@ public class RobolectricResourceSymbolsActionBuilder { builder.addExecPath("--classJarOutput", classJarOut); SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); - if (OS.getCurrent() == OS.WINDOWS) { - // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special - // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting - // semantics are very complicated (more so than in Bash), so let's just always use a parameter - // file. - // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating - // list-type and list-of-list-type flags that use such problematic separators in favor of - // multi-value flags (to remove one level of listing) and by changing all list separators to a - // platform-safe character (= comma). - spawnActionBuilder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); - } else { - spawnActionBuilder.useParameterFile(ParameterFileType.UNQUOTED); - } + ParamFileInfo.Builder paramFile = ParamFileInfo.builder(ParameterFileType.UNQUOTED); + // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special + // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting + // semantics are very complicated (more so than in Bash), so let's just always use a parameter + // file. + // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating + // list-type and list-of-list-type flags that use such problematic separators in favor of + // multi-value flags (to remove one level of listing) and by changing all list separators to a + // platform-safe character (= comma). + paramFile.setUseAlways(OS.getCurrent() == OS.WINDOWS); ruleContext.registerAction( spawnActionBuilder .useDefaultShellEnvironment() .addTransitiveInputs(inputs.build()) .addOutput(classJarOut) - .setCommandLine(builder.build()) + .addCommandLine(builder.build(), paramFile.build()) .setExecutable( ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) .setProgressMessage("Generating R classes for %s", ruleContext.getLabel()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java index 8c91d6be80..97b1742631 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java @@ -22,7 +22,7 @@ import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ExecutionRequirements; -import com.google.devtools.build.lib.actions.ParameterFile; +import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.OutputGroupProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; @@ -35,6 +35,7 @@ import com.google.devtools.build.lib.analysis.RunfilesSupport; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.FileWriteAction; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.test.ExecutionInfo; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; @@ -627,7 +628,8 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory { CustomCommandLine.Builder commandLine = CustomCommandLine.builder(); Action[] build(RuleContext context) { - spawnAction.setCommandLine(commandLine.build()); + spawnAction.addCommandLine( + commandLine.build(), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()); return spawnAction.build(context); } } @@ -696,8 +698,7 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory { packager .spawnAction .addTransitiveInputs(dwpTools) - .setExecutable(cppConfiguration.getDwpExecutable()) - .useParameterFile(ParameterFile.ParameterFileType.UNQUOTED); + .setExecutable(cppConfiguration.getDwpExecutable()); return packager; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java index 7acc41f935..48afc4455f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java @@ -154,7 +154,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory { .setProgressMessage( "LLVMUnzipProfileAction: Generating %s", rawProfileArtifact.prettyPrint()) .setMnemonic("LLVMUnzipProfileAction") - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("xf", zipProfileArtifact) .add( @@ -192,7 +192,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory { .setExecutable(cppConfiguration.getLLVMProfDataExecutable()) .setProgressMessage("LLVMProfDataAction: Generating %s", profileArtifact.prettyPrint()) .setMnemonic("LLVMProfDataAction") - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("merge") .add("-o") diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java index 5273d32226..da85efa79e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java @@ -664,7 +664,7 @@ public class CppHelper { .setExecutionInfo(executionInfoBuilder.build()) .setProgressMessage("Stripping %s for %s", output.prettyPrint(), context.getLabel()) .setMnemonic("CcStrip") - .setCommandLine(CustomCommandLine.builder().addAll(commandLine).build()) + .addCommandLine(CustomCommandLine.builder().addAll(commandLine).build()) .build(context); context.registerAction(stripAction); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java index c7ff2908a9..cce33c4209 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java @@ -28,6 +28,7 @@ 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.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.IterablesChain; import com.google.devtools.build.lib.util.Preconditions; @@ -278,8 +279,9 @@ public class DeployArchiveBuilder { .addOutput(outputJar) .setResources(resourceSet) .setJarExecutable(JavaCommon.getHostJavaExecutable(ruleContext), singlejar, jvmArgs) - .setCommandLine(commandLine) - .alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED) + .addCommandLine( + commandLine, + ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).setUseAlways(true).build()) .setProgressMessage("Building deploy jar %s", outputJar.prettyPrint()) .setMnemonic("JavaDeployJar") .setExecutionInfo(ExecutionRequirements.WORKER_MODE_ENABLED) @@ -291,8 +293,9 @@ public class DeployArchiveBuilder { .addOutput(outputJar) .setResources(resourceSet) .setExecutable(singlejar) - .setCommandLine(commandLine) - .alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED) + .addCommandLine( + commandLine, + ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).setUseAlways(true).build()) .setProgressMessage("Building deploy jar %s", outputJar.prettyPrint()) .setMnemonic("JavaDeployJar") .build(ruleContext)); 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 90a81bdc00..4605b94724 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 @@ -459,7 +459,7 @@ public final class JavaCompilationHelper { JavaCommon.getHostJavaExecutable(ruleContext), getGenClassJar(ruleContext), javaToolchain.getJvmOptions()) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--manifest_proto", manifestProto) .addExecPath("--class_jar", classJar) @@ -805,7 +805,7 @@ public final class JavaCompilationHelper { .useDefaultShellEnvironment() .setProgressMessage("Extracting interface %s", ruleContext.getLabel()) .setMnemonic("JavaIjar") - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath(inputJar) .addExecPath(interfaceJar) 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 index 134326487f..1ede1d062d 100644 --- 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 @@ -40,6 +40,7 @@ import com.google.devtools.build.lib.actions.UserExecException; 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.ParamFileInfo; 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; @@ -385,12 +386,15 @@ public class JavaHeaderCompileAction extends SpawnAction { if ((noFallback || directJars.isEmpty()) && !requiresAnnotationProcessing) { SpawnAction.Builder builder = new SpawnAction.Builder(); NestedSet<Artifact> classpath; + final ParamFileInfo paramFileInfo; if (!directJars.isEmpty() || classpathEntries.isEmpty()) { classpath = directJars; + paramFileInfo = null; } else { classpath = classpathEntries; // Transitive classpath actions may exceed the command line length limit. - builder.alwaysUseParameterFile(ParameterFileType.UNQUOTED); + paramFileInfo = + ParamFileInfo.builder(ParameterFileType.UNQUOTED).setUseAlways(true).build(); } CustomCommandLine.Builder commandLine = baseCommandLine(CustomCommandLine.builder(), classpath); @@ -402,7 +406,7 @@ public class JavaHeaderCompileAction extends SpawnAction { .addTransitiveInputs(baseInputs) .addTransitiveInputs(classpath) .addOutputs(outputs) - .setCommandLine(commandLine.build()) + .addCommandLine(commandLine.build(), paramFileInfo) .setJarExecutable( JavaCommon.getHostJavaExecutable(ruleContext), javaToolchain.getHeaderCompiler(), diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/OneVersionCheckActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/OneVersionCheckActionBuilder.java index 8646b90987..b3eac8b5e2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/OneVersionCheckActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/OneVersionCheckActionBuilder.java @@ -21,6 +21,7 @@ import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; 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.CustomCommandLine.VectorArg; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -102,8 +103,9 @@ public final class OneVersionCheckActionBuilder { .addInput(oneVersionWhitelist) .addTransitiveInputs(jarsToCheck) .setExecutable(oneVersionTool) - .setCommandLine(oneVersionArgs) - .alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED) + .addCommandLine( + oneVersionArgs, + ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).setUseAlways(true).build()) .setMnemonic("JavaOneVersion") .setProgressMessage("Checking for one-version violations in %s", ruleContext.getLabel()) .build(ruleContext)); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/ProguardHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardHelper.java index 8255830b8e..108e933044 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/ProguardHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardHelper.java @@ -434,7 +434,7 @@ public abstract class ProguardHelper { proguardAction .setProgressMessage("Trimming binary with Proguard") .addOutput(proguardOutputJar); - proguardAction.setCommandLine(commandLine.build()); + proguardAction.addCommandLine(commandLine.build()); ruleContext.registerAction(proguardAction.build(ruleContext)); } else { // Optimization passes have been specified, so run proguard in multiple phases. @@ -463,7 +463,7 @@ public abstract class ProguardHelper { .setProgressMessage("Trimming binary with Proguard: Verification/Shrinking Pass") .addOutput(lastStageOutput); initialCommandLine.add("-runtype INITIAL").addExecPath("-nextstageoutput", lastStageOutput); - initialAction.setCommandLine(initialCommandLine.build()); + initialAction.addCommandLine(initialCommandLine.build()); ruleContext.registerAction(initialAction.build(ruleContext)); for (int i = 1; i <= optimizationPasses; i++) { @@ -517,7 +517,7 @@ public abstract class ProguardHelper { .add("-runtype OPTIMIZATION") .addExecPath("-laststageoutput", lastStageOutput) .addExecPath("-nextstageoutput", optimizationOutput); - optimizationAction.setCommandLine(optimizationCommandLine.build()); + optimizationAction.addCommandLine(optimizationCommandLine.build()); ruleContext.registerAction(optimizationAction.build(ruleContext)); lastStageOutput = optimizationOutput; } @@ -546,7 +546,7 @@ public abstract class ProguardHelper { .addInput(lastStageOutput) .addOutput(proguardOutputJar); finalCommandLine.add("-runtype FINAL").addExecPath("-laststageoutput", lastStageOutput); - finalAction.setCommandLine(finalCommandLine.build()); + finalAction.addCommandLine(finalCommandLine.build()); ruleContext.registerAction(finalAction.build(ruleContext)); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibrary.java index b4cbd42fe3..0dd83de667 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibrary.java @@ -134,7 +134,7 @@ public final class ProguardLibrary { .setExecutable(proguardWhitelister) .setProgressMessage("Validating proguard configuration") .setMnemonic("ValidateProguard") - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--path", specToValidate) .addExecPath("--output", output) diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/ResourceJarActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/ResourceJarActionBuilder.java index 0d9cf42e02..4f5643c97a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/ResourceJarActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/ResourceJarActionBuilder.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; 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.CustomCommandLine; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -123,6 +124,7 @@ public class ResourceJarActionBuilder { if (!classpathResources.isEmpty()) { command.addExecPaths("--classpath_resources", classpathResources); } + ParamFileInfo paramFileInfo = null; // TODO(b/37444705): remove this logic and always call useParameterFile once the bug is fixed // Most resource jar actions are very small and expanding the argument list for // ParamFileHelper#getParamsFileMaybe is expensive, so avoid doing that work if @@ -132,7 +134,7 @@ public class ResourceJarActionBuilder { if (sizeGreaterThanOrEqual( Iterables.concat(messages, resources.values(), resourceJars, classpathResources), 10) || ruleContext.getConfiguration().getMinParamFileSize() < 10000) { - builder.useParameterFile(ParameterFileType.SHELL_QUOTED); + paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build(); } ruleContext.registerAction( builder @@ -141,7 +143,7 @@ public class ResourceJarActionBuilder { .addInputs(resources.values()) .addTransitiveInputs(resourceJars) .addInputs(classpathResources) - .setCommandLine(command.build()) + .addCommandLine(command.build(), paramFileInfo) .setProgressMessage("Building Java resource jar") .setMnemonic(MNEMONIC) .build(ruleContext)); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java index 155d4359d9..d91cfed186 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java @@ -21,6 +21,7 @@ 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.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.vfs.PathFragment; @@ -73,8 +74,9 @@ public final class SingleJarActionBuilder { .addOutput(outputJar) .addInputs(resources.values()) .addInputs(resourceJars) - .setCommandLine(sourceJarCommandLine(outputJar, resources, resourceJars)) - .alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED) + .addCommandLine( + sourceJarCommandLine(outputJar, resources, resourceJars), + ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).setUseAlways(true).build()) .setProgressMessage("Building source jar %s", outputJar.prettyPrint()) .setMnemonic("JavaSourceJar"); ruleContext.registerAction(builder.build(ruleContext)); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java index 70556f01ce..6918e236b5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java @@ -162,7 +162,7 @@ public class AppleStubBinary implements RuleConfiguredTargetFactory { ruleContext.registerAction( ObjcRuleClasses.spawnAppleEnvActionBuilder(appleConfiguration, platform) .setExecutable(xcrunwrapper(ruleContext)) - .setCommandLine(copyCommandLine) + .addCommandLine(copyCommandLine) .setMnemonic("CopyStubExecutable") .addOutput(outputBinary) .disableSandboxing() diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java index d9d25fc5ba..9735630f3f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java @@ -240,7 +240,7 @@ final class BundleSupport { ObjcRuleClasses.spawnAppleEnvActionBuilder(appleConfiguration, platform) .setMnemonic("StoryboardCompile") .setExecutable(attributes.ibtoolWrapper()) - .setCommandLine(ibActionsCommandLine(archiveRoot, zipOutput, storyboardInput)) + .addCommandLine(ibActionsCommandLine(archiveRoot, zipOutput, storyboardInput)) .addOutput(zipOutput) .addInput(storyboardInput) .build(ruleContext)); @@ -290,7 +290,7 @@ final class BundleSupport { .setExecutable(attributes.momcWrapper()) .addOutput(outputZip) .addInputs(datamodel.getInputs()) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath(outputZip) .addDynamicString(datamodel.archiveRootForMomczip()) @@ -319,7 +319,7 @@ final class BundleSupport { ObjcRuleClasses.spawnAppleEnvActionBuilder(appleConfiguration, platform) .setMnemonic("XibCompile") .setExecutable(attributes.ibtoolWrapper()) - .setCommandLine(ibActionsCommandLine(archiveRoot, zipOutput, original)) + .addCommandLine(ibActionsCommandLine(archiveRoot, zipOutput, original)) .addOutput(zipOutput) .addInput(original) // Disable sandboxing due to Bazel issue #2189. @@ -335,7 +335,7 @@ final class BundleSupport { ObjcRuleClasses.spawnAppleEnvActionBuilder(appleConfiguration, platform) .setMnemonic("ConvertStringsPlist") .setExecutable(PathFragment.create("/usr/bin/plutil")) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("-convert") .add("binary1") @@ -377,7 +377,7 @@ final class BundleSupport { .addTransitiveInputs(mergingContentArtifacts) .addOutput(bundling.getIntermediateArtifacts().mergedInfoplist()) .addInput(plMergeControlArtifact) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--control", plMergeControlArtifact) .build()) @@ -420,10 +420,7 @@ final class BundleSupport { .addTransitiveInputs(objcProvider.get(ASSET_CATALOG)) .addOutput(zipOutput) .addOutput(actoolPartialInfoplist) - .setCommandLine(actoolzipCommandLine( - objcProvider, - zipOutput, - actoolPartialInfoplist)) + .addCommandLine(actoolzipCommandLine(objcProvider, zipOutput, actoolPartialInfoplist)) .disableSandboxing() .build(ruleContext)); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java index cf15e6082f..159821f0e5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java @@ -1138,7 +1138,7 @@ public abstract class CompilationSupport { .addTransitiveInputs(j2ObjcDependencyMappingFiles) .addTransitiveInputs(j2ObjcHeaderMappingFiles) .addTransitiveInputs(j2ObjcArchiveSourceMappingFiles) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder().addFormatted("@%s", paramFile.getExecPath()).build()) .addOutput(prunedJ2ObjcArchive) .build(ruleContext)); @@ -1231,7 +1231,7 @@ public abstract class CompilationSupport { appleConfiguration, appleConfiguration.getSingleArchPlatform()) .setMnemonic("ObjcBinarySymbolStrip") .setExecutable(xcrunwrapper(ruleContext)) - .setCommandLine(symbolStripCommandLine(stripArgs, binaryToLink, strippedBinary)) + .addCommandLine(symbolStripCommandLine(stripArgs, binaryToLink, strippedBinary)) .addOutput(strippedBinary) .addInput(binaryToLink) .build(ruleContext)); @@ -1431,7 +1431,7 @@ public abstract class CompilationSupport { } ruleContext.registerAction( builder - .setCommandLine(cmdLine.add("--").addAll(args).build()) + .addCommandLine(cmdLine.add("--").addAll(args).build()) .addInputs(compilationArtifacts.getPrivateHdrs()) .addTransitiveInputs(attributes.hdrs()) .addTransitiveInputs(objcProvider.get(ObjcProvider.HEADER)) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java index c90d5a7a62..a2daa20475 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java @@ -35,6 +35,7 @@ import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; 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; @@ -567,7 +568,7 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF .addTransitiveInputs(depsHeaderMappingFiles) .addTransitiveInputs(depsClassMappingFiles) .addInput(paramFile) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder().addFormatted("@%s", paramFile.getExecPath()).build()) .addOutputs(j2ObjcSource.getObjcSrcs()) .addOutputs(j2ObjcSource.getObjcHdrs()) @@ -594,16 +595,18 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF "--source_jars", VectorArg.join(",").each(ImmutableList.copyOf(sourceJars))); } headerMapCommandLine.addExecPath("--output_mapping_file", outputHeaderMappingFile); - ruleContext.registerAction(new SpawnAction.Builder() - .setMnemonic("GenerateJ2objcHeaderMap") - .setExecutable(ruleContext.getPrerequisiteArtifact("$j2objc_header_map", Mode.HOST)) - .addInput(ruleContext.getPrerequisiteArtifact("$j2objc_header_map", Mode.HOST)) - .addInputs(sources) - .addInputs(sourceJars) - .setCommandLine(headerMapCommandLine.build()) - .useParameterFile(ParameterFileType.SHELL_QUOTED) - .addOutput(outputHeaderMappingFile) - .build(ruleContext)); + ruleContext.registerAction( + new SpawnAction.Builder() + .setMnemonic("GenerateJ2objcHeaderMap") + .setExecutable(ruleContext.getPrerequisiteArtifact("$j2objc_header_map", Mode.HOST)) + .addInput(ruleContext.getPrerequisiteArtifact("$j2objc_header_map", Mode.HOST)) + .addInputs(sources) + .addInputs(sourceJars) + .addCommandLine( + headerMapCommandLine.build(), + ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build()) + .addOutput(outputHeaderMappingFile) + .build(ruleContext)); } return new J2ObjcMappingFileProvider( diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java index 4dc2556ce8..8eee5e22fa 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java @@ -420,7 +420,7 @@ public class LegacyCompilationSupport extends CompilationSupport { compileBuilder .setMnemonic("ObjcCompile") .setExecutable(xcrunwrapper(ruleContext)) - .setCommandLine(commandLine) + .addCommandLine(commandLine) .addOutput(objFile) .addOutputs(gcnoFile.asSet()) .addOutput(dotdFile.artifact()) @@ -510,7 +510,7 @@ public class LegacyCompilationSupport extends CompilationSupport { appleConfiguration, appleConfiguration.getSingleArchPlatform()) .setMnemonic("ObjcLink") .setExecutable(libtool(ruleContext)) - .setCommandLine( + .addCommandLine( new CustomCommandLine.Builder() .add("-static") .addExecPath("-filelist", objList) @@ -533,7 +533,7 @@ public class LegacyCompilationSupport extends CompilationSupport { appleConfiguration, appleConfiguration.getSingleArchPlatform()) .setMnemonic("ObjcLink") .setExecutable(libtool(ruleContext)) - .setCommandLine( + .addCommandLine( new CustomCommandLine.Builder() .add("-static") .add("-arch_only", appleConfiguration.getSingleArchitecture()) @@ -634,7 +634,7 @@ public class LegacyCompilationSupport extends CompilationSupport { appleConfiguration, appleConfiguration.getSingleArchPlatform()) .setMnemonic("ObjcLink") .setShellCommand(ImmutableList.of("/bin/bash", "-c")) - .setCommandLine(new SingleArgCommandLine(commandLine)) + .addCommandLine(new SingleArgCommandLine(commandLine)) .addOutput(binaryToLink) .addOutputs(dsymBundleZip.asSet()) .addOutputs(linkmap.asSet()) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java index 20471b3e22..f18f610b43 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java @@ -53,7 +53,7 @@ public class LipoSupport { .addTransitiveInputs(inputBinaries) .addOutput(outputBinary) .setExecutable(CompilationSupport.xcrunwrapper(ruleContext)) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add(ObjcRuleClasses.LIPO) .addExecPaths("-create", inputBinaries) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java index 5d7bb41683..e13c67c485 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java @@ -457,7 +457,7 @@ final class ProtobufSupport { .addOutputs(getGeneratedProtoOutputs(outputProtos, HEADER_SUFFIX)) .addOutputs(getProtoSourceFilesForCompilation(outputProtos)) .setExecutable(attributes.getProtoCompiler().getExecPath()) - .setCommandLine(getGenerationCommandLine(protoInputsFile)) + .addCommandLine(getGenerationCommandLine(protoInputsFile)) .build(ruleContext)); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java index 67dd444271..7e13b35921 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java @@ -75,7 +75,7 @@ final class ProtocolBuffers2Support { .addOutputs(getGeneratedProtoOutputs(getHeaderExtension())) .addOutputs(getGeneratedProtoOutputs(getSourceExtension())) .setExecutable(PathFragment.create("/usr/bin/python")) - .setCommandLine(getGenerationCommandLine()) + .addCommandLine(getGenerationCommandLine()) .build(ruleContext)); return this; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java index d33cb964e7..648bba234c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java @@ -390,7 +390,7 @@ public final class ReleaseBundlingSupport { .setMnemonic("EnvironmentPlist") .setExecutable(attributes.environmentPlist()) .addOutput(getGeneratedEnvironmentPlist()) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .add("--platform", platformWithVersion) .addExecPath("--output", getGeneratedEnvironmentPlist()) @@ -609,7 +609,7 @@ public final class ReleaseBundlingSupport { .addTransitiveInputs(entitlements) .addOutput(intermediateArtifacts.entitlements()) .addInput(plMergeControlArtifact) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder() .addExecPath("--control", plMergeControlArtifact) .build()) @@ -861,7 +861,7 @@ public final class ReleaseBundlingSupport { .addInput(bundleMergeControlArtifact) .addTransitiveInputs(bundling.getBundleContentArtifacts()) .addOutput(intermediateArtifacts.unprocessedIpa()) - .setCommandLine( + .addCommandLine( CustomCommandLine.builder().addExecPath(bundleMergeControlArtifact).build()) .build(ruleContext)); } @@ -1048,7 +1048,7 @@ public final class ReleaseBundlingSupport { ObjcRuleClasses.spawnAppleEnvActionBuilder(appleConfiguration, platform) .setMnemonic("SwiftStdlibCopy") .setExecutable(attributes.swiftStdlibToolWrapper()) - .setCommandLine(commandLine.build()) + .addCommandLine(commandLine.build()) .addOutput(intermediateArtifacts.swiftFrameworksFileZip()) .addInput(combinedArchBinary) .build(ruleContext)); @@ -1080,7 +1080,7 @@ public final class ReleaseBundlingSupport { ObjcRuleClasses.spawnAppleEnvActionBuilder(configuration, platform) .setMnemonic("SwiftCopySwiftSupport") .setExecutable(attributes.swiftStdlibToolWrapper()) - .setCommandLine(commandLine.build()) + .addCommandLine(commandLine.build()) .addOutput(intermediateArtifacts.swiftSupportZip()) .addInput(combinedArchBinary) .build(ruleContext)); diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java index 265b7d6e31..6022fc4223 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java @@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.ParameterFile; +import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; import com.google.devtools.build.lib.actions.ResourceSet; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.MakeVariableExpander; @@ -37,6 +37,7 @@ 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.CustomCommandLine.VectorArg; import com.google.devtools.build.lib.analysis.actions.FileWriteAction; +import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -251,12 +252,13 @@ public class ProtoCompileActionBuilder { } result - .useParameterFile(ParameterFile.ParameterFileType.UNQUOTED) .addOutputs(outputs) .setResources(GENPROTO_RESOURCE_SET) .useDefaultShellEnvironment() .setExecutable(compilerTarget) - .setCommandLine(createProtoCompilerCommandLine().build()) + .addCommandLine( + createProtoCompilerCommandLine().build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setProgressMessage("Generating %s proto_library %s", language, ruleContext.getLabel()) .setMnemonic(MNEMONIC); @@ -455,12 +457,11 @@ public class ProtoCompileActionBuilder { } result - .useParameterFile(ParameterFile.ParameterFileType.UNQUOTED) .addOutputs(outputs) .setResources(GENPROTO_RESOURCE_SET) .useDefaultShellEnvironment() .setExecutable(compilerTarget) - .setCommandLine( + .addCommandLine( createCommandLineFromToolchains( toolchainInvocations, protosToCompile, @@ -468,7 +469,8 @@ public class ProtoCompileActionBuilder { areDepsStrict(ruleContext) ? protosInDirectDeps : null, ruleLabel, allowServices, - ruleContext.getFragment(ProtoConfiguration.class).protocOpts())) + ruleContext.getFragment(ProtoConfiguration.class).protocOpts()), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .setProgressMessage("Generating %s proto_library %s", flavorName, ruleContext.getLabel()) .setMnemonic(MNEMONIC); diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PythonUtils.java b/src/main/java/com/google/devtools/build/lib/rules/python/PythonUtils.java index 824fef7b03..fe2133f91b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PythonUtils.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PythonUtils.java @@ -125,7 +125,7 @@ public final class PythonUtils { .setExecutable(py2to3converter) .setProgressMessage("Converting to Python 3: %s", input.prettyPrint()) .setMnemonic("2to3") - .setCommandLine(commandLine.build()) + .addCommandLine(commandLine.build()) .build(ruleContext)); return output; } diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java index 04414a412f..1bc7baf7af 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java @@ -87,7 +87,7 @@ public class SpawnActionTest extends BuildViewTestCase { .setProgressMessage("hi, mom!") .setMnemonic("Dummy") .setEnvironment(environmentVariables) - .setCommandLine(CommandLine.of(arguments)) + .addCommandLine(CommandLine.of(arguments)) .build(ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig); collectingAnalysisEnvironment.registerAction(actions); return (SpawnAction) actions[0]; @@ -173,8 +173,9 @@ public class SpawnActionTest extends BuildViewTestCase { jarArtifact, "MyMainClass", asList("-jvmarg")) - .useParameterFile(ParameterFileType.UNQUOTED) - .setCommandLine(CustomCommandLine.builder().add("-X").build()) + .addCommandLine( + CustomCommandLine.builder().add("-X").build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .build(ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig); collectingAnalysisEnvironment.registerAction(actions); SpawnAction action = (SpawnAction) actions[0]; @@ -216,8 +217,12 @@ public class SpawnActionTest extends BuildViewTestCase { jarArtifact, "MyMainClass", asList("-jvmarg")) - .setCommandLine(CustomCommandLine.builder().add("-X").build()) - .useParameterFile(ParameterFileType.UNQUOTED, ISO_8859_1, "--flagfile=") + .addCommandLine( + CustomCommandLine.builder().add("-X").build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED) + .setCharset(ISO_8859_1) + .setFlag("--flagfile=") + .build()) .build(ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig); collectingAnalysisEnvironment.registerAction(actions); SpawnAction action = (SpawnAction) actions[0]; @@ -253,7 +258,7 @@ public class SpawnActionTest extends BuildViewTestCase { "MyMainClass", asList("-jvmarg")) .addExecutableArguments("execArg1", "execArg2") - .setCommandLine(CustomCommandLine.builder().add("arg1").build()) + .addCommandLine(CustomCommandLine.builder().add("arg1").build()) .build(ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig); collectingAnalysisEnvironment.registerAction(actions); SpawnAction action = (SpawnAction) actions[0]; @@ -286,8 +291,9 @@ public class SpawnActionTest extends BuildViewTestCase { "MyMainClass", asList("-jvmarg")) .addExecutableArguments("execArg1", "execArg2") - .useParameterFile(ParameterFileType.UNQUOTED) - .setCommandLine(CustomCommandLine.builder().add("arg1").add("arg2").add("arg3").build()) + .addCommandLine( + CustomCommandLine.builder().add("arg1").add("arg2").add("arg3").build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .build(ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig); collectingAnalysisEnvironment.registerAction(actions); SpawnAction action = (SpawnAction) actions[0]; @@ -338,8 +344,9 @@ public class SpawnActionTest extends BuildViewTestCase { builder() .addOutput(output1) .setExecutable(executable) - .useParameterFile(ParameterFileType.UNQUOTED) - .setCommandLine(CustomCommandLine.builder().addDynamicString(longOption).build()) + .addCommandLine( + CustomCommandLine.builder().addDynamicString(longOption).build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .build( ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig)[ 0]); @@ -352,8 +359,9 @@ public class SpawnActionTest extends BuildViewTestCase { builder() .addOutput(output2) .setExecutable(executable) - .useParameterFile(ParameterFileType.UNQUOTED) - .setCommandLine(CustomCommandLine.builder().addDynamicString(longOption).build()) + .addCommandLine( + CustomCommandLine.builder().addDynamicString(longOption).build(), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) .build( ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig)[ 0]); @@ -361,6 +369,48 @@ public class SpawnActionTest extends BuildViewTestCase { } @Test + public void testMultipleCommandLines() throws Exception { + Artifact input = getSourceArtifact("input"); + Artifact output = getBinArtifactWithNoOwner("output"); + Action[] actions = + builder() + .addInput(input) + .addOutput(output) + .setExecutable(scratch.file("/bin/xxx").asFragment()) + .addCommandLine(CommandLine.of(ImmutableList.of("arg1"))) + .addCommandLine(CommandLine.of(ImmutableList.of("arg2"))) + .build(ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig); + SpawnAction action = (SpawnAction) actions[0]; + assertThat(action.getArguments()).containsExactly("/bin/xxx", "arg1", "arg2"); + } + + @Test + public void testMultipleParameterFiles() throws Exception { + useConfiguration("--min_param_file_size=0"); + Artifact input = getSourceArtifact("input"); + Artifact output = getBinArtifactWithNoOwner("output"); + Artifact paramFile1 = getBinArtifactWithNoOwner("output-2.params"); + Artifact paramFile2 = getBinArtifactWithNoOwner("output-3.params"); + Action[] actions = + builder() + .addInput(input) + .addOutput(output) + .setExecutable(scratch.file("/bin/xxx").asFragment()) + .addCommandLine( + CommandLine.of(ImmutableList.of("arg1")), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) + .addCommandLine( + CommandLine.of(ImmutableList.of("arg2")), + ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) + .build(ActionsTestUtil.NULL_ACTION_OWNER, collectingAnalysisEnvironment, targetConfig); + SpawnAction action = (SpawnAction) actions[0]; + assertThat(actions).hasLength(3); + assertThat(action.getArguments()) + .containsExactly( + "/bin/xxx", "@" + paramFile1.getExecPathString(), "@" + paramFile2.getExecPathString()); + } + + @Test public void testExtraActionInfo() throws Exception { SpawnAction action = createCopyFromWelcomeToDestination(ImmutableMap.<String, String>of()); ExtraActionInfo info = action.getExtraActionInfo().build(); |