Merge branch 'main' into rules-based-toolchain-example
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 8d7899d..0707da9 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -51,3 +51,13 @@
       - "--ignore_dev_dependency"
     build_targets:
       - "//cc/..."
+  ubuntu_rule_based_toolchains:
+    name: Linux rule-based toolchains
+    platform: ubuntu1804
+    working_directory: examples/rule_based_toolchain
+    build_flags:
+      - "--enable_bzlmod"
+    build_targets:
+      - "//..."
+    test_targets:
+      - "//..."
diff --git a/.bazelignore b/.bazelignore
new file mode 100644
index 0000000..ff5e9ce
--- /dev/null
+++ b/.bazelignore
@@ -0,0 +1 @@
+examples/rule_based_toolchain
diff --git a/.gitignore b/.gitignore
index 65e8edc..a3fdb6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-/bazel-*
\ No newline at end of file
+/bazel-*
+/examples/rule_based_toolchain/bazel-*
diff --git a/examples/rule_based_toolchain/.bazelrc b/examples/rule_based_toolchain/.bazelrc
new file mode 100644
index 0000000..3216a76
--- /dev/null
+++ b/examples/rule_based_toolchain/.bazelrc
@@ -0,0 +1,5 @@
+# Do not use the default toolchain.
+build --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=0
+
+# Enable rule-based toolchains.
+build --@rules_cc//cc/toolchains:experimental_enable_rule_based_toolchains=True
diff --git a/examples/rule_based_toolchain/.bazelversion b/examples/rule_based_toolchain/.bazelversion
new file mode 100644
index 0000000..b26a34e
--- /dev/null
+++ b/examples/rule_based_toolchain/.bazelversion
@@ -0,0 +1 @@
+7.2.1
diff --git a/examples/rule_based_toolchain/BUILD b/examples/rule_based_toolchain/BUILD
new file mode 100644
index 0000000..b835735
--- /dev/null
+++ b/examples/rule_based_toolchain/BUILD
@@ -0,0 +1,10 @@
+cc_test(
+    name = "quick_test",
+    srcs = ["quick_test.cc"],
+    deps = [
+        "//dynamic_answer",
+        "//static_answer",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
+    ],
+)
diff --git a/examples/rule_based_toolchain/MODULE.bazel b/examples/rule_based_toolchain/MODULE.bazel
new file mode 100644
index 0000000..8e91dfd
--- /dev/null
+++ b/examples/rule_based_toolchain/MODULE.bazel
@@ -0,0 +1,34 @@
+module(
+    name = "rule_based_toolchain",
+    version = "0.0.1",
+)
+
+bazel_dep(name = "platforms", version = "0.0.10")
+bazel_dep(name = "googletest", version = "1.15.2")
+bazel_dep(name = "bazel_skylib", version = "1.7.1")
+
+bazel_dep(name = "rules_cc")
+local_path_override(module_name = "rules_cc", path = "../..")
+
+http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+http_archive(
+    name = "clang-linux-x86_64",
+    build_file = "//toolchain:clang.BUILD",
+    sha256 = "9042f89df9c13a2bf28e16ce34dfe22934b59b5d8390e94b030bb378bdb3c898",
+    type = "zip",
+    url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64/+/git_revision:0cfd03ac0d3f9713090a581bda07584754c73a49",
+)
+
+http_archive(
+    name = "linux_sysroot",
+    build_file = "//toolchain:linux_sysroot.BUILD",
+    sha256 = "f45ca0d8b46810b94d2a7dbc65f9092337d6a9568b260b51173a5ab9314da25e",
+    type = "zip",
+    url = "https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/sysroot/bionic/+/git_revision:702eb9654703a7cec1cadf93a7e3aa269d053943",
+)
+
+register_toolchains(
+    "//toolchain:host-linux-x86_64",
+    dev_dependency = True,
+)
diff --git a/examples/rule_based_toolchain/MODULE.bazel.lock b/examples/rule_based_toolchain/MODULE.bazel.lock
new file mode 100644
index 0000000..60e90b3
--- /dev/null
+++ b/examples/rule_based_toolchain/MODULE.bazel.lock
@@ -0,0 +1,137 @@
+{
+  "lockFileVersion": 11,
+  "registryFileHashes": {
+    "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
+    "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
+    "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/source.json": "750d5e29326fb59cbe61116a7b803c8a1d0a7090a9c8ed89888d188e3c473fc7",
+    "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
+    "https://bcr.bazel.build/modules/apple_support/1.15.1/source.json": "517f2b77430084c541bc9be2db63fdcbb7102938c5f64c17ee60ffda2e5cf07b",
+    "https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef",
+    "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
+    "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
+    "https://bcr.bazel.build/modules/bazel_features/1.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015",
+    "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
+    "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
+    "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
+    "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
+    "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
+    "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
+    "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
+    "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108",
+    "https://bcr.bazel.build/modules/googletest/1.15.2/source.json": "dbdda654dcb3a0d7a8bc5d0ac5fc7e150b58c2a986025ae5bc634bb2cb61f470",
+    "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
+    "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
+    "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5",
+    "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
+    "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
+    "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
+    "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
+    "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
+    "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
+    "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
+    "https://bcr.bazel.build/modules/protobuf/21.7/source.json": "bbe500720421e582ff2d18b0802464205138c06056f443184de39fbb8187b09b",
+    "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
+    "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680",
+    "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
+    "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa",
+    "https://bcr.bazel.build/modules/re2/2024-07-02/source.json": "547d0111a9d4f362db32196fef805abbf3676e8d6afbe44d395d87816c1130ca",
+    "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
+    "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
+    "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
+    "https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1",
+    "https://bcr.bazel.build/modules/rules_java/7.6.5/source.json": "a805b889531d1690e3c72a7a7e47a870d00323186a9904b36af83aa3d053ee8d",
+    "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.2/source.json": "10572111995bc349ce31c78f74b3c147f6b3233975c7fa5eff9211f6db0d34d9",
+    "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
+    "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
+    "https://bcr.bazel.build/modules/rules_license/0.0.7/source.json": "355cc5737a0f294e560d52b1b7a6492d4fff2caf0bef1a315df5a298fca2d34a",
+    "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
+    "https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c",
+    "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
+    "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
+    "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483",
+    "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/source.json": "8d8448e71706df7450ced227ca6b3812407ff5e2ccad74a43a9fbe79c84e34e0",
+    "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
+    "https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
+    "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
+    "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
+    "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937",
+    "https://bcr.bazel.build/modules/rules_python/0.33.2/source.json": "e539592cd3aae4492032cecea510e46ca16eeb972271560b922cae9893944e2f",
+    "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
+    "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
+    "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
+    "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
+    "https://bcr.bazel.build/modules/stardoc/0.7.0/source.json": "e3c524bf2ef20992539ce2bc4a2243f4853130209ee831689983e28d05769099",
+    "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
+    "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/source.json": "f1ef7d3f9e0e26d4b23d1c39b5f5de71f584dd7d1b4ef83d9bbba6ec7a6a6459",
+    "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
+    "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d"
+  },
+  "selectedYankedVersions": {},
+  "moduleExtensions": {
+    "@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": {
+      "general": {
+        "bzlTransitiveDigest": "ltCGFbl/LQQZXn/LEMXfKX7pGwyqNiOCHcmiQW0tmjM=",
+        "usagesDigest": "RkqDb8JtSSm4rLheCLMw/Dx3QQE7dZbl4taOVEYaQZg=",
+        "recordedFileInputs": {},
+        "recordedDirentsInputs": {},
+        "envVariables": {},
+        "generatedRepoSpecs": {
+          "local_config_apple_cc": {
+            "bzlFile": "@@apple_support~//crosstool:setup.bzl",
+            "ruleClassName": "_apple_cc_autoconf",
+            "attributes": {}
+          },
+          "local_config_apple_cc_toolchains": {
+            "bzlFile": "@@apple_support~//crosstool:setup.bzl",
+            "ruleClassName": "_apple_cc_autoconf_toolchains",
+            "attributes": {}
+          }
+        },
+        "recordedRepoMappingEntries": [
+          [
+            "apple_support~",
+            "bazel_tools",
+            "bazel_tools"
+          ]
+        ]
+      }
+    },
+    "@@platforms//host:extension.bzl%host_platform": {
+      "general": {
+        "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
+        "usagesDigest": "V1R2Y2oMxKNfx2WCWpSCaUV1WefW1o8HZGm3v1vHgY4=",
+        "recordedFileInputs": {},
+        "recordedDirentsInputs": {},
+        "envVariables": {},
+        "generatedRepoSpecs": {
+          "host_platform": {
+            "bzlFile": "@@platforms//host:extension.bzl",
+            "ruleClassName": "host_platform_repo",
+            "attributes": {}
+          }
+        },
+        "recordedRepoMappingEntries": []
+      }
+    }
+  }
+}
diff --git a/examples/rule_based_toolchain/dynamic_answer/BUILD b/examples/rule_based_toolchain/dynamic_answer/BUILD
new file mode 100644
index 0000000..ab86261
--- /dev/null
+++ b/examples/rule_based_toolchain/dynamic_answer/BUILD
@@ -0,0 +1,31 @@
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])  # Apache 2.0
+
+cc_library(
+    name = "headers",
+    includes = ["public"],
+    hdrs = ["public/dynamic_answer.h"],
+    visibility = ["//visibility:private"],
+)
+
+cc_library(
+    name = "answer",
+    srcs = ["dynamic_answer.c"],
+    deps = [":headers"],
+    visibility = ["//visibility:private"],
+)
+
+
+cc_shared_library(
+    name = "shared_library",
+    deps = [":answer"],
+    visibility = ["//visibility:private"],
+)
+
+# Forces linkage as a shared library.
+cc_library(
+    name = "dynamic_answer",
+    deps = [":headers"],
+    srcs = [":shared_library"],
+)
diff --git a/examples/rule_based_toolchain/dynamic_answer/dynamic_answer.c b/examples/rule_based_toolchain/dynamic_answer/dynamic_answer.c
new file mode 100644
index 0000000..a4256ac
--- /dev/null
+++ b/examples/rule_based_toolchain/dynamic_answer/dynamic_answer.c
@@ -0,0 +1,5 @@
+#include "dynamic_answer.h"
+
+int dynamic_answer(void) {
+    return 24;
+}
diff --git a/examples/rule_based_toolchain/dynamic_answer/public/dynamic_answer.h b/examples/rule_based_toolchain/dynamic_answer/public/dynamic_answer.h
new file mode 100644
index 0000000..2cf065a
--- /dev/null
+++ b/examples/rule_based_toolchain/dynamic_answer/public/dynamic_answer.h
@@ -0,0 +1,14 @@
+#ifndef DYNAMIC_ANSWER_PUBLIC_DYNAMIC_ANSWER_H_
+#define DYNAMIC_ANSWER_PUBLIC_DYNAMIC_ANSWER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+int dynamic_answer(void);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // DYNAMIC_ANSWER_PUBLIC_DYNAMIC_ANSWER_H_
diff --git a/examples/rule_based_toolchain/quick_test.cc b/examples/rule_based_toolchain/quick_test.cc
new file mode 100644
index 0000000..665b93b
--- /dev/null
+++ b/examples/rule_based_toolchain/quick_test.cc
@@ -0,0 +1,12 @@
+#include <gtest/gtest.h>
+
+#include "dynamic_answer.h"
+#include "static_answer.h"
+
+TEST(Static, ProperlyLinked) {
+  EXPECT_EQ(static_answer(), 42);
+}
+
+TEST(Dynamic, ProperlyLinked) {
+  EXPECT_EQ(dynamic_answer(), 24);
+}
diff --git a/examples/rule_based_toolchain/static_answer/BUILD b/examples/rule_based_toolchain/static_answer/BUILD
new file mode 100644
index 0000000..cab59e9
--- /dev/null
+++ b/examples/rule_based_toolchain/static_answer/BUILD
@@ -0,0 +1,18 @@
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])  # Apache 2.0
+
+cc_library(
+    name = "answer",
+    includes = ["public"],
+    hdrs = ["public/static_answer.h"],
+    srcs = ["static_answer.cc"],
+    linkstatic = True,
+    visibility = ["//visibility:private"],
+)
+
+# TODO: This should be a cc_static_library when that's supported.
+alias(
+    name = "static_answer",
+    actual = ":answer",
+)
diff --git a/examples/rule_based_toolchain/static_answer/public/static_answer.h b/examples/rule_based_toolchain/static_answer/public/static_answer.h
new file mode 100644
index 0000000..667ef6c
--- /dev/null
+++ b/examples/rule_based_toolchain/static_answer/public/static_answer.h
@@ -0,0 +1,14 @@
+#ifndef STATIC_ANSWER_PUBLIC_STATIC_ANSWER_H_
+#define STATIC_ANSWER_PUBLIC_STATIC_ANSWER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif  // __cplusplus
+
+int static_answer(void);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif  // __cplusplus
+
+#endif  // STATIC_ANSWER_PUBLIC_STATIC_ANSWER_H_
diff --git a/examples/rule_based_toolchain/static_answer/static_answer.cc b/examples/rule_based_toolchain/static_answer/static_answer.cc
new file mode 100644
index 0000000..1f2e1cc
--- /dev/null
+++ b/examples/rule_based_toolchain/static_answer/static_answer.cc
@@ -0,0 +1,5 @@
+#include "static_answer.h"
+
+extern "C" int static_answer() {
+    return 42;
+}
diff --git a/examples/rule_based_toolchain/toolchain/BUILD b/examples/rule_based_toolchain/toolchain/BUILD
new file mode 100644
index 0000000..1f3fccc
--- /dev/null
+++ b/examples/rule_based_toolchain/toolchain/BUILD
@@ -0,0 +1,65 @@
+load("@rules_cc//cc/toolchains:args.bzl", "cc_args")
+load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain")
+
+# For now, each toolchain is only declared to be compatible
+# when exec_platform == target_platform.
+PLATFORMS = {
+    "linux-x86_64": [
+        "@platforms//os:linux",
+        "@platforms//cpu:x86_64",
+    ],
+}
+
+cc_args(
+    name = "warnings",
+    actions = [
+        "@rules_cc//cc/toolchains/actions:c_compile",
+        "@rules_cc//cc/toolchains/actions:cpp_compile_actions",
+    ],
+    args = [
+        "-Werror",
+        "-Wall",
+        "-Wextra",
+        "-Wpedantic",
+    ],
+)
+
+cc_args(
+    name = "no_canonical_prefixes",
+    actions = [
+        "@rules_cc//cc/toolchains/actions:c_compile",
+        "@rules_cc//cc/toolchains/actions:cpp_compile_actions",
+    ],
+    args = ["-no-canonical-prefixes"],
+)
+
+[
+    cc_toolchain(
+        name = "host-{}-config".format(platform_name),
+        args = select({
+            "@platforms//os:linux": [
+                "@linux_sysroot//:sysroot",
+            ],
+            "//conditions:default": [],
+        }) + [
+            ":no_canonical_prefixes",
+            ":warnings",
+        ],
+        tool_map = "@clang-{}//:all_tools".format(platform_name),
+        known_features = ["@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features"],
+        enabled_features = ["@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features"],
+        target_compatible_with = constraints,
+    )
+    for platform_name, constraints in PLATFORMS.items()
+]
+
+[
+    toolchain(
+        name = "host-{}".format(platform_name),
+        exec_compatible_with = constraints,
+        target_compatible_with = constraints,
+        toolchain = ":host-{}-config".format(platform_name),
+        toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
+    )
+    for platform_name, constraints in PLATFORMS.items()
+]
diff --git a/examples/rule_based_toolchain/toolchain/clang.BUILD b/examples/rule_based_toolchain/toolchain/clang.BUILD
new file mode 100644
index 0000000..a548d25
--- /dev/null
+++ b/examples/rule_based_toolchain/toolchain/clang.BUILD
@@ -0,0 +1,217 @@
+load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool")
+load("@rules_cc//cc/toolchains:tool_map.bzl", "cc_tool_map")
+load("@bazel_skylib//rules/directory:directory.bzl", "directory")
+load("@bazel_skylib//rules/directory:subdirectory.bzl", "subdirectory")
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])
+
+# Directory-based rules in this toolchain only referece things in
+# lib/ or include/ subdirectories.
+directory(
+    name = "toolchain_root",
+    srcs = glob([
+        "lib/**",
+        "include/**",
+    ]),
+)
+
+#####################
+#       Tools       #
+#####################
+
+alias(
+    name = "all_tools",
+    actual = select({
+        "@platforms//os:macos": ":macos_tools",
+        "//conditions:default": ":default_tools",
+    })
+)
+
+COMMON_TOOLS = {
+    "@rules_cc//cc/toolchains/actions:assembly_actions": ":asm",
+    "@rules_cc//cc/toolchains/actions:c_compile": ":clang",
+    "@rules_cc//cc/toolchains/actions:cpp_compile_actions": ":clang++",
+    "@rules_cc//cc/toolchains/actions:link_actions": ":lld",
+    "@rules_cc//cc/toolchains/actions:objcopy_embed_data": ":llvm-objcopy",
+    "@rules_cc//cc/toolchains/actions:strip": ":llvm-strip",
+}
+
+cc_tool_map(
+    name = "default_tools",
+    tools = COMMON_TOOLS | {
+        "@rules_cc//cc/toolchains/actions:ar_actions": ":llvm-ar"
+    },
+    visibility = ["//visibility:private"],
+)
+
+cc_tool_map(
+    name = "macos_tools",
+    tools = COMMON_TOOLS | {
+        "@rules_cc//cc/toolchains/actions:ar_actions": ":llvm-libtool-darwin"
+    },
+    visibility = ["//visibility:private"],
+)
+
+# TODO: https://github.com/bazelbuild/rules_cc/issues/235 - Workaround until
+# Bazel has a more robust way to implement `cc_tool_map`.
+alias(
+    name = "asm",
+    actual = ":clang",
+)
+
+cc_tool(
+    name = "clang",
+    src = select({
+        "@platforms//os:windows": "//:bin/clang.exe",
+        "//conditions:default": "//:bin/clang",
+    }),
+    data = glob([
+        "bin/llvm",
+        "include/**",
+        "lib/clang/**/include/**",
+    ]),
+    allowlist_include_directories = [
+        ":lib-clang-include",
+    ],
+)
+
+cc_tool(
+    name = "clang++",
+    src = select({
+        "@platforms//os:windows": "//:bin/clang++.exe",
+        "//conditions:default": "//:bin/clang++",
+    }),
+    data = glob([
+        "bin/llvm",
+        "include/**",
+        "lib/clang/**/include/**",
+    ]),
+    allowlist_include_directories = [
+        ":include-x86_64-unknown-linux-gnu-c++-v1",
+        ":include-c++-v1",
+        ":lib-clang-include",
+    ],
+)
+
+cc_tool(
+    name = "lld",
+    src = select({
+        "@platforms//os:windows": "//:bin/clang++.exe",
+        "//conditions:default": "//:bin/clang++",
+    }),
+    data = glob([
+        "bin/llvm",
+        "bin/lld*",
+        "bin/ld*",
+        "lib/**/*.a",
+        "lib/**/*.so*",
+        "lib/**/*.o",
+    ]),
+)
+
+cc_tool(
+    name = "llvm-ar",
+    src = select({
+        "@platforms//os:windows": "//:bin/llvm-ar.exe",
+        "//conditions:default": "//:bin/llvm-ar",
+    }),
+    data = glob(["bin/llvm"]),
+)
+
+cc_tool(
+    name = "llvm-libtool-darwin",
+    src = select({
+        "@platforms//os:windows": "//:bin/llvm-libtool-darwin.exe",
+        "//conditions:default": "//:bin/llvm-libtool-darwin",
+    }),
+    data = glob(["bin/llvm"]),
+)
+
+cc_tool(
+    name = "llvm-objcopy",
+    src = select({
+        "@platforms//os:windows": "//:bin/llvm-objcopy.exe",
+        "//conditions:default": "//:bin/llvm-objcopy",
+    }),
+    data = glob(["bin/llvm"]),
+)
+
+cc_tool(
+    name = "llvm-objdump",
+    src = select({
+        "@platforms//os:windows": "//:bin/llvm-objdump.exe",
+        "//conditions:default": "//:bin/llvm-objdump",
+    }),
+    data = glob(["bin/llvm"]),
+)
+
+cc_tool(
+    name = "llvm-cov",
+    src = select({
+        "@platforms//os:windows": "//:bin/llvm-cov.exe",
+        "//conditions:default": "//:bin/llvm-cov",
+    }),
+    data = glob(["bin/llvm"]),
+)
+
+cc_tool(
+    name = "llvm-strip",
+    src = select({
+        "@platforms//os:windows": "//:bin/llvm-strip.exe",
+        "//conditions:default": "//:bin/llvm-strip",
+    }),
+    data = glob(["bin/llvm"]),
+)
+
+cc_tool(
+    name = "clang-tidy",
+    src = select({
+        "@platforms//os:windows": "//:bin/clang-tidy.exe",
+        "//conditions:default": "//:bin/clang-tidy",
+    }),
+    data = glob([
+        "bin/llvm",
+        "include/**",
+        "lib/clang/**/include/**",
+    ]) + select({
+        "@platforms//os:linux": ["@linux_sysroot//:root"],
+        "//conditions:default": [],
+    }),
+)
+
+#####################
+#     Arguments     #
+#####################
+
+# None...
+
+#####################
+#     Features      #
+#####################
+
+# None...
+
+#####################
+#     Builtins      #
+#####################
+
+subdirectory(
+    name = "include-c++-v1",
+    parent = ":toolchain_root",
+    path = "include/c++/v1",
+)
+
+subdirectory(
+    name = "lib-clang-include",
+    parent = ":toolchain_root",
+    path = "lib/clang/19/include",
+)
+
+subdirectory(
+    name = "include-x86_64-unknown-linux-gnu-c++-v1",
+    parent = ":toolchain_root",
+    path = "include/x86_64-unknown-linux-gnu/c++/v1",
+)
diff --git a/examples/rule_based_toolchain/toolchain/linux_sysroot.BUILD b/examples/rule_based_toolchain/toolchain/linux_sysroot.BUILD
new file mode 100644
index 0000000..904d48b
--- /dev/null
+++ b/examples/rule_based_toolchain/toolchain/linux_sysroot.BUILD
@@ -0,0 +1,32 @@
+load("@bazel_skylib//rules/directory:directory.bzl", "directory")
+load("@bazel_skylib//rules/directory:subdirectory.bzl", "subdirectory")
+load("@rules_cc//cc/toolchains/args:sysroot.bzl", "cc_sysroot")
+
+package(default_visibility = ["//visibility:public"])
+
+cc_sysroot(
+    name = "sysroot",
+    sysroot = ":root",
+    data = [":root"],
+    allowlist_include_directories = [
+        ":usr-include-x86_64-linux-gnu",
+        ":usr-include",
+    ],
+)
+
+directory(
+    name = "root",
+    srcs = glob(["**/*"]),
+)
+
+subdirectory(
+    name = "usr-include-x86_64-linux-gnu",
+    path = "usr/include/x86_64-linux-gnu",
+    parent = ":root",
+)
+
+subdirectory(
+    name = "usr-include",
+    path = "usr/include",
+    parent = ":root",
+)