[libc++] Make CC and CXX environment variables mandatory in run-buildbot (#166875)

Previously, the bootstrapping-build job defined in run-buildbot required
the CC and CXX environment variables to be defined even though
run-buildbot documents these environment variables as being optional. It
also relied on ccache being available.

Refactor run-buildbot to make CC and CXX mandatory, and refactor various
places in the CI where we called run-buildbot without setting CC and
CXX. After this patch, all places that use run-buildbot are setting CC
and CXX before calling the script, which makes it easier to track what
compiler is used where. This also allows simplifying run-buildbot
itself.

Finally, this patch makes ccache optional for running the bootstrapping
build.
diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml
index 8e6dc48..bded56d 100644
--- a/.github/workflows/libcxx-build-and-test.yaml
+++ b/.github/workflows/libcxx-build-and-test.yaml
@@ -223,6 +223,9 @@
           source .venv/bin/activate
           python -m pip install psutil
           xcrun bash libcxx/utils/ci/run-buildbot ${{ matrix.config }}
+        env:
+          CC: clang
+          CXX: clang++
       - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
         if: always()  # Upload artifacts even if the build or test suite fails
         with:
@@ -241,16 +244,16 @@
       fail-fast: false
       matrix:
         include:
-        - { config: clang-cl-dll, mingw: false }
-        - { config: clang-cl-static, mingw: false }
-        - { config: clang-cl-no-vcruntime, mingw: false }
-        - { config: clang-cl-debug, mingw: false }
-        - { config: clang-cl-static-crt, mingw: false }
-        - { config: mingw-dll, mingw: true }
-        - { config: mingw-static, mingw: true }
-        - { config: mingw-dll-i686, mingw: true }
-        - { config: mingw-incomplete-sysroot, mingw: true }
-        - { config: mingw-static, mingw: true, runner: windows-11-arm }
+        - { config: clang-cl-dll,             mingw: false, cc: clang-cl, cxx: clang-cl }
+        - { config: clang-cl-static,          mingw: false, cc: clang-cl, cxx: clang-cl }
+        - { config: clang-cl-no-vcruntime,    mingw: false, cc: clang-cl, cxx: clang-cl }
+        - { config: clang-cl-debug,           mingw: false, cc: clang-cl, cxx: clang-cl }
+        - { config: clang-cl-static-crt,      mingw: false, cc: clang-cl, cxx: clang-cl }
+        - { config: mingw-dll,                mingw: true,  cc: cc,       cxx: c++ }
+        - { config: mingw-dll,                mingw: true,  cc: i686-w64-mingw32-clang, cxx: i686-w64-mingw32-clang++ }
+        - { config: mingw-static,             mingw: true,  cc: cc,       cxx: c++ }
+        - { config: mingw-incomplete-sysroot, mingw: true,  cc: cc,       cxx: c++ }
+        - { config: mingw-static,             mingw: true,  cc: cc,       cxx: c++, runner: windows-11-arm }
     runs-on: ${{ matrix.runner != '' && matrix.runner || 'windows-2022' }}
     steps:
       - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
@@ -286,5 +289,7 @@
         run: |
           echo "c:\Program Files\LLVM\bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append
       - name: Build and test
-        run: |
-          bash libcxx/utils/ci/run-buildbot ${{ matrix.config }}
+        run: bash libcxx/utils/ci/run-buildbot ${{ matrix.config }}
+        env:
+          CC: ${{ matrix.cc }}
+          CXX: ${{ matrix.cxx }}
diff --git a/.github/workflows/libcxx-check-generated-files.yml b/.github/workflows/libcxx-check-generated-files.yml
index a25dc8b..ae1f680 100644
--- a/.github/workflows/libcxx-check-generated-files.yml
+++ b/.github/workflows/libcxx-check-generated-files.yml
@@ -22,3 +22,6 @@
 
       - name: Check generated files
         run: libcxx/utils/ci/run-buildbot check-generated-output
+        env:
+          CC: cc
+          CXX: c++
diff --git a/libcxx/docs/AddingNewCIJobs.rst b/libcxx/docs/AddingNewCIJobs.rst
index 9d749c0..7a12728 100644
--- a/libcxx/docs/AddingNewCIJobs.rst
+++ b/libcxx/docs/AddingNewCIJobs.rst
@@ -28,6 +28,9 @@
 
   - label: "C++11"
     command: "libcxx/utils/ci/run-buildbot generic-cxx11"
+    env:
+      CC: clang
+      CXX: clang++
     artifact_paths:
       - "**/test-results.xml"
     agents:
diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml
index 2ac69c3..1938d9a 100644
--- a/libcxx/utils/ci/buildkite-pipeline.yml
+++ b/libcxx/utils/ci/buildkite-pipeline.yml
@@ -37,6 +37,9 @@
   steps:
   - label: AArch64
     command: libcxx/utils/ci/run-buildbot aarch64
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: aarch64
@@ -44,6 +47,9 @@
 
   - label: AArch64 -fno-exceptions
     command: libcxx/utils/ci/run-buildbot aarch64-no-exceptions
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: aarch64
@@ -51,6 +57,9 @@
 
   - label: Armv8
     command: libcxx/utils/ci/run-buildbot armv8
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: armv8l
@@ -58,6 +67,9 @@
 
   - label: Armv8 -fno-exceptions
     command: libcxx/utils/ci/run-buildbot armv8-no-exceptions
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: armv8l
@@ -65,6 +77,9 @@
 
   - label: Armv7
     command: libcxx/utils/ci/run-buildbot armv7
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: armv8l
@@ -72,6 +87,9 @@
 
   - label: Armv7 -fno-exceptions
     command: libcxx/utils/ci/run-buildbot armv7-no-exceptions
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: armv8l
@@ -79,6 +97,9 @@
 
   - label: Armv7-M picolibc
     command: libcxx/utils/ci/run-buildbot armv7m-picolibc
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: aarch64
@@ -86,6 +107,9 @@
 
   - label: Armv7-M picolibc -fno-exceptions
     command: libcxx/utils/ci/run-buildbot armv7m-picolibc-no-exceptions
+    env:
+      CC: cc
+      CXX: c++
     agents:
       queue: libcxx-builders-linaro-arm
       arch: aarch64
@@ -131,6 +155,9 @@
   steps:
   - label: Android 5.0, x86 NDK
     command: libcxx/utils/ci/run-buildbot android-ndk-21-def-x86
+    env:
+      CC: /opt/android/clang/clang-current/bin/clang
+      CXX: /opt/android/clang/clang-current/bin/clang++
     agents:
       queue: libcxx-builders
       os: android
@@ -138,6 +165,9 @@
 
   - label: Android 13, x86_64 NDK
     command: libcxx/utils/ci/run-buildbot android-ndk-33-goog-x86_64
+    env:
+      CC: /opt/android/clang/clang-current/bin/clang
+      CXX: /opt/android/clang/clang-current/bin/clang++
     agents:
       queue: libcxx-builders
       os: android
diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot
index 8ab6a94e..b8ff947 100755
--- a/libcxx/utils/ci/run-buildbot
+++ b/libcxx/utils/ci/run-buildbot
@@ -30,17 +30,41 @@
 
 Environment variables
 CC                  The C compiler to use, this value is used by CMake. This
-                    variable is optional.
+                    variable is mandatory.
 
 CXX                 The C++ compiler to use, this value is used by CMake. This
-                    variable is optional.
+                    variable is mandatory.
 
-CLANG_FORMAT        The clang-format binary to use when generating the format
-                    ignore list.
-
+CCACHE              The ccache binary to use. This variable is optional and is only
+                    used by the bootstrapping build.
 EOF
 }
 
