Make C++ autoconfigured toolchain the default for Linux and OS X.

This is done by adding a default workspace suffix.

--
MOS_MIGRATED_REVID=118656979
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
index 6c29411..aee043a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -83,7 +83,8 @@
    * Builder for {@link ConfiguredRuleClassProvider}.
    */
   public static class Builder implements RuleDefinitionEnvironment {
-    private final StringBuilder defaultWorkspaceFile = new StringBuilder();
+    private final StringBuilder defaultWorkspaceFilePrefix = new StringBuilder();
+    private final StringBuilder defaultWorkspaceFileSuffix = new StringBuilder();
     private Label preludeLabel;
     private String runfilesPrefix;
     private String toolsRepository;
@@ -109,8 +110,12 @@
         ImmutableList.<Class<?>>builder().addAll(SkylarkModules.MODULES);
     private final List<Class<? extends FragmentOptions>> buildOptions = Lists.newArrayList();
 
-    public void addWorkspaceFile(String contents) {
-      defaultWorkspaceFile.append(contents);
+    public void addWorkspaceFilePrefix(String contents) {
+      defaultWorkspaceFilePrefix.append(contents);
+    }
+
+    public void addWorkspaceFileSuffix(String contents) {
+      defaultWorkspaceFileSuffix.append(contents);
     }
 
     public Builder setPrelude(String preludeLabelString) {
@@ -264,7 +269,8 @@
           ImmutableMap.copyOf(ruleClassMap),
           ImmutableMap.copyOf(ruleDefinitionMap),
           ImmutableMap.copyOf(aspectFactoryMap),
-          defaultWorkspaceFile.toString(),
+          defaultWorkspaceFilePrefix.toString(),
+          defaultWorkspaceFileSuffix.toString(),
           ImmutableList.copyOf(buildInfoFactories),
           ImmutableList.copyOf(configurationOptions),
           ImmutableList.copyOf(configurationFragments),
@@ -304,10 +310,15 @@
   });
 
   /**
-   * A list of relative paths to the WORKSPACE files needed to provide external dependencies for
-   * the rule classes.
+   * Default content that should be added at the beginning of the WORKSPACE file.
    */
-  String defaultWorkspaceFile;
+  private final String defaultWorkspaceFilePrefix;
+
+  /**
+   * Default content that should be added at the end of the WORKSPACE file.
+   */
+  private final String defaultWorkspaceFileSuffix;
+
 
   /**
    * Label for the prelude file.
@@ -375,7 +386,8 @@
       ImmutableMap<String, RuleClass> ruleClassMap,
       ImmutableMap<String, Class<? extends RuleDefinition>> ruleDefinitionMap,
       ImmutableMap<String, Class<? extends NativeAspectFactory>> aspectFactoryMap,
-      String defaultWorkspaceFile,
+      String defaultWorkspaceFilePrefix,
+      String defaultWorkspaceFileSuffix,
       ImmutableList<BuildInfoFactory> buildInfoFactories,
       ImmutableList<Class<? extends FragmentOptions>> configurationOptions,
       ImmutableList<ConfigurationFragmentFactory> configurationFragments,
@@ -391,7 +403,8 @@
     this.ruleClassMap = ruleClassMap;
     this.ruleDefinitionMap = ruleDefinitionMap;
     this.aspectFactoryMap = aspectFactoryMap;
-    this.defaultWorkspaceFile = defaultWorkspaceFile;
+    this.defaultWorkspaceFilePrefix = defaultWorkspaceFilePrefix;
+    this.defaultWorkspaceFileSuffix = defaultWorkspaceFileSuffix;
     this.buildInfoFactories = buildInfoFactories;
     this.configurationOptions = configurationOptions;
     this.configurationFragments = configurationFragments;
@@ -540,9 +553,13 @@
         eventHandler, astFileContentHashCode, importMap);
   }
 
+  @Override
+  public String getDefaultWorkspacePrefix() {
+    return defaultWorkspaceFilePrefix;
+  }
 
   @Override
-  public String getDefaultWorkspaceFile() {
-    return defaultWorkspaceFile;
+  public String getDefaultWorkspaceSuffix() {
+    return defaultWorkspaceFileSuffix;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index a2592ea..1fa4f8f 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -297,13 +297,13 @@
     builder.addRuleDefinition(new BazelPyTestRule());
 
     try {
-      builder.addWorkspaceFile(
+      builder.addWorkspaceFilePrefix(
           ResourceFileLoader.loadResource(BazelRuleClassProvider.class, "tools.WORKSPACE"));
-      builder.addWorkspaceFile(
+      builder.addWorkspaceFilePrefix(
           ResourceFileLoader.loadResource(BazelJavaRuleClasses.class, "jdk.WORKSPACE"));
-      builder.addWorkspaceFile(
+      builder.addWorkspaceFilePrefix(
           ResourceFileLoader.loadResource(BazelAndroidSemantics.class, "android.WORKSPACE"));
-      builder.addWorkspaceFile(
+      builder.addWorkspaceFilePrefix(
           ResourceFileLoader.loadResource(BazelJ2ObjcLibraryRule.class, "j2objc.WORKSPACE"));
     } catch (IOException e) {
       throw new IllegalStateException(e);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
index 4327e67..2af2575 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
@@ -26,6 +26,7 @@
 import com.google.devtools.build.lib.actions.SimpleActionContextProvider;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
 import com.google.devtools.build.lib.analysis.actions.FileWriteActionContext;
+import com.google.devtools.build.lib.bazel.rules.cpp.BazelCppRuleClasses;
 import com.google.devtools.build.lib.query2.output.OutputFormatter;
 import com.google.devtools.build.lib.rules.android.WriteAdbArgsActionContext;
 import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext;
@@ -37,10 +38,12 @@
 import com.google.devtools.build.lib.runtime.CommandEnvironment;
 import com.google.devtools.build.lib.runtime.GotOptionsEvent;
 import com.google.devtools.build.lib.skyframe.PrecomputedValue;
+import com.google.devtools.build.lib.util.ResourceFileLoader;
 import com.google.devtools.common.options.Converters.AssignmentConverter;
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionsBase;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
@@ -170,6 +173,14 @@
   @Override
   public void initializeRuleClasses(ConfiguredRuleClassProvider.Builder builder) {
     BazelRuleClassProvider.setup(builder);
+    try {
+      // Load auto-configuration files, it is made outside of the rule class provider so that it
+      // will not be loaded for our Java tests.
+      builder.addWorkspaceFileSuffix(
+          ResourceFileLoader.loadResource(BazelCppRuleClasses.class, "cc_configure.WORKSPACE"));
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/cc_configure.WORKSPACE b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/cc_configure.WORKSPACE
new file mode 100644
index 0000000..70ef8f7
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/cc_configure.WORKSPACE
@@ -0,0 +1,2 @@
+load("@bazel_tools//tools/cpp:cc_configure.bzl", "cc_configure")
+cc_configure()
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
index 2f0988f..7a3566a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
@@ -69,13 +69,21 @@
   Map<String, Class<? extends NativeAspectFactory>> getAspectFactoryMap();
 
   /**
-   * Returns the default content of the WORKSPACE file.
+   * Returns the default content that should be added at the beginning of the WORKSPACE file.
    *
    * <p>Used to provide external dependencies for built-in rules. Rules defined here can be
    * overwritten in the WORKSPACE file in the actual workspace.
    */
-  String getDefaultWorkspaceFile();
-  
+  String getDefaultWorkspacePrefix();
+
+
+  /**
+   * Returns the default content that should be added at the end of the WORKSPACE file.
+   *
+   * <p>Used to load skylark repository in the bazel_tools repository.
+   */
+  String getDefaultWorkspaceSuffix();
+
   /**
    * Returns the path to the tools repository
    */
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
index 46f5d0d..d101139 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
@@ -52,10 +52,10 @@
     }
 
     Path repoWorkspace = workspaceRoot.getRoot().getRelative(workspaceRoot.getRelativePath());
