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
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 dc830e8..2a17ddf 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 @@
 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 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);
+  public String lookupMakeVariable(String variableName) throws ExpansionException {
+    for (MakeVariableSupplier supplier : allMakeVariableSuppliers) {
+      String variableValue = supplier.getMakeVariable(variableName);
+      if (variableValue != null) {
+        return variableValue;
+      }
     }
-    if (value == null) {
-      value = pkg.lookupMakeVariable(var, platform);
-    }
-    if (value == null) {
-      value = globalEnv.get(var);
-    }
-    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 0000000..9114569
--- /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 170d323..2077a887 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.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 @@
    * @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 @@
         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 @@
   /**
    * Expands make variables in value and tokenizes the result into tokens.
    *
-   * <p>This methods should be called only during initialization.
-   */
-  public void tokenizeAndExpandMakeVars(List<String> tokens, String attributeName, String value) {
-    LocationExpander locationExpander =
-        new LocationExpander(this, Options.ALLOW_DATA, Options.EXEC_PATHS);
-    tokenizeAndExpandMakeVars(tokens, attributeName, value, locationExpander);
-  }
-
-  /**
-   * 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);
+      Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
+    LocationExpander locationExpander =
+        new LocationExpander(this, Options.ALLOW_DATA, Options.EXEC_PATHS);
+    tokenizeAndExpandMakeVars(
+        tokens, attributeName, value, locationExpander, makeVariableSuppliers);
+  }
+
+  /**
+   * Expands make variables and $(location) tags in value and tokenizes the result into tokens.
+   *
+   * @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,
+      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 @@
   }
 
   /**
-   * 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.
-   * @param expression the string to expand.
-   * @return the expansion of "expression".
+   * <p>Uses {@NoopExpansionInterceptor}.
+   *
+   * @return a ConfigurationMakeVariableContext.
    */
   public String expandMakeVariables(String attributeName, String expression) {
-    return expandMakeVariables(attributeName, expression, getConfigurationMakeVariableContext());
+    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,
+      Iterable<? extends MakeVariableSupplier> makeVariableSuppliers) {
+    return expandMakeVariables(
+        attributeName, expression, getConfigurationMakeVariableContext(makeVariableSuppliers));
   }
 
   /**
@@ -1100,24 +1175,29 @@
   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 3b9792c..a7331cc 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.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 @@
    * @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 @@
         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 @@
   }
 
   /**
-   * 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 @@
   }
 
   /**
-   * 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) {
-    return new RunfilesSupport(
-        ruleContext, executable, runfiles, CommandLine.EMPTY, createSymlinks);
-  }
-
-  /**
-   * Creates and returns a RunfilesSupport object for the given rule, executable, runfiles and args.
-   */
-  public static RunfilesSupport withExecutable(RuleContext ruleContext, Runfiles runfiles,
-      Artifact executable, List<String> appendingArgs) {
+  public static RunfilesSupport withExecutable(
+      RuleContext ruleContext, Runfiles runfiles, Artifact executable, boolean createSymlinks) {
     return new RunfilesSupport(
         ruleContext,
         executable,
         runfiles,
-        CustomCommandLine.builder().add(appendingArgs).build(),
+        computeArgs(ruleContext, CommandLine.EMPTY, ImmutableList.<MakeVariableSupplier>of()),
+        createSymlinks);
+  }
+
+  /**
+   * 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) {
+    return new RunfilesSupport(
+        ruleContext,
+        executable,
+        runfiles,
+        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 @@
         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 1098e2a..44bcbc7 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 @@
    * (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 3e0ec37..55f39fd 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 @@
   /**
    * 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 acd7e31..565da4d 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 @@
         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 f5de614..505d8e3 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.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.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.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 @@
           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 @@
     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 4f54022..abb218d 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 @@
             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 @@
             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 @@
             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 2d3231b..ea3deb8 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 @@
     // 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 5bc7e36..0fd33d0 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 @@
 @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 @@
   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 c9e148c..7fc17ec 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 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 @@
     // 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 96ba0a6..f1952e8 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.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.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 @@
         !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 @@
         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 5f0432a..f35627b 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.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.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 @@
 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 @@
    */
   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 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 @@
     }
 
     @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 @@
               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 74fdc2f..ab6df63 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.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 @@
     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;