+function step() {
+  endstep
+  set +x
+  if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then
+    echo "::group::$1"
+    export IN_GROUP=1
+  else
+    echo "--- $1"
+  fi
+  set -x
+}
+
+function endstep() {
+  set +x
+  if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then
+    echo "::endgroup::"
+    unset IN_GROUP
+  fi
+  set -x
+}
+
+function error() {
+    echo "::error::$1"
+}
+
 if [[ $# == 0 ]]; then
    usage
    exit 0
@@ -71,30 +95,22 @@
 BUILD_DIR="${BUILD_DIR:=${MONOREPO_ROOT}/build/${BUILDER}}"
 INSTALL_DIR="${BUILD_DIR}/install"
 
-function step() {
-  endstep
-  set +x
-  if [[ ! -z ${GITHUB_ACTIONS+x} ]]; then
-    echo "::group::$1"
-    export IN_GROUP=1
-  else
-    echo "--- $1"
-  fi
-  set -x
-}
+if [ -z ${CC+x} ]; then
+    error "Environment variable CC must be defined"
+    exit 1
+fi
 
-function endstep() {
-  set +x
-  if [[ ! -z ${GITHUB_ACTIONS+x} ]] && [[ ! -z ${IN_GROUP+x} ]]; then
-    echo "::endgroup::"
-    unset IN_GROUP
-  fi
-  set -x
-}
+if [ -z ${CXX+x} ]; then
+    error "Environment variable CXX must be defined"
+    exit 1
+fi
 
-function error() {
-    echo "::error::$1"
-}
+# Print the version of a few tools to aid diagnostics in some cases
+step "Diagnose tools in use"
+cmake --version
+ninja --version
+${CC} --version
+${CXX} --version
 
 function clean() {
     rm -rf "${BUILD_DIR}"
@@ -127,11 +143,7 @@
 }
 
 function generate-cmake-libcxx-win() {
-    generate-cmake-base \
-          -DLLVM_ENABLE_RUNTIMES="libcxx" \
-          -DCMAKE_C_COMPILER=clang-cl \
-          -DCMAKE_CXX_COMPILER=clang-cl \
-          "${@}"
+    generate-cmake-base -DLLVM_ENABLE_RUNTIMES="libcxx" "${@}"
 }
 
 function generate-cmake-android() {
@@ -216,12 +228,6 @@
     check-runtimes
 }
 
-# Print the version of a few tools to aid diagnostics in some cases
-step "Diagnose tools in use"
-cmake --version
-ninja --version
-if [ ! -z "${CXX}" ]; then ${CXX} --version; fi
-
 case "${BUILDER}" in
 check-generated-output)
     # `! foo` doesn't work properly with `set -e`, use `! foo || false` instead.
@@ -358,12 +364,16 @@
 bootstrapping-build)
     clean
 
