pw_polyfill: Add polyfill to toolchain

This adds the pw_polyfill bazel targets that can be consumed by a
remote toolchain. This change also adds a dependency on a set of remote
toolchains that target both host and ARM cortex-m devices. The remote
toolchain is compatible with the bazel targets in pw_polyfill.

Change-Id: I868d3349d8c20a70725e6f936cd6ca54acd93ef3
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/32820
Reviewed-by: Keir Mierle <keir@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
Reviewed-by: Akira Baruah <akira.baruah@gmail.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/.bazelrc b/.bazelrc
new file mode 100644
index 0000000..21d2703
--- /dev/null
+++ b/.bazelrc
@@ -0,0 +1 @@
+build --incompatible_enable_cc_toolchain_resolution
\ No newline at end of file
diff --git a/WORKSPACE b/WORKSPACE
index 9f53c87..adcb010 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,4 +1,4 @@
-# Copyright 2019 The Pigweed Authors
+# Copyright 2021 The Pigweed Authors
 #
 # 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
@@ -17,36 +17,114 @@
     managed_directories = {"@npm": ["node_modules"]},
 )
 
-# Set up build_bazel_rules_nodejs
+# Set up build_bazel_rules_nodejs.
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
 http_archive(
     name = "build_bazel_rules_nodejs",
     sha256 = "4952ef879704ab4ad6729a29007e7094aef213ea79e9f2e94cbe1c9a753e63ef",
     urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.2.0/rules_nodejs-2.2.0.tar.gz"],
 )
-# Get the latest LTS version of Node
-load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories")
+
+# Get the latest LTS version of Node.
+load(
+    "@build_bazel_rules_nodejs//:index.bzl",
+    "node_repositories",
+    "yarn_install",
+)
+
 node_repositories(package_json = ["//:package.json"])
 
-# Install packages with yarn
-load("@build_bazel_rules_nodejs//:index.bzl", "yarn_install")
 yarn_install(
     name = "npm",
     package_json = "//:package.json",
     yarn_lock = "//:yarn.lock",
 )
 
-# Set up Karma
+# Set up Karma.
 load("@npm//@bazel/karma:package.bzl", "npm_bazel_karma_dependencies")
+
 npm_bazel_karma_dependencies()
 
-load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories")
+load(
+    "@io_bazel_rules_webtesting//web:repositories.bzl",
+    "web_test_repositories",
+)
+
 web_test_repositories()
 
-load("@io_bazel_rules_webtesting//web/versioned:browsers-0.3.2.bzl", "browser_repositories")
+load(
+    "@io_bazel_rules_webtesting//web/versioned:browsers-0.3.2.bzl",
+    "browser_repositories",
+)
 
 browser_repositories(
     chromium = True,
     firefox = True,
 )
 
+# Setup embedded C/C++ toolchains.
+git_repository(
+    name = "bazel_embedded",
+    commit = "89c05fa415218abd2e24fa7016cb7903317d606b",
+    remote = "https://github.com/silvergasp/bazel-embedded.git",
+    shallow_since = "1614045367 +0800",
+)
+
+# Instantiate Pigweed configuration for embedded toolchain,
+# this must be called before bazel_embedded_deps.
+load(
+    "//pw_build:pigweed_toolchain_upstream.bzl",
+    "toolchain_upstream_deps",
+)
+
+toolchain_upstream_deps()
+
+# Configure bazel_embedded toolchains and platforms.
+load(
+    "@bazel_embedded//:bazel_embedded_deps.bzl",
+    "bazel_embedded_deps",
+)
+
+bazel_embedded_deps()
+
+load(
+    "@bazel_embedded//platforms:execution_platforms.bzl",
+    "register_platforms",
+)
+
+register_platforms()
+
+# Fetch gcc-arm-none-eabi compiler and register for toolchain
+# resolution.
+load(
+    "@bazel_embedded//toolchains/compilers/gcc_arm_none_eabi:gcc_arm_none_repository.bzl",
+    "gcc_arm_none_compiler",
+)
+
+gcc_arm_none_compiler()
+
+load(
+    "@bazel_embedded//toolchains/gcc_arm_none_eabi:gcc_arm_none_toolchain.bzl",
+    "register_gcc_arm_none_toolchain",
+)
+
+register_gcc_arm_none_toolchain()
+
+# Fetch LLVM/Clang compiler and register for toolchain resolution.
+load(
+    "@bazel_embedded//toolchains/compilers/llvm:llvm_repository.bzl",
+    "llvm_repository",
+)
+
+llvm_repository(
+    name = "com_llvm_compiler",
+)
+
+load(
+    "@bazel_embedded//toolchains/clang:clang_toolchain.bzl",
+    "register_clang_toolchain",
+)
+
+register_clang_toolchain()
diff --git a/pw_build/docs.rst b/pw_build/docs.rst
index 43ff762..18aadb1 100644
--- a/pw_build/docs.rst
+++ b/pw_build/docs.rst
@@ -514,11 +514,44 @@
 
 Bazel
 =====
