aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
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/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
parent849cec256c606db47dc179c788f937d7482087ae (diff)
RELNOTES: Allow expanding TreeArtifacts for libraries_to_link
PiperOrigin-RevId: 181750466
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java181
1 files changed, 130 insertions, 51 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));
}