Unconditionally include gcc's stdc-predef.h if it is available.

--
MOS_MIGRATED_REVID=89964638
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
index 5bf199d..1ad6f32 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
@@ -540,7 +540,7 @@
   }
 
   private void prepareToBuild(PackageRootResolver resolver) throws ViewCreationFailedException {
-    for (BuildConfiguration config : configurations.getTargetConfigurations()) {
+    for (BuildConfiguration config : configurations.getAllConfigurations()) {
       config.prepareToBuild(directories.getExecRoot(), getArtifactFactory(), resolver);
     }
   }
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 8789cad..530b759 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
@@ -152,8 +152,7 @@
      * The fragment may use this hook to perform I/O and read data into memory that is used during
      * analysis. During the analysis phase disk I/O operations are disallowed.
      *
-     * <p>This hook is only called for the top-level configuration after the loading phase is
-     * complete.
+     * <p>This hook is called for all configurations after the loading phase is complete.
      */
     @SuppressWarnings("unused")
     public void prepareHook(Path execPath, ArtifactFactory artifactFactory,
@@ -1873,6 +1872,9 @@
    * phase is generally not allowed to perform disk I/O. This code is here because it is
    * conceptually part of the analysis phase, and it needs to happen when the loading phase is
    * complete.
+   *
+   * <p>C++ also requires this to resolve artifacts that are unconditionally included in every
+   * compilation.</p>
    */
   public void prepareToBuild(Path execRoot, ArtifactFactory artifactFactory,
       PackageRootResolver resolver) throws ViewCreationFailedException {
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 c813931..a38ec41 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
@@ -297,6 +297,12 @@
     return cppConfiguration.getBuiltInIncludeDirectories();
   }
 
+  @Nullable
+  @Override
+  public Artifact getBuiltInIncludeFile() {
+    return cppConfiguration.getBuiltInIncludeFile();
+  }
+
   public String getHostSystemName() {
     return cppConfiguration.getHostSystemName();
   }
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 1fca0b4..b3cdf3b 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
@@ -26,6 +26,7 @@
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
+import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.ArtifactFactory;
 import com.google.devtools.build.lib.actions.PackageRootResolver;
 import com.google.devtools.build.lib.actions.Root;
@@ -69,6 +70,8 @@
 import java.util.Set;
 import java.util.zip.ZipException;
 
+import javax.annotation.Nullable;
+
 /**
  * This class represents the C/C++ parts of the {@link BuildConfiguration},
  * including the host architecture, target architecture, compiler version, and
@@ -190,6 +193,12 @@
   public static final String FDO_STAMP_MACRO = "BUILD_FDO_TYPE";
 
   /**
+   * This file (found under the sysroot) may be unconditionally included in every C/C++ compilation.
+   */
+  private static final PathFragment BUILT_IN_INCLUDE_PATH_FRAGMENT =
+      new PathFragment("include/stdc-predef.h");
+
+  /**
    * Represents an optional flag that can be toggled using the package features mechanism.
    */
   @VisibleForTesting
@@ -286,6 +295,7 @@
   private final PathFragment sysroot;
   private final PathFragment runtimeSysroot;
   private final List<PathFragment> builtInIncludeDirectories;
+  private Artifact builtInIncludeFile;
 
   private final Map<String, PathFragment> toolPaths;
   private final PathFragment ldExecutable;
@@ -1095,6 +1105,15 @@
   }
 
   /**
+   * Returns the built-in header automatically included by the toolchain compiler. All C++ files
+   * may implicitly include this file. May be null if {@link #getSysroot} is null.
+   */
+  @Nullable
+  public Artifact getBuiltInIncludeFile() {
+    return builtInIncludeFile;
+  }
+
+  /**
    * Returns the sysroot to be used. If the toolchain compiler does not support
    * different sysroots, or the sysroot is the same as the default sysroot, then
    * this method returns <code>null</code>.
@@ -1725,6 +1744,15 @@
   @Override
   public void prepareHook(Path execRoot, ArtifactFactory artifactFactory, PathFragment genfilesPath,
       PackageRootResolver resolver) throws ViewCreationFailedException {
+    // TODO(bazel-team): Remove the "relative" guard. sysroot should always be relative, and this
+    // should be enforced in the creation of CppConfiguration.
+    if (getSysroot() != null && !getSysroot().isAbsolute()) {
+      Root sysrootRoot = Iterables.getOnlyElement(
+          resolver.findPackageRoots(ImmutableList.of(getSysroot())).entrySet()).getValue();
+      builtInIncludeFile = Preconditions.checkNotNull(artifactFactory.getSourceArtifact(
+              sysroot.getRelative(BUILT_IN_INCLUDE_PATH_FRAGMENT), sysrootRoot),
+          "%s %s", sysrootRoot, sysroot);
+    }
     try {
       getFdoSupport().prepareToBuild(execRoot, genfilesPath, artifactFactory, resolver);
     } catch (ZipException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScannable.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScannable.java
index d1f89f9..472e69b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScannable.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScannable.java
@@ -22,6 +22,8 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.annotation.Nullable;
+
 /**
  * To be implemented by actions (such as C++ compilation steps) whose inputs
  * can be scanned to discover other implicit inputs (such as C++ header files).
@@ -68,6 +70,13 @@
   List<String> getCmdlineIncludes();
 
   /**
+   * Returns an artifact that the compiler may unconditionally include, even if the source file
+   * does not mention it.
+   */
+  @Nullable
+  Artifact getBuiltInIncludeFile();
+
+  /**
    * Returns the artifact relative to which the {@code getCmdlineIncludes()} should be interpreted. 
    */
   Artifact getMainIncludeScannerSource();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java
index 6929975..82afb5c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java
@@ -92,6 +92,10 @@
       Path execRoot = executor.getExecRoot();
 
       final List<Path> absoluteBuiltInIncludeDirs = new ArrayList<>();
+      Artifact builtInInclude = action.getBuiltInIncludeFile();
+      if (builtInInclude != null) {
+        includes.add(builtInInclude);
+      }
 
       Profiler profiler = Profiler.instance();
       try {