-Bazel is currently very experimental, and only builds for host.
+Bazel is currently very experimental, and only builds for host and ARM Cortex-M
+microcontrollers.
 
 The common configuration for Bazel for all modules is in the ``pigweed.bzl``
 file. The built-in Bazel rules ``cc_binary``, ``cc_library``, and ``cc_test``
 are wrapped with ``pw_cc_binary``, ``pw_cc_library``, and ``pw_cc_test``.
 These wrappers add parameters to calls to the compiler and linker.
 
-The ``BUILD`` file is merely a placeholder and currently does nothing.
+Currently Pigweed is making use of a set of
+[open source](https://github.com/silvergasp/bazel-embedded) toolchains. The host
+builds are only supported on Linux/Mac based systems. Additionally the host
+builds are not entirely hermetic, and will make use of system
+libraries and headers. This is close to the default configuration for Bazel,
+though slightly more hermetic. The host toolchain is based around clang-11 which
+has a system dependency on 'libtinfo.so.5' which is often included as part of
+the libncurses packages. On Debian based systems this can be installed using the
+command below:
+
+.. code-block:: sh
+
+  sudo apt install libncurses5
+
+The host toolchain does not currently support native Windows, though using WSL
+is a viable alternative.
+
+The ARM Cortex-M Bazel toolchains are based around gcc-arm-non-eabi and are
+entirely hermetic. You can target Cortex-M, by using the platforms command line
+option. This set of toolchains is supported from hosts; Windows, Mac and Linux.
+The platforms that are currently supported are listed below.
+
+.. code-block:: sh
+
+  bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m0
+  bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m1
+  bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m3
+  bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m4
+  bazel build //:your_target --platforms=@bazel_embedded//platforms:cortex_m7
+  bazel build //:your_target \
+       --platforms=@bazel_embedded//platforms:cortex_m4_fpu
+  bazel build //:your_target \
+       --platforms=@bazel_embedded//platforms:cortex_m7_fpu
\ No newline at end of file
diff --git a/pw_build/pigweed_toolchain_upstream.bzl b/pw_build/pigweed_toolchain_upstream.bzl
new file mode 100644
index 0000000..4b7767a
--- /dev/null
+++ b/pw_build/pigweed_toolchain_upstream.bzl
@@ -0,0 +1,77 @@
+# Copyright 2021 The Pigweed Authors
+#
+# 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
+#
+#     https://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.
+
+def _toolchain_upstream_repository_impl(rctx):
+    """Creates a remote repository with a set of toolchain components.
+
+    The bazel embedded toolchain expects two targets injected_headers
+    and polyfill. This is rule generates these targets so that
+    bazel-embedded can depend on them and so that the targets can depend
+    on pigweeds implementation of polyfill. This rule is only ever
+    intended to be instantiated with the name
+    "bazel_embedded_upstream_toolchain", and should only be used from
+    the "toolchain_upstream_deps" macro.
+
+    The bazel-embedded package expects to be able to access these
+    targets as @bazel_embedded_upstream_toolchain//:polyfill and
+    @bazel_embedded_upstream_toolchain//:injected_headers.
+
+    Args:
+      rctx: Repository context.
+    """
+    rctx.file("BUILD", """
+package(default_visibility = ["//visibility:public"])
+load(
+    "@bazel_embedded//toolchains/tools/include_tools:defs.bzl",
+    "cc_injected_toolchain_header_library",
+    "cc_polyfill_toolchain_library",
+)
+
+cc_polyfill_toolchain_library(
+    name = "polyfill",
+    deps = ["@pigweed//pw_polyfill:toolchain_polyfill_overrides"],
+)
+
+cc_injected_toolchain_header_library(
+    name = "injected_headers",
+    deps = ["@pigweed//pw_polyfill:toolchain_injected_headers"],
+)
+""")
+
+_toolchain_upstream_repository = repository_rule(
+    _toolchain_upstream_repository_impl,
+    doc = """
+toolchain_upstream_repository creates a remote repository that can be
+accessed by a toolchain repository to configure system includes.
+
+It's recommended to use this rule through the 'toolchain_upstream_deps'
+macro rather than using this rule directly.
+""",
+)
+
+def toolchain_upstream_deps():
+    """Implements the set of dependencies that bazel-embedded requires.
+
+    These targets are used to override the default toolchain
+    requirements in the remote bazel-embedded toolchain. The remote
+    toolchain expects to find two targets;
+      - "@bazel_embedded_upstream_toolchain//:polyfill" -> Additional
+        system headers for the toolchain
+      - "@bazel_embedded_upstream_toolchain//:injected_headers" ->
+        Headers that are injected into the toolchain via the -include
+        command line argument
+    """
+    _toolchain_upstream_repository(
+        name = "bazel_embedded_upstream_toolchain",
+    )
diff --git a/pw_polyfill/BUILD b/pw_polyfill/BUILD
index 976b45a..1b2f74d 100644
--- a/pw_polyfill/BUILD
+++ b/pw_polyfill/BUILD
@@ -1,4 +1,4 @@
-# Copyright 2020 The Pigweed Authors
+# Copyright 2021 The Pigweed Authors
 #
 # 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
@@ -17,11 +17,48 @@
     "pw_cc_library",
     "pw_cc_test",
 )