-    PathFragment pathFragment = new PathFragment("/DEFAULT.WORKSPACE");
     try {
       BuildFileAST ast = BuildFileAST.parseBuildFile(
-          ParserInputSource.create(ruleClassProvider.getDefaultWorkspaceFile(), pathFragment),
+          ParserInputSource.create(ruleClassProvider.getDefaultWorkspacePrefix(),
+              new PathFragment("/DEFAULT.WORKSPACE")),
           env.getListener(), false);
       if (ast.containsErrors()) {
         throw new WorkspaceASTFunctionException(
@@ -69,6 +69,17 @@
               new IOException("Failed to parse WORKSPACE file"), Transience.PERSISTENT);
         }
       }
+      ast = BuildFileAST.parseBuildFile(
+          ParserInputSource.create(ruleClassProvider.getDefaultWorkspaceSuffix(),
+              new PathFragment("/DEFAULT.WORKSPACE.SUFFIX")),
+          ast.getStatements(),
+          env.getListener(),
+          false);
+      if (ast.containsErrors()) {
+        throw new WorkspaceASTFunctionException(
+            new IOException("Failed to parse default WORKSPACE file suffix"),
+            Transience.PERSISTENT);
+      }
       return new WorkspaceASTValue(splitAST(ast));
     } catch (IOException ex) {
       throw new WorkspaceASTFunctionException(ex, Transience.TRANSIENT);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java
index 784c3e0..4d61274 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunctionTest.java
@@ -52,7 +52,8 @@
     ConfiguredRuleClassProvider ruleClassProvider = TestRuleClassProvider.getRuleClassProvider();
     ConfiguredRuleClassProvider ruleClassProviderSpy = Mockito.spy(ruleClassProvider);
     // Prevent returning default workspace file.
-    Mockito.when(ruleClassProviderSpy.getDefaultWorkspaceFile()).thenReturn("");
+    Mockito.when(ruleClassProviderSpy.getDefaultWorkspacePrefix()).thenReturn("");
+    Mockito.when(ruleClassProviderSpy.getDefaultWorkspaceSuffix()).thenReturn("");
     astSkyFunc = new WorkspaceASTFunction(ruleClassProviderSpy);
     fakeWorkspaceFileValue = new FakeFileValue();
   }
