aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
authorGravatar Chris Parsons <cparsons@google.com>2016-01-07 16:56:37 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-01-07 20:20:06 +0000
commitefe22ec3338a82a0e4c3f5c256f5f86a27fc4f4e (patch)
tree989a7243eaf6ff39fe46a9cdcc933f04ed76c424 /src/main/java/com/google/devtools
parent6ecf17a26b1907362c45410c6399533e48f8c467 (diff)
Extend crosstool configuration to allow features to specify (expandable) environment variables to pass to actions
-- MOS_MIGRATED_REVID=111608329
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java168
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java9
2 files changed, 135 insertions, 42 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 598fd6e5a1..15edc30dd5 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
@@ -74,13 +74,13 @@ public class CcToolchainFeatures implements Serializable {
}
/**
- * A piece of a single flag.
+ * A piece of a single string value.
*
- * <p>A single flag can contain a combination of text and variables (for example
- * "-f %{var1}/%{var2}"). We split the flag into chunks, where each chunk represents either a
+ * <p>A single value can contain a combination of text and variables (for example
+ * "-f %{var1}/%{var2}"). We split the string into chunks, where each chunk represents either a
* text snippet, or a variable that is to be replaced.
*/
- interface FlagChunk {
+ interface StringChunk {
/**
* Expands this chunk.
@@ -92,13 +92,13 @@ public class CcToolchainFeatures implements Serializable {
}
/**
- * A plain text chunk of a flag.
+ * A plain text chunk of a string (containing no variables).
*/
@Immutable
- private static class StringChunk implements FlagChunk, Serializable {
+ private static class StringLiteralChunk implements StringChunk, Serializable {
private final String text;
- private StringChunk(String text) {
+ private StringLiteralChunk(String text) {
this.text = text;
}
@@ -109,10 +109,10 @@ public class CcToolchainFeatures implements Serializable {
}
/**
- * A chunk of a flag into which a variable should be expanded.
+ * A chunk of a string value into which a variable should be expanded.
*/
@Immutable
- private static class VariableChunk implements FlagChunk, Serializable {
+ private static class VariableChunk implements StringChunk, Serializable {
private final String variableName;
private VariableChunk(String variableName) {
@@ -120,7 +120,7 @@ public class CcToolchainFeatures implements Serializable {
}
@Override
- public void expand(Map<String, String> variables, StringBuilder flag) {
+ public void expand(Map<String, String> variables, StringBuilder stringBuilder) {
// We check all variables in FlagGroup.expandCommandLine.
// If we arrive here with the variable not being available, the variable was provided, but
// the nesting level of the NestedSequence was deeper than the nesting level of the flag
@@ -136,31 +136,29 @@ public class CcToolchainFeatures implements Serializable {
throw new ExpansionException(
"Internal blaze error: build variable '" + variableName + "'was set to 'null'.");
}
- flag.append(variables.get(variableName));
+ stringBuilder.append(variables.get(variableName));
}
}
/**
- * Parser for toolchain flags.
+ * Parser for toolchain string values.
*
- * <p>A flag contains a snippet of text supporting variable expansion. For example, a flag value
- * "-f %{var1}/%{var2}" will expand the values of the variables "var1" and "var2" in the
- * corresponding places in the string.
+ * <p>A string value contains a snippet of text supporting variable expansion. For example, a
+ * string value "-f %{var1}/%{var2}" will expand the values of the variables "var1" and "var2"
+ * in the corresponding places in the string.
*
- * <p>The {@code FlagParser} takes a flag string and parses it into a list of {@code FlagChunk}
- * objects, where each chunk represents either a snippet of text or a variable to be expanded. In
- * the above example, the resulting chunks would be ["-f ", var1, "/", var2].
+ * <p>The {@code StringValueParser} takes a string and parses it into a list of
+ * {@link StringChunk} objects, where each chunk represents either a snippet of text or a
+ * variable to be expanded. In the above example, the resulting chunks would be
+ * ["-f ", var1, "/", var2].
*
- * <p>In addition to the list of chunks, the {@code FlagParser} also provides the set of variables
- * necessary for the expansion of this flag via {@code getUsedVariables}.
+ * <p>In addition to the list of chunks, the {@link StringValueParser} also provides the set of
+ * variables necessary for the expansion of this flag via {@link #getUsedVariables}.
*
- * <p>To get a literal percent character, "%%" can be used in the flag text.
+ * <p>To get a literal percent character, "%%" can be used in the string.
*/
- private static class FlagParser {
-
- /**
- * The given flag value.
- */
+ private static class StringValueParser {
+
private final String value;
/**
@@ -168,30 +166,30 @@ public class CcToolchainFeatures implements Serializable {
*/
private int current = 0;
- private final ImmutableList.Builder<FlagChunk> chunks = ImmutableList.builder();
+ private final ImmutableList.Builder<StringChunk> chunks = ImmutableList.builder();
private final ImmutableSet.Builder<String> usedVariables = ImmutableSet.builder();
- private FlagParser(String value) throws InvalidConfigurationException {
+ private StringValueParser(String value) throws InvalidConfigurationException {
this.value = value;
parse();
}
/**
- * @return the parsed chunks for this flag.
+ * @return the parsed chunks for this string.
*/
- private ImmutableList<FlagChunk> getChunks() {
+ private ImmutableList<StringChunk> getChunks() {
return chunks.build();
}
/**
- * @return all variable names needed to expand this flag.
+ * @return all variable names needed to expand this string.
*/
private ImmutableSet<String> getUsedVariables() {
return usedVariables.build();
}
/**
- * Parses the flag.
+ * Parses the string.
*
* @throws InvalidConfigurationException if there is a parsing error.
*/
@@ -223,7 +221,7 @@ public class CcToolchainFeatures implements Serializable {
// We only parse string chunks starting with '%' if they also start with '%%'.
// In that case, we want to have a single '%' in the string, so we start at the second
// character.
- // Note that for flags like "abc%%def" this will lead to two string chunks, the first
+ // Note that for strings like "abc%%def" this will lead to two string chunks, the first
// referencing the subtring "abc", and a second referencing the substring "%def".
if (value.charAt(current) == '%') {
current = current + 1;
@@ -234,7 +232,7 @@ public class CcToolchainFeatures implements Serializable {
current = value.length();
}
final String text = value.substring(start, current);
- chunks.add(new StringChunk(text));
+ chunks.add(new StringLiteralChunk(text));
}
/**
@@ -260,7 +258,7 @@ public class CcToolchainFeatures implements Serializable {
/**
* @throws InvalidConfigurationException with the given error text, adding information about
- * the current position in the flag.
+ * the current position in the string.
*/
private void abort(String error) throws InvalidConfigurationException {
throw new InvalidConfigurationException("Invalid toolchain configuration: " + error
@@ -297,9 +295,9 @@ public class CcToolchainFeatures implements Serializable {
*/
@Immutable
private static class Flag implements Serializable, Expandable {
- private final ImmutableList<FlagChunk> chunks;
+ private final ImmutableList<StringChunk> chunks;
- private Flag(ImmutableList<FlagChunk> chunks) {
+ private Flag(ImmutableList<StringChunk> chunks) {
this.chunks = chunks;
}
@@ -309,7 +307,7 @@ public class CcToolchainFeatures implements Serializable {
@Override
public void expand(Variables.View view, List<String> commandLine) {
StringBuilder flag = new StringBuilder();
- for (FlagChunk chunk : chunks) {
+ for (StringChunk chunk : chunks) {
chunk.expand(view.getVariables(), flag);
}
commandLine.add(flag.toString());
@@ -323,6 +321,36 @@ public class CcToolchainFeatures implements Serializable {
}
/**
+ * A single environment key/value pair to be expanded under a set of variables.
+ */
+ @Immutable
+ private static class EnvEntry implements Serializable {
+ private final String key;
+ private final ImmutableList<StringChunk> valueChunks;
+ private final ImmutableSet<String> usedVariables;
+
+ private EnvEntry(CToolchain.EnvEntry envEntry) throws InvalidConfigurationException {
+ this.key = envEntry.getKey();
+ StringValueParser parser = new StringValueParser(envEntry.getValue());
+ this.valueChunks = parser.getChunks();
+ this.usedVariables = parser.getUsedVariables();
+ }
+
+ /**
+ * Adds the key/value pair this object represents to the given map of environment variables.
+ * The value of the entry is expanded with the given {@code variables}.
+ */
+ public void addEnvEntry(Variables variables, ImmutableMap.Builder<String, String> envBuilder) {
+ Variables.View view = variables.getView(usedVariables);
+ StringBuilder value = new StringBuilder();
+ for (StringChunk chunk : valueChunks) {
+ chunk.expand(view.getVariables(), value);
+ }
+ envBuilder.put(key, value.toString());
+ }
+ }
+
+ /**
* A group of flags.
*/
@Immutable
@@ -342,7 +370,7 @@ public class CcToolchainFeatures implements Serializable {
+ "and another flag_group.");
}
for (String flag : flags) {
- FlagParser parser = new FlagParser(flag);
+ StringValueParser parser = new StringValueParser(flag);
expandables.add(new Flag(parser.getChunks()));
usedVariables.addAll(parser.getUsedVariables());
}
@@ -425,20 +453,58 @@ public class CcToolchainFeatures implements Serializable {
}
/**
+ * Groups a set of environment variables to apply for certain actions.
+ */
+ @Immutable
+ private static class EnvSet implements Serializable {
+ private final ImmutableSet<String> actions;
+ private final ImmutableList<EnvEntry> envEntries;
+
+ private EnvSet(CToolchain.EnvSet envSet) throws InvalidConfigurationException {
+ this.actions = ImmutableSet.copyOf(envSet.getActionList());
+ ImmutableList.Builder<EnvEntry> builder = ImmutableList.builder();
+ for (CToolchain.EnvEntry envEntry : envSet.getEnvEntryList()) {
+ builder.add(new EnvEntry(envEntry));
+ }
+ this.envEntries = builder.build();
+ }
+
+ /**
+ * Adds the environment key/value pairs that apply to the given {@code action} to
+ * {@code envBuilder}.
+ */
+ private void expandEnvironment(String action, Variables variables,
+ ImmutableMap.Builder<String, String> envBuilder) {
+ if (!actions.contains(action)) {
+ return;
+ }
+ for (EnvEntry envEntry : envEntries) {
+ envEntry.addEnvEntry(variables, envBuilder);
+ }
+ }
+ }
+
+ /**
* Contains flags for a specific feature.
*/
@Immutable
private static class Feature implements Serializable {
private final String name;
private final ImmutableList<FlagSet> flagSets;
+ private final ImmutableList<EnvSet> envSets;
private Feature(CToolchain.Feature feature) throws InvalidConfigurationException {
this.name = feature.getName();
- ImmutableList.Builder<FlagSet> builder = ImmutableList.builder();
+ ImmutableList.Builder<FlagSet> flagSetBuilder = ImmutableList.builder();
for (CToolchain.FlagSet flagSet : feature.getFlagSetList()) {
- builder.add(new FlagSet(flagSet));
+ flagSetBuilder.add(new FlagSet(flagSet));
+ }
+ this.flagSets = flagSetBuilder.build();
+ ImmutableList.Builder<EnvSet> envSetBuilder = ImmutableList.builder();
+ for (CToolchain.EnvSet flagSet : feature.getEnvSetList()) {
+ envSetBuilder.add(new EnvSet(flagSet));
}
- this.flagSets = builder.build();
+ this.envSets = envSetBuilder.build();
}
/**
@@ -448,6 +514,13 @@ public class CcToolchainFeatures implements Serializable {
return name;
}
+ private void expandEnvironment(String action, Variables variables,
+ ImmutableMap.Builder<String, String> envBuilder) {
+ for (EnvSet envSet : envSets) {
+ envSet.expandEnvironment(action, variables, envBuilder);
+ }
+ }
+
/**
* Adds the flags that apply to the given {@code action} to {@code commandLine}.
*/
@@ -793,6 +866,17 @@ public class CcToolchainFeatures implements Serializable {
}
return commandLine;
}
+
+ /**
+ * @return the environment variables (key/value pairs) for the given {@code action}.
+ */
+ Map<String, String> getEnvironmentVariables(String action, Variables variables) {
+ ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.builder();
+ for (Feature feature : enabledFeatures) {
+ feature.expandEnvironment(action, variables, envBuilder);
+ }
+ return envBuilder.build();
+ }
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index f23a921c30..6faa64a728 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -610,6 +610,8 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
environment.putAll(appleConfiguration.appleTargetPlatformEnv(
Platform.forTargetCpu(cppConfiguration.getTargetCpu())));
}
+
+ environment.putAll(cppCompileCommandLine.getEnvironment());
// TODO(bazel-team): Check (crosstool) host system name instead of using OS.getCurrent.
if (OS.getCurrent() == OS.WINDOWS) {
@@ -1259,6 +1261,13 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
this.fdoBuildStamp = fdoBuildStamp;
}
+ /**
+ * Returns the environment variables that should be set for C++ compile actions.
+ */
+ protected Map<String, String> getEnvironment() {
+ return featureConfiguration.getEnvironmentVariables(getActionName(), variables);
+ }
+
protected List<String> getArgv(PathFragment outputFile) {
List<String> commandLine = new ArrayList<>();