+load(
+    "@bazel_embedded//toolchains/tools/include_tools:defs.bzl",
+    "cc_injected_toolchain_header_library",
+    "cc_polyfill_toolchain_library",
+)
 
 package(default_visibility = ["//visibility:public"])
 
 licenses(["notice"])  # Apache License 2.0
 
+cc_injected_toolchain_header_library(
+    name = "toolchain_injected_headers",
+    hdrs = ["language_features.h"],
+)
+
+cc_polyfill_toolchain_library(
+    name = "toolchain_polyfill_overrides",
+    hdrs = [
+        "language_features.h",
+        "public_overrides/array",
+        "public_overrides/assert.h",
+        "public_overrides/bit",
+        "public_overrides/cstddef",
+        "public_overrides/iterator",
+        "public_overrides/type_traits",
+        "public_overrides/utility",
+        "standard_library_public/pw_polyfill/standard_library/array.h",
+        "standard_library_public/pw_polyfill/standard_library/assert.h",
+        "standard_library_public/pw_polyfill/standard_library/bit.h",
+        "standard_library_public/pw_polyfill/standard_library/cstddef.h",
+        "standard_library_public/pw_polyfill/standard_library/iterator.h",
+        "standard_library_public/pw_polyfill/standard_library/namespace.h",
+        "standard_library_public/pw_polyfill/standard_library/type_traits.h",
+        "standard_library_public/pw_polyfill/standard_library/utility.h",
+    ],
+    system_includes = [
+        "public_overrides",
+        "public",
+        "standard_library_public",
+    ],
+)
+
 pw_cc_library(
     name = "pw_polyfill",
     hdrs = [