diff --git a/src/test/shell/bazel/external_correctness_test.sh b/src/test/shell/bazel/external_correctness_test.sh
index bb84579..4a70e16 100755
--- a/src/test/shell/bazel/external_correctness_test.sh
+++ b/src/test/shell/bazel/external_correctness_test.sh
@@ -140,7 +140,7 @@
 )
 EOF
   bazel build @a//b/c:echo-d &> $TEST_log || fail "Build failed"
-  assert_contains "bazel-out/local_.*-fastbuild/genfiles/external/a/b/c" \
+  assert_contains "bazel-out/local.*-fastbuild/genfiles/external/a/b/c" \
     "bazel-genfiles/external/a/b/c/d"
 }
 
diff --git a/src/test/shell/integration/testenv.sh b/src/test/shell/integration/testenv.sh
index b9baa4a..9326abd 100755
--- a/src/test/shell/integration/testenv.sh
+++ b/src/test/shell/integration/testenv.sh
@@ -37,6 +37,8 @@
 }
 
 function write_default_bazelrc() {
+  # Our tests use the static crosstool, so make it the default.
+  EXTRA_BAZELRC="build --crosstool_top=@bazel_tools//tools/cpp:default-toolchain"
   setup_bazelrc
 }
 
diff --git a/tools/cpp/test/BUILD b/tools/cpp/test/BUILD
index 9f6163a..b0a66b76 100644
--- a/tools/cpp/test/BUILD
+++ b/tools/cpp/test/BUILD
@@ -39,42 +39,18 @@
     for flavour in FLAVOURS
 ]
 
-genrule(
-    name = "gen_workspace",
-    srcs = ["//:workspace-file"],
-    outs = ["WORKSPACE"],
-    cmd = """
-    cat <<EOF >$@
-load("@bazel_tools//tools/cpp:cc_configure.bzl", "cc_configure")
-cc_configure()
-EOF
-    cat $(location //:workspace-file) >>$@
-""",
-)
-
-pkg_tar(
-    name = "cc_configure_ws",
-    files = [":WORKSPACE"],
-    package_dir = "/opt/workspace",
-    strip_prefix = ".",
-)
-
 pkg_tar(
     name = "bazel_cc_configure",
     package_dir = "/opt/workspace",
     strip_prefix = "/",
-    deps = [
-        # Order matters.
-        ":cc_configure_ws",
-        "//:bazel-srcs",
-    ],
+    deps = ["//:bazel-srcs"],
 )
 
 [
     [docker_build(
         name = "bazel_cc_configure-%s-%s" % (flavour, mode),
         base = ":base-" + flavour,
-        entrypoint = "/opt/workspace/compile.sh",
+        entrypoint = "/opt/workspace/compile.sh && ./output/bazel test ${EXTRA_BAZEL_ARGS} //examples/cpp:hello-success_test",
         env = {
             "EXTRA_BAZEL_ARGS": "--spawn_strategy=standalone --genrule_strategy=standalone -c %s" % mode,
         },