+    if [ ! -z ${CCACHE+x} ]; then
+        COMPILER_LAUNCHER="-DCMAKE_CXX_COMPILER_LAUNCHER=${CCACHE}"
+    fi
+
     step "Generating CMake"
     cmake \
           -S "${MONOREPO_ROOT}/llvm" \
           -B "${BUILD_DIR}" \
           -GNinja \
-          -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
+          ${COMPILER_LAUNCHER} \
           -DCMAKE_BUILD_TYPE=Release \
           -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
           -DLLVM_ENABLE_PROJECTS="clang;lldb" \
@@ -691,14 +701,6 @@
           -DLIBUNWIND_ENABLE_SHARED=OFF
     check-runtimes
 ;;
-mingw-dll-i686)
-    clean
-    generate-cmake \
-          -DCMAKE_C_COMPILER=i686-w64-mingw32-clang \
-          -DCMAKE_CXX_COMPILER=i686-w64-mingw32-clang++ \
-          -C "${MONOREPO_ROOT}/libcxx/cmake/caches/MinGW.cmake"
-    check-runtimes
-;;
 mingw-incomplete-sysroot)
     # When bringing up a new cross compiler from scratch, we build
     # libunwind/libcxx in a setup where the toolchain is incomplete and
@@ -743,10 +745,6 @@
     fi
     ARCH=$(arch_of_emu_img ${ANDROID_EMU_IMG})
 
-    # Use the Android compiler by default.
-    export CC=${CC:-/opt/android/clang/clang-current/bin/clang}
-    export CXX=${CXX:-/opt/android/clang/clang-current/bin/clang++}
-
     # The NDK libc++_shared.so is always built against the oldest supported API
     # level. When tests are run against a device with a newer API level, test
     # programs can be built for any supported API level, but building for the