aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2018-01-12 09:01:13 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-01-12 09:02:32 -0800
commitd4c19e65c9e219772d22720761ef7646cdb210f8 (patch)
tree71f3e5dc98823a1fea347bccd0505aba1f0381ca /src/main
parent849cec256c606db47dc179c788f937d7482087ae (diff)
RELNOTES: Allow expanding TreeArtifacts for libraries_to_link
PiperOrigin-RevId: 181750466
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java181
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java46
4 files changed, 211 insertions, 88 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
index 9d3a2f6719..17d4adcb60 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
@@ -32,6 +32,8 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.google.common.collect.Streams;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -76,7 +78,7 @@ import javax.annotation.Nullable;
*/
@Immutable
public class CcToolchainFeatures implements Serializable {
-
+
/**
* Thrown when a flag value cannot be expanded under a set of build variables.
*
@@ -292,7 +294,7 @@ public class CcToolchainFeatures implements Serializable {
* <p>The {@code variables} controls which variables are visible during the expansion and allows
* to recursively expand nested flag groups.
*/
- void expand(Variables variables, List<String> commandLine);
+ void expand(Variables variables, @Nullable ArtifactExpander expander, List<String> commandLine);
}
/**
@@ -308,10 +310,11 @@ public class CcToolchainFeatures implements Serializable {
private Flag(ImmutableList<StringChunk> chunks) {
this.chunks = chunks;
}
-
+
/** Expand this flag into a single new entry in {@code commandLine}. */
@Override
- public void expand(Variables variables, List<String> commandLine) {
+ public void expand(
+ Variables variables, @Nullable ArtifactExpander expander, List<String> commandLine) {
StringBuilder flag = new StringBuilder();
for (StringChunk chunk : chunks) {
chunk.expand(variables, flag);
@@ -406,53 +409,55 @@ public class CcToolchainFeatures implements Serializable {
this.expandIfEqual = null;
}
}
-
+
@Override
- public void expand(Variables variables, final List<String> commandLine) {
- if (!canBeExpanded(variables)) {
+ public void expand(
+ Variables variables, @Nullable ArtifactExpander expander, final List<String> commandLine) {
+ if (!canBeExpanded(variables, expander)) {
return;
}
if (iterateOverVariable != null) {
- for (VariableValue variableValue : variables.getSequenceVariable(iterateOverVariable)) {
+ for (VariableValue variableValue :
+ variables.getSequenceVariable(iterateOverVariable, expander)) {
Variables nestedVariables = new Variables(variables, iterateOverVariable, variableValue);
for (Expandable expandable : expandables) {
- expandable.expand(nestedVariables, commandLine);
+ expandable.expand(nestedVariables, expander, commandLine);
}
}
} else {
for (Expandable expandable : expandables) {
- expandable.expand(variables, commandLine);
+ expandable.expand(variables, expander, commandLine);
}
}
}
- private boolean canBeExpanded(Variables variables) {
+ private boolean canBeExpanded(Variables variables, @Nullable ArtifactExpander expander) {
for (String variable : expandIfAllAvailable) {
- if (!variables.isAvailable(variable)) {
+ if (!variables.isAvailable(variable, expander)) {
return false;
}
}
for (String variable : expandIfNoneAvailable) {
- if (variables.isAvailable(variable)) {
+ if (variables.isAvailable(variable, expander)) {
return false;
}
}
if (expandIfTrue != null
- && (!variables.isAvailable(expandIfTrue)
+ && (!variables.isAvailable(expandIfTrue, expander)
|| !variables.getVariable(expandIfTrue).isTruthy())) {
return false;
}
if (expandIfFalse != null
- && (!variables.isAvailable(expandIfFalse)
+ && (!variables.isAvailable(expandIfFalse, expander)
|| variables.getVariable(expandIfFalse).isTruthy())) {
return false;
}
if (expandIfEqual != null
- && (!variables.isAvailable(expandIfEqual.variable)
+ && (!variables.isAvailable(expandIfEqual.variable, expander)
|| !variables
- .getVariable(expandIfEqual.variable)
- .getStringValue(expandIfEqual.variable)
- .equals(expandIfEqual.value))) {
+ .getVariable(expandIfEqual.variable)
+ .getStringValue(expandIfEqual.variable)
+ .equals(expandIfEqual.value))) {
return false;
}
return true;
@@ -473,8 +478,9 @@ public class CcToolchainFeatures implements Serializable {
* explicit 'iterate_over' instead.
* </ul>
*/
- private void expandCommandLine(Variables variables, final List<String> commandLine) {
- expand(variables, commandLine);
+ private void expandCommandLine(
+ Variables variables, @Nullable ArtifactExpander expander, final List<String> commandLine) {
+ expand(variables, expander, commandLine);
}
}
@@ -532,9 +538,10 @@ public class CcToolchainFeatures implements Serializable {
String action,
Variables variables,
Set<String> enabledFeatureNames,
+ @Nullable ArtifactExpander expander,
List<String> commandLine) {
for (String variable : expandIfAllAvailable) {
- if (!variables.isAvailable(variable)) {
+ if (!variables.isAvailable(variable, expander)) {
return;
}
}
@@ -545,7 +552,7 @@ public class CcToolchainFeatures implements Serializable {
return;
}
for (FlagGroup flagGroup : flagGroups) {
- flagGroup.expandCommandLine(variables, commandLine);
+ flagGroup.expandCommandLine(variables, expander, commandLine);
}
}
}
@@ -649,9 +656,10 @@ public class CcToolchainFeatures implements Serializable {
String action,
Variables variables,
Set<String> enabledFeatureNames,
+ @Nullable ArtifactExpander expander,
List<String> commandLine) {
for (FlagSet flagSet : flagSets) {
- flagSet.expandCommandLine(action, variables, enabledFeatureNames, commandLine);
+ flagSet.expandCommandLine(action, variables, enabledFeatureNames, expander, commandLine);
}
}
}
@@ -778,9 +786,13 @@ public class CcToolchainFeatures implements Serializable {
/** Adds the flags that apply to this action to {@code commandLine}. */
private void expandCommandLine(
- Variables variables, Set<String> enabledFeatureNames, List<String> commandLine) {
+ Variables variables,
+ Set<String> enabledFeatureNames,
+ @Nullable ArtifactExpander expander,
+ List<String> commandLine) {
for (FlagSet flagSet : flagSets) {
- flagSet.expandCommandLine(actionName, variables, enabledFeatureNames, commandLine);
+ flagSet.expandCommandLine(
+ actionName, variables, enabledFeatureNames, expander, commandLine);
}
}
}
@@ -899,6 +911,9 @@ public class CcToolchainFeatures implements Serializable {
*/
VariableValue getFieldValue(String variableName, String field);
+ VariableValue getFieldValue(
+ String variableName, String field, @Nullable ArtifactExpander expander);
+
/** Returns true if the variable is truthy */
boolean isTruthy();
}
@@ -919,6 +934,12 @@ public class CcToolchainFeatures implements Serializable {
@Override
public VariableValue getFieldValue(String variableName, String field) {
+ return getFieldValue(variableName, field, null);
+ }
+
+ @Override
+ public VariableValue getFieldValue(
+ String variableName, String field, @Nullable ArtifactExpander expander) {
throw new ExpansionException(
String.format(
"Invalid toolchain configuration: Cannot expand variable '%s.%s': variable '%s' is "
@@ -1097,58 +1118,87 @@ public class CcToolchainFeatures implements Serializable {
}
private final String name;
+ private final Artifact directory;
private final ImmutableList<String> objectFiles;
private final boolean isWholeArchive;
private final Type type;
public static LibraryToLinkValue forDynamicLibrary(String name) {
return new LibraryToLinkValue(
- Preconditions.checkNotNull(name), null, false, Type.DYNAMIC_LIBRARY);
+ Preconditions.checkNotNull(name), null, null, false, Type.DYNAMIC_LIBRARY);
}
public static LibraryToLinkValue forVersionedDynamicLibrary(
String name) {
return new LibraryToLinkValue(
- Preconditions.checkNotNull(name), null, false, Type.VERSIONED_DYNAMIC_LIBRARY);
+ Preconditions.checkNotNull(name), null, null, false, Type.VERSIONED_DYNAMIC_LIBRARY);
}
public static LibraryToLinkValue forInterfaceLibrary(String name) {
return new LibraryToLinkValue(
- Preconditions.checkNotNull(name), null, false, Type.INTERFACE_LIBRARY);
+ Preconditions.checkNotNull(name), null, null, false, Type.INTERFACE_LIBRARY);
}
public static LibraryToLinkValue forStaticLibrary(String name, boolean isWholeArchive) {
return new LibraryToLinkValue(
- Preconditions.checkNotNull(name), null, isWholeArchive, Type.STATIC_LIBRARY);
+ Preconditions.checkNotNull(name), null, null, isWholeArchive, Type.STATIC_LIBRARY);
}
public static LibraryToLinkValue forObjectFile(String name, boolean isWholeArchive) {
return new LibraryToLinkValue(
- Preconditions.checkNotNull(name), null, isWholeArchive, Type.OBJECT_FILE);
+ Preconditions.checkNotNull(name), null, null, isWholeArchive, Type.OBJECT_FILE);
}
public static LibraryToLinkValue forObjectFileGroup(
ImmutableList<String> objects, boolean isWholeArchive) {
Preconditions.checkNotNull(objects);
Preconditions.checkArgument(!objects.isEmpty());
- return new LibraryToLinkValue(null, objects, isWholeArchive, Type.OBJECT_FILE_GROUP);
+ return new LibraryToLinkValue(null, null, objects, isWholeArchive, Type.OBJECT_FILE_GROUP);
+ }
+
+ public static LibraryToLinkValue forObjectDirectory(
+ Artifact directory, boolean isWholeArchive) {
+ Preconditions.checkNotNull(directory);
+ Preconditions.checkArgument(directory.isTreeArtifact());
+ return new LibraryToLinkValue(
+ null, directory, null, isWholeArchive, Type.OBJECT_FILE_GROUP);
}
private LibraryToLinkValue(
- String name, ImmutableList<String> objectFiles, boolean isWholeArchive, Type type) {
+ String name,
+ Artifact directory,
+ ImmutableList<String> objectFiles,
+ boolean isWholeArchive,
+ Type type) {
this.name = name;
+ this.directory = directory;
this.objectFiles = objectFiles;
this.isWholeArchive = isWholeArchive;
this.type = type;
}
@Override
- public VariableValue getFieldValue(String variableName, String field) {
+ public VariableValue getFieldValue(
+ String variableName, String field, @Nullable ArtifactExpander expander) {
Preconditions.checkNotNull(field);
if (NAME_FIELD_NAME.equals(field) && !type.equals(Type.OBJECT_FILE_GROUP)) {
return new StringValue(name);
} else if (OBJECT_FILES_FIELD_NAME.equals(field) && type.equals(Type.OBJECT_FILE_GROUP)) {
- return new StringSequence(objectFiles);
+ ImmutableList.Builder<String> expandedObjectFiles = ImmutableList.builder();
+ if (objectFiles != null) {
+ expandedObjectFiles.addAll(objectFiles);
+ } else if (directory != null) {
+ if (expander != null) {
+ List<Artifact> artifacts = new ArrayList<>();
+ expander.expand(directory, artifacts);
+
+ expandedObjectFiles.addAll(
+ Iterables.transform(artifacts, artifact -> artifact.getExecPathString()));
+ } else {
+ expandedObjectFiles.add(directory.getExecPathString());
+ }
+ }
+ return new StringSequence(expandedObjectFiles.build());
} else if (TYPE_FIELD_NAME.equals(field)) {
return new StringValue(type.name);
} else if (IS_WHOLE_ARCHIVE_FIELD_NAME.equals(field)) {
@@ -1283,7 +1333,8 @@ public class CcToolchainFeatures implements Serializable {
}
@Override
- public VariableValue getFieldValue(String variableName, String field) {
+ public VariableValue getFieldValue(
+ String variableName, String field, @Nullable ArtifactExpander expander) {
if (value.containsKey(field)) {
return value.get(field);
} else {
@@ -1570,7 +1621,11 @@ public class CcToolchainFeatures implements Serializable {
* accessing a field of non-structured variable
*/
public VariableValue getVariable(String name) {
- return lookupVariable(name, true);
+ return lookupVariable(name, true, null);
+ }
+
+ public VariableValue getVariable(String name, @Nullable ArtifactExpander expander) {
+ return lookupVariable(name, true, expander);
}
/**
@@ -1580,12 +1635,14 @@ public class CcToolchainFeatures implements Serializable {
* @return Pair<VariableValue, String> returns either (variable value, null) or (null, string
* reason why variable was not found)
*/
- private VariableValue lookupVariable(String name, boolean throwOnMissingVariable) {
+ private VariableValue lookupVariable(
+ String name, boolean throwOnMissingVariable, @Nullable ArtifactExpander expander) {
VariableValue nonStructuredVariable = getNonStructuredVariable(name);
if (nonStructuredVariable != null) {
return nonStructuredVariable;
}
- VariableValue structuredVariable = getStructureVariable(name, throwOnMissingVariable);
+ VariableValue structuredVariable =
+ getStructureVariable(name, throwOnMissingVariable, expander);
if (structuredVariable != null) {
return structuredVariable;
} else if (throwOnMissingVariable) {
@@ -1612,7 +1669,8 @@ public class CcToolchainFeatures implements Serializable {
return null;
}
- private VariableValue getStructureVariable(String name, boolean throwOnMissingVariable) {
+ private VariableValue getStructureVariable(
+ String name, boolean throwOnMissingVariable, @Nullable ArtifactExpander expander) {
if (!name.contains(".")) {
return null;
}
@@ -1633,7 +1691,7 @@ public class CcToolchainFeatures implements Serializable {
while (!fieldsToAccess.empty()) {
String field = fieldsToAccess.pop();
- variable = variable.getFieldValue(structPath, field);
+ variable = variable.getFieldValue(structPath, field, expander);
if (variable == null) {
if (throwOnMissingVariable) {
throw new ExpansionException(
@@ -1650,16 +1708,29 @@ public class CcToolchainFeatures implements Serializable {
}
public String getStringVariable(String variableName) {
- return getVariable(variableName).getStringValue(variableName);
+ return getVariable(variableName, null).getStringValue(variableName);
+ }
+
+ public String getStringVariable(String variableName, @Nullable ArtifactExpander expander) {
+ return getVariable(variableName, expander).getStringValue(variableName);
}
public Iterable<? extends VariableValue> getSequenceVariable(String variableName) {
- return getVariable(variableName).getSequenceValue(variableName);
+ return getVariable(variableName, null).getSequenceValue(variableName);
+ }
+
+ public Iterable<? extends VariableValue> getSequenceVariable(
+ String variableName, @Nullable ArtifactExpander expander) {
+ return getVariable(variableName, expander).getSequenceValue(variableName);
}
/** Returns whether {@code variable} is set. */
boolean isAvailable(String variable) {
- return lookupVariable(variable, false) != null;
+ return isAvailable(variable, null);
+ }
+
+ boolean isAvailable(String variable, @Nullable ArtifactExpander expander) {
+ return lookupVariable(variable, false, expander) != null;
}
}
@@ -1725,19 +1796,22 @@ public class CcToolchainFeatures implements Serializable {
return enabledActionConfigActionNames.contains(actionName);
}
- /**
- * @return the command line for the given {@code action}.
- */
+ /** @return the command line for the given {@code action}. */
public List<String> getCommandLine(String action, Variables variables) {
+ return getCommandLine(action, variables, null);
+ }
+
+ public List<String> getCommandLine(
+ String action, Variables variables, @Nullable ArtifactExpander expander) {
List<String> commandLine = new ArrayList<>();
if (actionIsConfigured(action)) {
actionConfigByActionName
.get(action)
- .expandCommandLine(variables, enabledFeatureNames, commandLine);
+ .expandCommandLine(variables, enabledFeatureNames, expander, commandLine);
}
for (Feature feature : enabledFeatures) {
- feature.expandCommandLine(action, variables, enabledFeatureNames, commandLine);
+ feature.expandCommandLine(action, variables, enabledFeatureNames, expander, commandLine);
}
return commandLine;
@@ -1746,18 +1820,23 @@ public class CcToolchainFeatures implements Serializable {
/** @return the flags expanded for the given {@code action} in per-feature buckets. */
public ImmutableList<Pair<String, List<String>>> getPerFeatureExpansions(
String action, Variables variables) {
+ return getPerFeatureExpansions(action, variables, null);
+ }
+
+ public ImmutableList<Pair<String, List<String>>> getPerFeatureExpansions(
+ String action, Variables variables, @Nullable ArtifactExpander expander) {
ImmutableList.Builder<Pair<String, List<String>>> perFeatureExpansions =
ImmutableList.builder();
if (actionIsConfigured(action)) {
List<String> commandLine = new ArrayList<>();
ActionConfig actionConfig = actionConfigByActionName.get(action);
- actionConfig.expandCommandLine(variables, enabledFeatureNames, commandLine);
+ actionConfig.expandCommandLine(variables, enabledFeatureNames, expander, commandLine);
perFeatureExpansions.add(Pair.of(actionConfig.getName(), commandLine));
}
for (Feature feature : enabledFeatures) {
List<String> commandLine = new ArrayList<>();
- feature.expandCommandLine(action, variables, enabledFeatureNames, commandLine);
+ feature.expandCommandLine(action, variables, enabledFeatureNames, expander, commandLine);
perFeatureExpansions.add(Pair.of(feature.getName(), commandLine));
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java
index 86aea4c801..932b5d8d93 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java
@@ -29,6 +29,7 @@ import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.ActionResult;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.CommandAction;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.ExecException;
@@ -284,10 +285,11 @@ public final class CppLinkAction extends AbstractAction
* Returns the command line specification for this link, included any required linkstamp
* compilation steps. The command line may refer to a .params file.
*
+ * @param expander ArtifactExpander for expanding TreeArtifacts.
* @return a finalized command line suitable for execution
*/
- public final List<String> getCommandLine() {
- return linkCommandLine.getCommandLine();
+ public final List<String> getCommandLine(@Nullable ArtifactExpander expander) {
+ return linkCommandLine.getCommandLine(expander);
}
/**
@@ -305,18 +307,19 @@ public final class CppLinkAction extends AbstractAction
public ActionResult execute(ActionExecutionContext actionExecutionContext)
throws ActionExecutionException, InterruptedException {
if (fake) {
- executeFake();
+ executeFake(actionExecutionContext.getArtifactExpander());
return ActionResult.EMPTY;
} else {
try {
- Spawn spawn = new SimpleSpawn(
- this,
- ImmutableList.copyOf(getCommandLine()),
- getEnvironment(),
- getExecutionInfo(),
- ImmutableList.copyOf(getMandatoryInputs()),
- getOutputs().asList(),
- estimateResourceConsumptionLocal());
+ Spawn spawn =
+ new SimpleSpawn(
+ this,
+ ImmutableList.copyOf(getCommandLine(actionExecutionContext.getArtifactExpander())),
+ getEnvironment(),
+ getExecutionInfo(),
+ ImmutableList.copyOf(getMandatoryInputs()),
+ getOutputs().asList(),
+ estimateResourceConsumptionLocal());
return ActionResult.create(
actionExecutionContext
.getSpawnActionContext(getMnemonic())
@@ -332,11 +335,11 @@ public final class CppLinkAction extends AbstractAction
// Don't forget to update FAKE_LINK_GUID if you modify this method.
@ThreadCompatible
- private void executeFake()
- throws ActionExecutionException {
+ private void executeFake(@Nullable ArtifactExpander expander) throws ActionExecutionException {
// Prefix all fake output files in the command line with $TEST_TMPDIR/.
final String outputPrefix = "$TEST_TMPDIR/";
- List<String> escapedLinkArgv = escapeLinkArgv(linkCommandLine.getRawLinkArgv(), outputPrefix);
+ List<String> escapedLinkArgv =
+ escapeLinkArgv(linkCommandLine.getRawLinkArgv(expander), outputPrefix);
// Write the commands needed to build the real target to the fake target
// file.
StringBuilder s = new StringBuilder();
@@ -424,7 +427,7 @@ public final class CppLinkAction extends AbstractAction
info.setLinkStaticness(getLinkCommandLine().getLinkStaticness().name());
info.addAllLinkStamp(Artifact.toExecPaths(getLinkstampObjects()));
info.addAllBuildInfoHeaderArtifact(Artifact.toExecPaths(getBuildInfoHeaderArtifacts()));
- info.addAllLinkOpt(getLinkCommandLine().getRawLinkArgv());
+ info.addAllLinkOpt(getLinkCommandLine().getRawLinkArgv(null));
try {
return super.getExtraActionInfo(actionKeyContext)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
index df76aad01a..f7646c6d25 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
@@ -969,7 +969,8 @@ public class CppLinkActionBuilder {
.setLinkopts(ImmutableList.copyOf(linkopts));
} else {
List<String> opts = new ArrayList<>(linkopts);
- opts.addAll(featureConfiguration.getCommandLine("lto-indexing", buildVariables));
+ opts.addAll(
+ featureConfiguration.getCommandLine("lto-indexing", buildVariables, null /* expander */));
opts.addAll(cppConfiguration.getLtoIndexOptions());
linkCommandLineBuilder.setLinkopts(ImmutableList.copyOf(opts));
}
@@ -1065,9 +1066,13 @@ public class CppLinkActionBuilder {
}
if (linkCommandLine.getParamFile() != null) {
inputsBuilder.add(ImmutableList.of(linkCommandLine.getParamFile()));
+ // Pass along tree artifacts, so they can be properly expanded.
+ Iterable<Artifact> expandedNonLibraryTreeArtifactInputs =
+ Iterables.filter(expandedNonLibraryInputs, a -> a.isTreeArtifact());
Action parameterFileWriteAction =
new ParameterFileWriteAction(
getOwner(),
+ expandedNonLibraryTreeArtifactInputs,
paramFile,
linkCommandLine.paramCmdLine(),
ParameterFile.ParameterFileType.UNQUOTED,
@@ -1260,15 +1265,6 @@ public class CppLinkActionBuilder {
return this;
}
- private void addObjectFile(LinkerInput input) {
- // We skip file extension checks for TreeArtifacts because they represent directory artifacts
- // without a file extension.
- String name = input.getArtifact().getFilename();
- Preconditions.checkArgument(
- input.getArtifact().isTreeArtifact() || Link.OBJECT_FILETYPES.matches(name), name);
- this.objectFiles.add(input);
- }
-
public CppLinkActionBuilder addLtoBitcodeFiles(ImmutableMap<Artifact, Artifact> files) {
Preconditions.checkState(ltoBitcodeFiles == null);
ltoBitcodeFiles = files;
@@ -1280,6 +1276,15 @@ public class CppLinkActionBuilder {
return this;
}
+ private void addObjectFile(LinkerInput input) {
+ // We skip file extension checks for TreeArtifacts because they represent directory artifacts
+ // without a file extension.
+ String name = input.getArtifact().getFilename();
+ Preconditions.checkArgument(
+ input.getArtifact().isTreeArtifact() || Link.OBJECT_FILETYPES.matches(name), name);
+ this.objectFiles.add(input);
+ }
+
/**
* Adds a single object file to the set of inputs.
*/
@@ -2058,10 +2063,16 @@ public class CppLinkActionBuilder {
name = inputArtifact.getExecPathString();
}
- librariesToLink.addValue(
- artifactCategory.equals(ArtifactCategory.OBJECT_FILE)
- ? LibraryToLinkValue.forObjectFile(name, inputIsWholeArchive)
- : LibraryToLinkValue.forStaticLibrary(name, inputIsWholeArchive));
+ if (artifactCategory.equals(ArtifactCategory.OBJECT_FILE)) {
+ if (inputArtifact.isTreeArtifact()) {
+ librariesToLink.addValue(
+ LibraryToLinkValue.forObjectDirectory(inputArtifact, inputIsWholeArchive));
+ } else {
+ librariesToLink.addValue(LibraryToLinkValue.forObjectFile(name, inputIsWholeArchive));
+ }
+ } else {
+ librariesToLink.addValue(LibraryToLinkValue.forStaticLibrary(name, inputIsWholeArchive));
+ }
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
index 83116f4dd5..f14fe175f7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
@@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CommandLine;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -188,7 +189,13 @@ public final class LinkCommandLine extends CommandLine {
*/
@VisibleForTesting
final Pair<List<String>, List<String>> splitCommandline() {
- List<String> args = getRawLinkArgv();
+ return splitCommandline(null);
+ }
+
+ @VisibleForTesting
+ final Pair<List<String>, List<String>> splitCommandline(@Nullable ArtifactExpander expander) {
+ Preconditions.checkNotNull(paramFile);
+ List<String> args = getRawLinkArgv(expander);
if (linkTargetType.staticness() == Staticness.STATIC) {
// Ar link commands can also generate huge command lines.
List<String> paramFileArgs = new ArrayList<>();
@@ -215,7 +222,12 @@ public final class LinkCommandLine extends CommandLine {
return new CommandLine() {
@Override
public Iterable<String> arguments() {
- return splitCommandline().getSecond();
+ return splitCommandline(null).getSecond();
+ }
+
+ @Override
+ public Iterable<String> arguments(ArtifactExpander expander) {
+ return splitCommandline(expander).getSecond();
}
};
}
@@ -342,11 +354,23 @@ public final class LinkCommandLine extends CommandLine {
/**
* Returns a raw link command for the given link invocation, including both command and arguments
- * (argv).
+ * (argv). The version that uses the expander is preferred, but that one can't be used during
+ * analysis.
*
* @return raw link command line.
*/
public List<String> getRawLinkArgv() {
+ return getRawLinkArgv(null);
+ }
+
+ /**
+ * Returns a raw link command for the given link invocation, including both command and arguments
+ * (argv).
+ *
+ * @param expander ArtifactExpander for expanding TreeArtifacts.
+ * @return raw link command line.
+ */
+ public List<String> getRawLinkArgv(@Nullable ArtifactExpander expander) {
List<String> argv = new ArrayList<>();
if (forcedToolPath != null) {
argv.add(forcedToolPath);
@@ -366,24 +390,30 @@ public final class LinkCommandLine extends CommandLine {
new Variables.Builder(variables)
.addStringSequenceVariable(
CppLinkActionBuilder.LEGACY_LINK_FLAGS_VARIABLE, getToolchainFlags())
- .build()));
+ .build(),
+ expander));
return argv;
}
- List<String> getCommandLine() {
+ List<String> getCommandLine(@Nullable ArtifactExpander expander) {
// Try to shorten the command line by use of a parameter file.
// This makes the output with --subcommands (et al) more readable.
if (paramFile != null) {
- Pair<List<String>, List<String>> split = splitCommandline();
+ Pair<List<String>, List<String>> split = splitCommandline(expander);
return split.first;
} else {
- return getRawLinkArgv();
+ return getRawLinkArgv(expander);
}
}
@Override
public List<String> arguments() {
- return getRawLinkArgv();
+ return getRawLinkArgv(null);
+ }
+
+ @Override
+ public Iterable<String> arguments(ArtifactExpander artifactExpander) {
+ return getRawLinkArgv(artifactExpander);
}
/** A builder for a {@link LinkCommandLine}. */