build/toolchain: init

This adds a new, bare-bones, host-based C++ toolchain, and enables it
for all target builds. This toolchain replaces the automatically
generated host toolchain from bazel-tools, and differs in the following
ways:
 - uses fully hardcoded paths
 - is the bare minimum required, which allows us full control over all
   aspects of it, notably link arguments
 - does not assume we're building normal C++ binaries for Linux (for
   instance, the new toolchain does not always link with -lm)

This is in anticipation of a change by @lorenz that uses cc_binary to
build qboot for tests. However, this is also a good basis to start
writing a 'real' toolchain suite for mkfs.xfs, linux & co.

Test Plan: For now, this is unused - but does not break any existing flow, which is fine. I did test this on a qboot WIP commit from @lorenz, and it at least fixed our immediate problem that it wanted to build it with with -lm,-lstdc++ - which we didn't.

X-Origin-Diff: phab/D560
GitOrigin-RevId: 8a5bc5f00a0a0534ea245e556d160f5bab7f8a0c
diff --git a/.bazelrc b/.bazelrc
index d1d18db..1dd8a0a 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -10,3 +10,11 @@
 
 # Set workspace status file and stamp
 build --stamp --workspace_status_command=./build/print-workspace-status.sh
+
+# Use our custom-configured host C++ toolchain.
+build --crosstool_top=//build/toolchain:host_cc_suite
+build --cpu=k8
+
+# Use the default Bazel C++ toolchain to build the tools used during the
+# build.
+build --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
diff --git a/build/toolchain/BUILD b/build/toolchain/BUILD
new file mode 100644
index 0000000..5bf53d2
--- /dev/null
+++ b/build/toolchain/BUILD
@@ -0,0 +1,51 @@
+load(":cc_toolchain_config.bzl", "host_cc_toolchain_config")
+
+# Toolchain definitions.
+#
+# We currently define a single custom toolchain: the host_cc toolchain suite.
+# This is a C++ toolchain that uses GCC from the host at hardcoded paths. We
+# can get away with this, as currently the entire build is performed in a known
+# container (see: //scripts:create_container.sh). We define this toolchain so
+# that we have full control over all configuration of it, which we need as we
+# are building some fairly odd C binaries (notably, a qboot bootloader for
+# testing).
+#
+# The host_cc toolchain suite is enabled for all cc_* targets that aren't
+# building host tools by setting --crosstool_top in .bazelrc. In the future,
+# this should only be triggered by transitions where necessary.
+#
+# In the future, the host_cc toolchains should be replaced by a hermetic
+# toolchain that's built locally, or downloaded from the Internet - as
+# github.com/bazelbuild/bazel-toolchains does it. As that's being built, we
+# should then also have another toolchain definition for C binaries that
+# target Smalltown static binaries, so that mkfs.xfs can be built using native
+# cc_* rules, too.
+#
+# This, and :cc_toolchain_config.bzl is based on the following tutorial:
+# https://docs.bazel.build/versions/master/tutorial/cc-toolchain-config.html
+
+package(default_visibility = ["//visibility:public"])
+
+filegroup(name = "empty")
+
+cc_toolchain_suite(
+    name = "host_cc_suite",
+    toolchains = {
+        "k8": ":host_cc_k8_toolchain",
+    },
+)
+
+cc_toolchain(
+    name = "host_cc_k8_toolchain",
+    toolchain_identifier = "host-k8-toolchain",
+    toolchain_config = ":host_cc_k8_toolchain_config",
+    all_files = ":empty",
+    compiler_files = ":empty",
+    dwp_files = ":empty",
+    linker_files = ":empty",
+    objcopy_files = ":empty",
+    strip_files = ":empty",
+    supports_param_files = 0,
+)
+
+host_cc_toolchain_config(name = "host_cc_k8_toolchain_config")
diff --git a/build/toolchain/cc_toolchain_config.bzl b/build/toolchain/cc_toolchain_config.bzl
new file mode 100644
index 0000000..b69e06f
--- /dev/null
+++ b/build/toolchain/cc_toolchain_config.bzl
@@ -0,0 +1,79 @@
+#  Copyright 2020 The Monogon Project Authors.
+#
+#  SPDX-License-Identifier: Apache-2.0
+#
+#  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.
+
+load("@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", "tool_path")
+
+# This defines a minimal, non-parametrized toolchain configuration rule that
+# uses the host GCC. For background on why we do this, see
+# //build/toolchain/BUILD.
+
+def _host_cc_toolchain_impl(ctx):
+    tool_paths = [
+        tool_path(
+            name = "gcc",
+            path = "/usr/bin/gcc",
+        ),
+        tool_path(
+            name = "ld",
+            path = "/usr/bin/ld",
+        ),
+        tool_path(
+            name = "ar",
+            path = "/usr/bin/ar",
+        ),
+        tool_path(
+            name = "cpp",
+            path = "/bin/false",
+        ),
+        tool_path(
+            name = "gcov",
+            path = "/bin/false",
+        ),
+        tool_path(
+            name = "nm",
+            path = "/bin/false",
+        ),
+        tool_path(
+            name = "objdump",
+            path = "/bin/false",
+        ),
+        tool_path(
+            name = "strip",
+            path = "/bin/false",
+        ),
+    ]
+    return cc_common.create_cc_toolchain_config_info(
+        ctx = ctx,
+        cxx_builtin_include_directories = [
+          "/usr/lib/gcc/x86_64-redhat-linux/10/include/",
+          "/usr/include",
+        ],
+        toolchain_identifier = "k8-toolchain",
+        host_system_name = "local",
+        target_system_name = "local",
+        target_cpu = "k8",
+        target_libc = "unknown",
+        compiler = "gcc",
+        abi_version = "unknown",
+        abi_libc_version = "unknown",
+        tool_paths = tool_paths,
+    )
+
+host_cc_toolchain_config = rule(
+    implementation = _host_cc_toolchain_impl,
+    attrs = {},
+    provides = [CcToolchainConfigInfo],
+)