aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar hlopko <hlopko@google.com>2017-05-26 11:37:28 +0200
committerGravatar Irina Iancu <elenairina@google.com>2017-05-26 13:25:58 +0200
commita47780541536764cf56d09f78a988d6155689c7f (patch)
tree3ec1afd6b557ac27a6bd827fcdcee51865fef69f /src
parent1fd27bc4d97533031401c54aa05eb75b13c6874b (diff)
Use FeatureConfiguration to compute value of CC_FLAGS make variable
This cl introduces new action_config type for Crosstool named 'generic'. This can be used to set the value of CC_FLAGS make variable using much more expressive mechanism (action_configs + features) than previous make_variable Crosstool messages. This has been requested by the C++ LPT. However, as FeatureConfiguration needs RuleContext, CC_FLAGS cannot be computed using configuration only anymore. Also, FeatureConfiguration is C++ rules specific class, and Bazel build-base cannot depend on it. Therefore we cannot use FeatureConfiguration for ExtraActions, for example. Because it cannot be made perfect, this cl is not updating all the possible places that expand make variables but limits the scope to: * genrule (the only widely used rule that often expands make variables) * *_test (CC_FLAGS is used by Tensorflow in the 'args' attribute) * cc_rules (people sometimes set 'copts' to something like: "-DCC_STRING=\\\"$(CC)\\\" -DCC_FLAGS_STRING=\"$(CC_FLAGS)\"" The long term plan is to use Skylark C++ API to get C++ command lines, so CC_FLAGS together with this inconsistent solution will be removed. RELNOTES: CC_FLAGS can be defined using 'generic' action_config in CROSSTOOL PiperOrigin-RevId: 157202883
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java84
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/MakeVariableSupplier.java78
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java140
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java70
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Package.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java63
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java34
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/python/PyBinary.java11
-rw-r--r--src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleCommandSubstitutionTest.java31
16 files changed, 447 insertions, 117 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java
index dc830e89fe..2a17ddf838 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationMakeVariableContext.java
@@ -17,23 +17,23 @@ package com.google.devtools.build.lib.analysis;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.MakeVariableExpander.ExpansionException;
+import com.google.devtools.build.lib.analysis.MakeVariableSupplier.MapBackedMakeVariableSupplier;
+import com.google.devtools.build.lib.analysis.MakeVariableSupplier.PackageBackedMakeVariableSupplier;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.syntax.SkylarkDict;
+import com.google.devtools.build.lib.util.Preconditions;
import java.util.LinkedHashMap;
import java.util.Map;
/**
- * Implements make variable expansion for make variables that depend on the
- * configuration and the target (not on behavior of the
- * {@link ConfiguredTarget} implementation)
+ * Implements make variable expansion for make variables that depend on the configuration and the
+ * target (not on behavior of the {@link ConfiguredTarget} implementation). Retrieved Make variable
+ * value can be modified using {@link MakeVariableSupplier}
*/
public class ConfigurationMakeVariableContext implements MakeVariableExpander.Context {
- private final Package pkg;
- private final ImmutableMap<String, String> ruleEnv;
- private final ImmutableMap<String, String> commandLineEnv;
- private final ImmutableMap<String, String> globalEnv;
- private final String platform;
+
+ private final ImmutableList<? extends MakeVariableSupplier> allMakeVariableSuppliers;
// TODO(b/37567440): Remove when Skylark callers can be updated to get this from
// CcToolchainProvider. We should use CcCommon.CC_TOOLCHAIN_ATTRIBUTE_NAME, but we didn't want to
@@ -43,47 +43,65 @@ public class ConfigurationMakeVariableContext implements MakeVariableExpander.Co
public ConfigurationMakeVariableContext(
RuleContext ruleContext, Package pkg, BuildConfiguration configuration) {
- this(ruleContext.getMakeVariables(defaultMakeVariableAttributes), pkg, configuration);
+ this(
+ ruleContext.getMakeVariables(defaultMakeVariableAttributes),
+ pkg,
+ configuration,
+ ImmutableList.<MakeVariableSupplier>of());
}
public ConfigurationMakeVariableContext(
ImmutableMap<String, String> ruleMakeVariables,
Package pkg,
BuildConfiguration configuration) {
- this.pkg = pkg;
- this.ruleEnv = ruleMakeVariables;
- this.commandLineEnv = ImmutableMap.copyOf(configuration.getCommandLineBuildVariables());
- this.globalEnv = ImmutableMap.copyOf(configuration.getGlobalMakeEnvironment());
- this.platform = configuration.getPlatformName();
+ this(ruleMakeVariables, pkg, configuration, ImmutableList.<MakeVariableSupplier>of());
+ }
+
+ public ConfigurationMakeVariableContext(
+ RuleContext ruleContext,
+ Package pkg,
+ BuildConfiguration configuration,
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
+ this(
+ ruleContext.getMakeVariables(defaultMakeVariableAttributes),
+ pkg,
+ configuration,
+ makeVariableSuppliers);
+ }
+
+ public ConfigurationMakeVariableContext(
+ ImmutableMap<String, String> ruleMakeVariables,
+ Package pkg,
+ BuildConfiguration configuration,
+ Iterable<? extends MakeVariableSupplier> extraMakeVariableSuppliers) {
+ this.allMakeVariableSuppliers =
+ ImmutableList.<MakeVariableSupplier>builder()
+ .addAll(Preconditions.checkNotNull(extraMakeVariableSuppliers))
+ .add(new MapBackedMakeVariableSupplier(ruleMakeVariables))
+ .add(new MapBackedMakeVariableSupplier(configuration.getCommandLineBuildVariables()))
+ .add(new PackageBackedMakeVariableSupplier(pkg, configuration.getPlatformName()))
+ .add(new MapBackedMakeVariableSupplier(configuration.getGlobalMakeEnvironment()))
+ .build();
}
@Override
- public String lookupMakeVariable(String var) throws ExpansionException {
- String value = ruleEnv.get(var);
- if (value == null) {
- value = commandLineEnv.get(var);
- }
- if (value == null) {
- value = pkg.lookupMakeVariable(var, platform);
- }
- if (value == null) {
- value = globalEnv.get(var);
+ public String lookupMakeVariable(String variableName) throws ExpansionException {
+ for (MakeVariableSupplier supplier : allMakeVariableSuppliers) {
+ String variableValue = supplier.getMakeVariable(variableName);
+ if (variableValue != null) {
+ return variableValue;
+ }
}
- if (value == null) {
- throw new MakeVariableExpander.ExpansionException("$(" + var + ") not defined");
- }
-
- return value;
+ throw new MakeVariableExpander.ExpansionException("$(" + variableName + ") not defined");
}
public SkylarkDict<String, String> collectMakeVariables() {
Map<String, String> map = new LinkedHashMap<>();
// Collect variables in the reverse order as in lookupMakeVariable
// because each update is overwriting.
- map.putAll(pkg.getAllMakeVariables(platform));
- map.putAll(globalEnv);
- map.putAll(commandLineEnv);
- map.putAll(ruleEnv);
+ for (MakeVariableSupplier supplier : allMakeVariableSuppliers.reverse()) {
+ map.putAll(supplier.getAllMakeVariables());
+ }
return SkylarkDict.<String, String>copyOf(null, map);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/MakeVariableSupplier.java b/src/main/java/com/google/devtools/build/lib/analysis/MakeVariableSupplier.java
new file mode 100644
index 0000000000..911456965b
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/MakeVariableSupplier.java
@@ -0,0 +1,78 @@
+// 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;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.util.Preconditions;
+import javax.annotation.Nullable;
+
+/**
+ * Instances of {@link MakeVariableSupplier} passed to {@link ConfigurationMakeVariableContext} will
+ * be called before getting value from {@link ConfigurationMakeVariableContext} itself.
+ */
+public interface MakeVariableSupplier {
+
+ /** Returns Make variable value or null if value is not supplied. */
+ @Nullable
+ String getMakeVariable(String variableName);
+
+ /** Returns all Make variables that it supplies */
+ ImmutableMap<String, String> getAllMakeVariables();
+
+ /** {@link MakeVariableSupplier} that reads variables it supplies from a map. */
+ class MapBackedMakeVariableSupplier implements MakeVariableSupplier {
+
+ private final ImmutableMap<String, String> makeVariables;
+
+ public MapBackedMakeVariableSupplier(ImmutableMap<String, String> makeVariables) {
+ this.makeVariables = Preconditions.checkNotNull(makeVariables);
+ }
+
+ @Nullable
+ @Override
+ public String getMakeVariable(String variableName) {
+ return makeVariables.get(variableName);
+ }
+
+ @Override
+ public ImmutableMap<String, String> getAllMakeVariables() {
+ return makeVariables;
+ }
+ }
+
+ /** {@link MakeVariableSupplier} that reads variables it supplies from a {@link Package} */
+ class PackageBackedMakeVariableSupplier implements MakeVariableSupplier {
+
+ private final String platform;
+ private final Package pkg;
+
+ public PackageBackedMakeVariableSupplier(Package pkg, String platform) {
+ this.pkg = pkg;
+ this.platform = platform;
+ }
+
+ @Nullable
+ @Override
+ public String getMakeVariable(String variableName) {
+ return pkg.lookupMakeVariable(variableName, platform);
+ }
+
+ @Override
+ public ImmutableMap<String, String> getAllMakeVariables() {
+ return pkg.getAllMakeVariables(platform);
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 170d323631..2077a88733 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -92,6 +92,7 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -942,17 +943,46 @@ public final class RuleContext extends TargetContext
* @return a list of strings containing the expanded and tokenized values for the attribute
*/
public ImmutableList<String> getTokenizedStringListAttr(String attributeName) {
- return getExpandedStringListAttr(attributeName, Tokenize.YES);
+ return getExpandedStringListAttr(attributeName, Tokenize.YES, Collections.EMPTY_LIST);
}
/**
- * Gets an attribute of type STRING_LIST expanding Make variables and $(location) tags,
- * and optionally tokenizes the result.
+ * Gets an attribute of type STRING_LIST expanding Make variables, $(location) tags into the
+ * dependency location (see {@link LocationExpander} for details) and tokenizes the result.
+ *
+ * @param attributeName the name of the attribute to process
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
+ * @return a list of strings containing the expanded and tokenized values for the attribute
+ */
+ public ImmutableList<String> getTokenizedStringListAttr(
+ String attributeName, Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
+ return getExpandedStringListAttr(attributeName, Tokenize.YES, makeVariableSuppliers);
+ }
+
+ /**
+ * Gets an attribute of type STRING_LIST expanding Make variables and $(location) tags, and
+ * optionally tokenizes the result. Doesn't register any {@link MakeVariableSupplier}.
*
* @param attributeName the name of the attribute to process
* @return a list of strings containing the processed values for the attribute
*/
public ImmutableList<String> getExpandedStringListAttr(String attributeName, Tokenize tokenize) {
+ return getExpandedStringListAttr(
+ attributeName, tokenize, ImmutableList.<MakeVariableSupplier>of());
+ }
+
+ /**
+ * Gets an attribute of type STRING_LIST expanding Make variables and $(location) tags, and
+ * optionally tokenizes the result.
+ *
+ * @param attributeName the name of the attribute to process
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
+ * @return a list of strings containing the processed values for the attribute
+ */
+ public ImmutableList<String> getExpandedStringListAttr(
+ String attributeName,
+ Tokenize tokenize,
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
if (!getRule().isAttrDefined(attributeName, Type.STRING_LIST)) {
// TODO(bazel-team): This should be an error.
return ImmutableList.of();
@@ -966,7 +996,7 @@ public final class RuleContext extends TargetContext
new LocationExpander(this, LocationExpander.Options.ALLOW_DATA);
for (String token : original) {
- expandValue(tokens, attributeName, token, locationExpander, tokenize);
+ expandValue(tokens, attributeName, token, locationExpander, tokenize, makeVariableSuppliers);
}
return ImmutableList.copyOf(tokens);
}
@@ -974,42 +1004,53 @@ public final class RuleContext extends TargetContext
/**
* Expands make variables in value and tokenizes the result into tokens.
*
- * <p>This methods should be called only during initialization.
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
+ * <p>This methods should be called only during initialization.
*/
- public void tokenizeAndExpandMakeVars(List<String> tokens, String attributeName, String value) {
+ public void tokenizeAndExpandMakeVars(
+ List<String> tokens,
+ String attributeName,
+ String value,
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
LocationExpander locationExpander =
new LocationExpander(this, Options.ALLOW_DATA, Options.EXEC_PATHS);
- tokenizeAndExpandMakeVars(tokens, attributeName, value, locationExpander);
+ tokenizeAndExpandMakeVars(
+ tokens, attributeName, value, locationExpander, makeVariableSuppliers);
}
/**
* Expands make variables and $(location) tags in value and tokenizes the result into tokens.
*
- * <p>This methods should be called only during initialization.
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
+ * <p>This methods should be called only during initialization.
*/
public void tokenizeAndExpandMakeVars(
List<String> tokens,
String attributeName,
String value,
- @Nullable LocationExpander locationExpander) {
- expandValue(tokens, attributeName, value, locationExpander, Tokenize.YES);
+ @Nullable LocationExpander locationExpander,
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
+ expandValue(
+ tokens, attributeName, value, locationExpander, Tokenize.YES, makeVariableSuppliers);
}
/**
* Expands make variables and $(location) tags in value, and optionally tokenizes the result.
*
- * <p>This methods should be called only during initialization.
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
+ * <p>This methods should be called only during initialization.
*/
public void expandValue(
List<String> tokens,
String attributeName,
String value,
@Nullable LocationExpander locationExpander,
- Tokenize tokenize) {
+ Tokenize tokenize,
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
if (locationExpander != null) {
value = locationExpander.expandAttribute(attributeName, value);
}
- value = expandMakeVariables(attributeName, value);
+ value = expandMakeVariables(attributeName, value, makeVariableSuppliers);
if (tokenize == Tokenize.YES) {
try {
ShellUtils.tokenize(tokens, value);
@@ -1046,30 +1087,64 @@ public final class RuleContext extends TargetContext
}
/**
- * Return a context that maps Make variable names (string) to values (string).
+ * Returns a (cached! read on) context that maps Make variable names (string) to values (string)
+ * without any extra {@link MakeVariableSupplier}.
+ *
+ * <p>Beware!!! {@link ConfigurationMakeVariableContext} instance is cached, so if you call it
+ * first with some list of {@link MakeVariableSupplier} and then with other list, you will always
+ * get the first instance back. TODO(hlopko): Extract Make variable expansion from RuleContext and
+ * fix all the callers
*
* @return a ConfigurationMakeVariableContext.
- **/
+ */
public ConfigurationMakeVariableContext getConfigurationMakeVariableContext() {
+ return getConfigurationMakeVariableContext(ImmutableList.<MakeVariableSupplier>of());
+ }
+
+ /**
+ * Returns a (cached! read on) context that maps Make variable names (string) to values (string).
+ *
+ * @see #getConfigurationMakeVariableContext() to understand how the instance is cached!
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
+ * @return a ConfigurationMakeVariableContext.
+ */
+ public ConfigurationMakeVariableContext getConfigurationMakeVariableContext(
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
if (configurationMakeVariableContext == null) {
configurationMakeVariableContext =
- new ConfigurationMakeVariableContext(this, getRule().getPackage(), getConfiguration());
+ new ConfigurationMakeVariableContext(
+ this, getRule().getPackage(), getConfiguration(), makeVariableSuppliers);
}
return configurationMakeVariableContext;
}
/**
- * Returns the string "expression" after expanding all embedded references to
- * "Make" variables. If any errors are encountered, they are reported, and
- * "expression" is returned unchanged.
+ * Return a context that maps Make variable names (string) to values (string).
*
- * @param attributeName the name of the attribute from which "expression" comes;
- * used for error reporting.
+ * <p>Uses {@NoopExpansionInterceptor}.
+ *
+ * @return a ConfigurationMakeVariableContext.
+ */
+ public String expandMakeVariables(String attributeName, String expression) {
+ return expandMakeVariables(attributeName, expression, ImmutableList.<MakeVariableSupplier>of());
+ }
+
+ /**
+ * Returns the string "expression" after expanding all embedded references to "Make" variables. If
+ * any errors are encountered, they are reported, and "expression" is returned unchanged.
+ *
+ * @param attributeName the name of the attribute from which "expression" comes; used for error
+ * reporting.
* @param expression the string to expand.
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
* @return the expansion of "expression".
*/
- public String expandMakeVariables(String attributeName, String expression) {
- return expandMakeVariables(attributeName, expression, getConfigurationMakeVariableContext());
+ public String expandMakeVariables(
+ String attributeName,
+ String expression,
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
+ return expandMakeVariables(
+ attributeName, expression, getConfigurationMakeVariableContext(makeVariableSuppliers));
}
/**
@@ -1100,24 +1175,29 @@ public final class RuleContext extends TargetContext
public List<String> expandedMakeVariablesList(String attrName) {
List<String> variables = new ArrayList<>();
for (String variable : attributes().get(attrName, Type.STRING_LIST)) {
- variables.add(expandMakeVariables(attrName, variable));
+ variables.add(
+ expandMakeVariables(attrName, variable, ImmutableList.<MakeVariableSupplier>of()));
}
return variables;
}
/**
- * If the string consists of a single variable, returns the expansion of
- * that variable. Otherwise, returns null. Syntax errors are reported.
+ * If the string consists of a single variable, returns the expansion of that variable. Otherwise,
+ * returns null. Syntax errors are reported.
*
- * @param attrName the name of the attribute from which "expression" comes;
- * used for error reporting.
+ * @param attrName the name of the attribute from which "expression" comes; used for error
+ * reporting.
* @param expression the string to expand.
+ * @param makeVariableSuppliers to be used with {@link ConfigurationMakeVariableContext}
* @return the expansion of "expression", or null.
*/
- public String expandSingleMakeVariable(String attrName, String expression) {
+ public String expandSingleMakeVariable(
+ String attrName,
+ String expression,
+ ImmutableList<? extends MakeVariableSupplier> makeVariableSuppliers) {
try {
return MakeVariableExpander.expandSingleVariable(
- expression, getConfigurationMakeVariableContext());
+ expression, getConfigurationMakeVariableContext(makeVariableSuppliers));
} catch (MakeVariableExpander.ExpansionException e) {
attributeError(attrName, e.getMessage());
return expression;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
index 3b9792cbcf..a7331ccd06 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
@@ -21,7 +21,6 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.SourceManifestAction.ManifestType;
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.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.SymlinkTreeAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.RunUnder;
@@ -87,13 +86,12 @@ public final class RunfilesSupport {
* @param executable the executable for whose runfiles this runfiles support is responsible, may
* be null
* @param runfiles the runfiles
- * @param appendingArgs to be added after the rule's args
*/
private RunfilesSupport(
RuleContext ruleContext,
Artifact executable,
Runfiles runfiles,
- CommandLine appendingArgs,
+ CommandLine args,
boolean createSymlinks) {
owningExecutable = Preconditions.checkNotNull(executable);
this.createSymlinks = createSymlinks;
@@ -127,8 +125,7 @@ public final class RunfilesSupport {
ruleContext, artifactsMiddleman, runfilesManifest);
sourcesManifest = createSourceManifest(ruleContext, runfiles);
- ImmutableList<String> args = ruleContext.getTokenizedStringListAttr("args");
- this.args = CommandLine.concat(args, appendingArgs);
+ this.args = args;
}
/**
@@ -323,7 +320,7 @@ public final class RunfilesSupport {
}
/**
- * Creates an Artifact which writes the "sources only" manifest file.
+ * Creates an {@link Artifact} which writes the "sources only" manifest file.
*
* @param context the owner for the manifest action
* @param runfiles the runfiles
@@ -366,44 +363,51 @@ public final class RunfilesSupport {
}
/**
- * Creates and returns a RunfilesSupport object for the given rule and executable. Note that this
- * method calls back into the passed in rule to obtain the runfiles.
+ * Creates and returns a {@link RunfilesSupport} object for the given rule and executable. Note
+ * that this method calls back into the passed in rule to obtain the runfiles.
*/
- public static RunfilesSupport withExecutable(RuleContext ruleContext, Runfiles runfiles,
- Artifact executable) {
+ public static RunfilesSupport withExecutable(
+ RuleContext ruleContext, Runfiles runfiles, Artifact executable) {
return new RunfilesSupport(
ruleContext,
executable,
runfiles,
- CommandLine.EMPTY,
+ computeArgs(ruleContext, CommandLine.EMPTY, ImmutableList.<MakeVariableSupplier>of()),
ruleContext.shouldCreateRunfilesSymlinks());
}
/**
- * Creates and returns a RunfilesSupport object for the given rule and executable. Note that this
- * method calls back into the passed in rule to obtain the runfiles.
+ * Creates and returns a {@link RunfilesSupport} object for the given rule and executable. Note
+ * that this method calls back into the passed in rule to obtain the runfiles.
*/
- public static RunfilesSupport withExecutable(RuleContext ruleContext, Runfiles runfiles,
- Artifact executable, boolean createSymlinks) {
+ public static RunfilesSupport withExecutable(
+ RuleContext ruleContext, Runfiles runfiles, Artifact executable, boolean createSymlinks) {
return new RunfilesSupport(
- ruleContext, executable, runfiles, CommandLine.EMPTY, createSymlinks);
+ ruleContext,
+ executable,
+ runfiles,
+ computeArgs(ruleContext, CommandLine.EMPTY, ImmutableList.<MakeVariableSupplier>of()),
+ createSymlinks);
}
/**
- * Creates and returns a RunfilesSupport object for the given rule, executable, runfiles and args.
+ * Creates and returns a {@link RunfilesSupport} object for the given rule and executable. Note
+ * that this method calls back into the passed in rule to obtain the runfiles.
*/
- public static RunfilesSupport withExecutable(RuleContext ruleContext, Runfiles runfiles,
- Artifact executable, List<String> appendingArgs) {
+ public static RunfilesSupport withExecutable(
+ RuleContext ruleContext, Runfiles runfiles, Artifact executable, List<String> appendingArgs) {
return new RunfilesSupport(
ruleContext,
executable,
runfiles,
- CustomCommandLine.builder().add(appendingArgs).build(),
+ computeArgs(
+ ruleContext, CommandLine.of(appendingArgs), ImmutableList.<MakeVariableSupplier>of()),
ruleContext.shouldCreateRunfilesSymlinks());
}
/**
- * Creates and returns a RunfilesSupport object for the given rule, executable, runfiles and args.
+ * Creates and returns a {@link RunfilesSupport} object for the given rule, executable, runfiles
+ * and args.
*/
public static RunfilesSupport withExecutable(
RuleContext ruleContext, Runfiles runfiles, Artifact executable, CommandLine appendingArgs) {
@@ -411,7 +415,29 @@ public final class RunfilesSupport {
ruleContext,
executable,
runfiles,
- appendingArgs,
+ computeArgs(ruleContext, appendingArgs, ImmutableList.<MakeVariableSupplier>of()),
ruleContext.shouldCreateRunfilesSymlinks());
}
+
+ public static RunfilesSupport withExecutable(
+ RuleContext ruleContext,
+ Runfiles runfiles,
+ Artifact executable,
+ boolean createSymlinks,
+ ImmutableList<? extends MakeVariableSupplier> makeVariableSuppliers) {
+ return new RunfilesSupport(
+ ruleContext,
+ executable,
+ runfiles,
+ computeArgs(ruleContext, CommandLine.EMPTY, makeVariableSuppliers),
+ createSymlinks);
+ }
+
+ private static CommandLine computeArgs(
+ RuleContext ruleContext,
+ CommandLine additionalArgs,
+ ImmutableList<? extends MakeVariableSupplier> makeVariableSuppliers) {
+ return CommandLine.concat(
+ ruleContext.getTokenizedStringListAttr("args", makeVariableSuppliers), additionalArgs);
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 1098e2aa81..44bcbc7857 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -2356,14 +2356,14 @@ public final class BuildConfiguration implements BuildEvent {
* (Fragments, in particular the Google C++ support, can set variables through the
* command line.)
*/
- public Map<String, String> getCommandLineBuildVariables() {
+ public ImmutableMap<String, String> getCommandLineBuildVariables() {
return commandLineBuildVariables;
}
/**
* Returns the global defaults for this configuration for the Make environment.
*/
- public Map<String, String> getGlobalMakeEnvironment() {
+ public ImmutableMap<String, String> getGlobalMakeEnvironment() {
return globalMakeEnv;
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index 3e0ec37f1e..55f39fdd46 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -390,7 +390,7 @@ public class Package {
/**
* Returns all make variables for a given platform.
*/
- public Map<String, String> getAllMakeVariables(String platform) {
+ public ImmutableMap<String, String> getAllMakeVariables(String platform) {
ImmutableMap.Builder<String, String> map = ImmutableMap.builder();
for (String var : makeEnv.getBindings().keySet()) {
String value = makeEnv.lookup(var, platform);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
index acd7e31332..565da4d942 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
@@ -1010,11 +1010,11 @@ public final class SkylarkRuleContext implements SkylarkValue {
new ConfigurationMakeVariableContext(
ruleContext, ruleContext.getRule().getPackage(), ruleContext.getConfiguration()) {
@Override
- public String lookupMakeVariable(String name) throws ExpansionException {
- if (additionalSubstitutions.containsKey(name)) {
- return additionalSubstitutions.get(name);
+ public String lookupMakeVariable(String variableName) throws ExpansionException {
+ if (additionalSubstitutions.containsKey(variableName)) {
+ return additionalSubstitutions.get(variableName);
} else {
- return super.lookupMakeVariable(name);
+ return super.lookupMakeVariable(variableName);
}
}
});
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
index f5de614815..505d8e33b0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
@@ -13,7 +13,10 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.cpp;
+import com.google.common.base.Joiner;
+import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
@@ -21,6 +24,7 @@ import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.FileProvider;
+import com.google.devtools.build.lib.analysis.MakeVariableSupplier;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
@@ -32,6 +36,7 @@ import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.rules.apple.Platform;
import com.google.devtools.build.lib.rules.cpp.CcLibraryHelper.SourceCategory;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
+import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.DynamicMode;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.HeadersCheckingMode;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
@@ -50,6 +55,7 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+import javax.annotation.Nullable;
/**
* Common parts of the implementation of cc rules.
@@ -89,6 +95,7 @@ public final class CcCommon {
CppRuleClasses.PIC,
CppRuleClasses.PER_OBJECT_DEBUG_INFO,
CppRuleClasses.PREPROCESSOR_DEFINES);
+ public static final String CC_TOOLCHAIN_DEFAULT_ATTRIBUTE_NAME = ":cc_toolchain";
/** C++ configuration */
private final CppConfiguration cppConfiguration;
@@ -304,6 +311,62 @@ public final class CcCommon {
return getHeaders(ruleContext);
}
+ /**
+ * Supply CC_FLAGS Make variable value computed from FeatureConfiguration. Appends them to
+ * original CC_FLAGS, so FeatureConfiguration can override legacy values.
+ */
+ public static class CcFlagsSupplier implements MakeVariableSupplier {
+
+ private final RuleContext ruleContext;
+
+ public CcFlagsSupplier(RuleContext ruleContext) {
+ this.ruleContext = Preconditions.checkNotNull(ruleContext);
+ }
+
+ @Override
+ @Nullable
+ public String getMakeVariable(String variableName) {
+ if (!variableName.equals(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME)) {
+ return null;
+ }
+
+ CcToolchainProvider toolchain =
+ CppHelper.getToolchainUsingDefaultCcToolchainAttribute(ruleContext);
+ FeatureConfiguration featureConfiguration =
+ CcCommon.configureFeatures(ruleContext, toolchain);
+ if (!featureConfiguration.actionIsConfigured(
+ CppCompileAction.CC_FLAGS_MAKE_VARIABLE_ACTION_NAME)) {
+ return null;
+ }
+
+ Variables buildVariables = new Variables.Builder()
+ .addAllStringVariables(toolchain.getBuildVariables())
+ .build();
+ String toolchainCcFlags =
+ Joiner.on(" ")
+ .join(
+ featureConfiguration.getCommandLine(
+ CppCompileAction.CC_FLAGS_MAKE_VARIABLE_ACTION_NAME, buildVariables));
+
+ ImmutableMap<String, String> currentMakeVariables =
+ ruleContext.getMakeVariables(ImmutableList.of(CC_TOOLCHAIN_DEFAULT_ATTRIBUTE_NAME));
+ Preconditions.checkArgument(
+ currentMakeVariables.containsKey(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME));
+
+ return FluentIterable.of(
+ currentMakeVariables.get(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME))
+ .append(toolchainCcFlags)
+ .join(Joiner.on(" "));
+ }
+
+ @Override
+ public ImmutableMap<String, String> getAllMakeVariables() {
+ return ImmutableMap.of(
+ CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME,
+ getMakeVariable(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME));
+ }
+ }
+
private static ImmutableList<String> getPackageCopts(RuleContext ruleContext) {
List<String> unexpanded = ruleContext.getRule().getPackage().getDefaultCopts();
return ImmutableList.copyOf(CppHelper.expandMakeVariables(ruleContext, "copts", unexpanded));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
index 4f540224ff..abb218d4d0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
@@ -101,6 +101,7 @@ public final class CcLibraryHelper {
CppFileTypes.ASSEMBLER,
CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR),
ImmutableSet.<String>of(
+ CppCompileAction.CC_FLAGS_MAKE_VARIABLE_ACTION_NAME,
CppCompileAction.C_COMPILE,
CppCompileAction.CPP_COMPILE,
CppCompileAction.CPP_HEADER_PARSING,
@@ -128,6 +129,7 @@ public final class CcLibraryHelper {
CppFileTypes.ASSEMBLER,
CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR),
ImmutableSet.<String>of(
+ CppCompileAction.CC_FLAGS_MAKE_VARIABLE_ACTION_NAME,
CppCompileAction.C_COMPILE,
CppCompileAction.CPP_COMPILE,
CppCompileAction.OBJC_COMPILE,
@@ -147,9 +149,9 @@ public final class CcLibraryHelper {
Link.LinkTargetType.EXECUTABLE.getActionName()));
private final FileTypeSet sourceTypeSet;
- private final Set<String> actionConfigSet;
+ private final ImmutableSet<String> actionConfigSet;
- private SourceCategory(FileTypeSet sourceTypeSet, Set<String> actionConfigSet) {
+ private SourceCategory(FileTypeSet sourceTypeSet, ImmutableSet<String> actionConfigSet) {
this.sourceTypeSet = sourceTypeSet;
this.actionConfigSet = actionConfigSet;
}
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 2d3231b177..ea3deb880e 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
@@ -464,9 +464,9 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
// Overwrite the CC_FLAGS variable to include sysroot, if it's available.
if (sysroot != null) {
String sysrootFlag = "--sysroot=" + sysroot;
- String ccFlags = makeVariables.get("CC_FLAGS");
+ String ccFlags = makeVariables.get(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME);
ccFlags = ccFlags.isEmpty() ? sysrootFlag : ccFlags + " " + sysrootFlag;
- makeVariables.put("CC_FLAGS", ccFlags);
+ makeVariables.put(CppConfiguration.CC_FLAGS_MAKE_VARIABLE_NAME, ccFlags);
}
return new MakeVariableProvider(ImmutableMap.copyOf(makeVariables));
}
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 5bc7e3647a..0fd33d0567 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
@@ -83,6 +83,7 @@ import javax.annotation.Nullable;
@ThreadCompatible
public class CppCompileAction extends AbstractAction
implements IncludeScannable, ExecutionInfoSpecifier, CommandAction {
+
/**
* Represents logic that determines if an artifact is a special input, meaning that it may require
* additional inputs when it is compiled or may not be available to other actions.
@@ -115,6 +116,10 @@ public class CppCompileAction extends AbstractAction
private static final int VALIDATION_DEBUG = 0; // 0==none, 1==warns/errors, 2==all
private static final boolean VALIDATION_DEBUG_WARN = VALIDATION_DEBUG >= 1;
+ /** A string constant used to compute CC_FLAGS make variable value */
+ public static final java.lang.String CC_FLAGS_MAKE_VARIABLE_ACTION_NAME =
+ "cc-flags-make-variable";
+
/**
* A string constant for the c compilation action.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index c9e148ca12..7fc17ec06f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -88,6 +88,9 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
*/
public static final String MAC_SYSTEM_NAME = "x86_64-apple-macosx";
+ /** String constant for CC_FLAGS make variable name */
+ public static final String CC_FLAGS_MAKE_VARIABLE_NAME = "CC_FLAGS";
+
/**
* An enumeration of all the tools that comprise a toolchain.
*/
@@ -576,7 +579,7 @@ public class CppConfiguration extends BuildConfiguration.Fragment {
// The following are to be used to allow some build rules to avoid the limits on stack frame
// sizes and variable-length arrays. Ensure that these are always set.
makeVariablesBuilder.put("STACK_FRAME_UNLIMITED", "");
- makeVariablesBuilder.put("CC_FLAGS", "");
+ makeVariablesBuilder.put(CC_FLAGS_MAKE_VARIABLE_NAME, "");
for (CrosstoolConfig.MakeVariable variable : toolchain.getMakeVariableList()) {
makeVariablesBuilder.put(variable.getName(), variable.getValue());
}
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 96ba0a6892..f1952e897d 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
@@ -24,6 +24,7 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MiddlemanFactory;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.FileProvider;
+import com.google.devtools.build.lib.analysis.MakeVariableSupplier;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
@@ -37,6 +38,7 @@ 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.packages.RuleErrorConsumer;
+import com.google.devtools.build.lib.rules.cpp.CcCommon.CcFlagsSupplier;
import com.google.devtools.build.lib.rules.cpp.CcLinkParams.Linkstamp;
import com.google.devtools.build.lib.rules.cpp.CppCompilationContext.Builder;
import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType;
@@ -136,17 +138,22 @@ public class CppHelper {
!ruleContext.getFeatures().contains("no_copts_tokenization");
List<String> tokens = new ArrayList<>();
+ ImmutableList<? extends MakeVariableSupplier> makeVariableSuppliers =
+ ImmutableList.of(new CcFlagsSupplier(ruleContext));
for (String token : input) {
try {
// Legacy behavior: tokenize all items.
if (tokenization) {
- ruleContext.tokenizeAndExpandMakeVars(tokens, attributeName, token);
+ ruleContext.tokenizeAndExpandMakeVars(
+ tokens, attributeName, token, makeVariableSuppliers);
} else {
- String exp = ruleContext.expandSingleMakeVariable(attributeName, token);
+ String exp =
+ ruleContext.expandSingleMakeVariable(attributeName, token, makeVariableSuppliers);
if (exp != null) {
ShellUtils.tokenize(tokens, exp);
} else {
- tokens.add(ruleContext.expandMakeVariables(attributeName, token));
+ tokens.add(
+ ruleContext.expandMakeVariables(attributeName, token, makeVariableSuppliers));
}
}
} catch (ShellUtils.TokenizationException e) {
@@ -178,7 +185,11 @@ public class CppHelper {
ruleContext.attributeError(attrName, "could not resolve label '" + attrValue + "'");
}
} else {
- ruleContext.tokenizeAndExpandMakeVars(values, attrName, attrValue);
+ ruleContext.tokenizeAndExpandMakeVars(
+ values,
+ attrName,
+ attrValue,
+ ImmutableList.of(new CcFlagsSupplier(ruleContext)));
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java
index 5f0432ac4a..f35627b6eb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java
@@ -27,6 +27,7 @@ import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.MakeVariableExpander.ExpansionException;
+import com.google.devtools.build.lib.analysis.MakeVariableSupplier;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
@@ -40,6 +41,7 @@ import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.rules.AliasProvider;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.cpp.CcCommon.CcFlagsSupplier;
import com.google.devtools.build.lib.rules.cpp.CcToolchain;
import com.google.devtools.build.lib.rules.cpp.CppHelper;
import com.google.devtools.build.lib.rules.java.JavaHelper;
@@ -56,7 +58,7 @@ import java.util.regex.Pattern;
public abstract class GenRuleBase implements RuleConfiguredTargetFactory {
private static final Pattern CROSSTOOL_MAKE_VARIABLE =
- Pattern.compile("\\$\\((CC|AR|NM|OBJCOPY|STRIP|GCOVTOOL|CC_FLAGS)\\)");
+ Pattern.compile("\\$\\((CC|CC_FLAGS|AR|NM|OBJCOPY|STRIP|GCOVTOOL)\\)");
private static final Pattern JDK_MAKE_VARIABLE =
Pattern.compile("\\$\\((JAVABASE|JAVA)\\)");
@@ -278,7 +280,11 @@ public abstract class GenRuleBase implements RuleConfiguredTargetFactory {
*/
protected CommandResolverContext createCommandResolverContext(RuleContext ruleContext,
NestedSet<Artifact> resolvedSrcs, NestedSet<Artifact> filesToBuild) {
- return new CommandResolverContext(ruleContext, resolvedSrcs, filesToBuild);
+ return new CommandResolverContext(
+ ruleContext,
+ resolvedSrcs,
+ filesToBuild,
+ ImmutableList.of(new CcFlagsSupplier(ruleContext)));
}
/**
@@ -297,11 +303,13 @@ public abstract class GenRuleBase implements RuleConfiguredTargetFactory {
public CommandResolverContext(
RuleContext ruleContext,
NestedSet<Artifact> resolvedSrcs,
- NestedSet<Artifact> filesToBuild) {
+ NestedSet<Artifact> filesToBuild,
+ Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
super(
ruleContext.getMakeVariables(makeVariableAttributes),
ruleContext.getRule().getPackage(),
- ruleContext.getConfiguration());
+ ruleContext.getConfiguration(),
+ makeVariableSuppliers);
this.ruleContext = ruleContext;
this.resolvedSrcs = resolvedSrcs;
this.filesToBuild = filesToBuild;
@@ -312,16 +320,16 @@ public abstract class GenRuleBase implements RuleConfiguredTargetFactory {
}
@Override
- public String lookupMakeVariable(String name) throws ExpansionException {
- if (name.equals("SRCS")) {
+ public String lookupMakeVariable(String variableName) throws ExpansionException {
+ if (variableName.equals("SRCS")) {
return Artifact.joinExecPaths(" ", resolvedSrcs);
- } else if (name.equals("<")) {
+ } else if (variableName.equals("<")) {
return expandSingletonArtifact(resolvedSrcs, "$<", "input file");
- } else if (name.equals("OUTS")) {
+ } else if (variableName.equals("OUTS")) {
return Artifact.joinExecPaths(" ", filesToBuild);
- } else if (name.equals("@")) {
+ } else if (variableName.equals("@")) {
return expandSingletonArtifact(filesToBuild, "$@", "output file");
- } else if (name.equals("@D")) {
+ } else if (variableName.equals("@D")) {
// The output directory. If there is only one filename in outs,
// this expands to the directory containing that file. If there are
// multiple filenames, this variable instead expands to the
@@ -348,14 +356,14 @@ public abstract class GenRuleBase implements RuleConfiguredTargetFactory {
ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot();
return dir.getRelative(relPath).getPathString();
}
- } else if (JDK_MAKE_VARIABLE.matcher("$(" + name + ")").find()) {
+ } else if (JDK_MAKE_VARIABLE.matcher("$(" + variableName + ")").find()) {
return new ConfigurationMakeVariableContext(
ruleContext.getMakeVariables(makeVariableAttributes),
ruleContext.getTarget().getPackage(),
ruleContext.getHostConfiguration())
- .lookupMakeVariable(name);
+ .lookupMakeVariable(variableName);
} else {
- return super.lookupMakeVariable(name);
+ return super.lookupMakeVariable(variableName);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyBinary.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyBinary.java
index 74fdc2fcd8..ab6df63379 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/python/PyBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyBinary.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.python;
+import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
@@ -23,6 +24,7 @@ import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.RunfilesSupport;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.cpp.CcCommon.CcFlagsSupplier;
import com.google.devtools.build.lib.rules.cpp.CcLinkParams;
import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
import com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore;
@@ -84,8 +86,13 @@ public abstract class PyBinary implements RuleConfiguredTargetFactory {
semantics.collectDefaultRunfilesForBinary(ruleContext, defaultRunfilesBuilder);
Runfiles defaultRunfiles = defaultRunfilesBuilder.build();
- RunfilesSupport runfilesSupport = RunfilesSupport.withExecutable(ruleContext, defaultRunfiles,
- common.getExecutable(), ruleContext.shouldCreateRunfilesSymlinks());
+ RunfilesSupport runfilesSupport =
+ RunfilesSupport.withExecutable(
+ ruleContext,
+ defaultRunfiles,
+ common.getExecutable(),
+ ruleContext.shouldCreateRunfilesSymlinks(),
+ ImmutableList.of(new CcFlagsSupplier(ruleContext)));
if (ruleContext.hasErrors()) {
return null;
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleCommandSubstitutionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleCommandSubstitutionTest.java
index a17c2ebb92..2d57b3a10a 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleCommandSubstitutionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/genrule/GenRuleCommandSubstitutionTest.java
@@ -14,10 +14,12 @@
package com.google.devtools.build.lib.bazel.rules.genrule;
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import com.google.common.base.Joiner;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -475,4 +477,31 @@ public class GenRuleCommandSubstitutionTest extends BuildViewTestCase {
" outs = ['out'],",
" cmd = '" + command + "')");
}
-}
+
+ @Test
+ public void testCcFlagsFromFeatureConfiguration() throws Exception {
+ AnalysisMock.get()
+ .ccSupport()
+ .setupCrosstool(
+ mockToolsConfig,
+ "action_config {",
+ " action_name: 'cc-flags-make-variable'",
+ " config_name: 'cc-flags-make-variable'",
+ " flag_set {",
+ " flag_group {",
+ " flag: 'foo'",
+ " flag: 'bar'",
+ " flag: 'baz'",
+ " }",
+ " }",
+ "}");
+ useConfiguration();
+ scratch.file(
+ "foo/BUILD",
+ "genrule(name = 'foo',",
+ " outs = ['out'],",
+ " cmd = '$(CC_FLAGS)')");
+ String command = getGenruleCommand("//foo");
+ assertThat(command).endsWith("foo bar baz");
+ }
+} \ No newline at end of file