[libcxx] [llvm] [libc++][CI] Add hermetic Linux premerge builder (PR #226358)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 22:54:58 PDT 2026
https://github.com/zeroomega updated https://github.com/llvm/llvm-project/pull/226358
>From 1499a67389ca737651ca7ce71322eda1bc83ea37 Mon Sep 17 00:00:00 2001
From: Haowei Wu <haowei at google.com>
Date: Thu, 24 Sep 2026 22:53:36 -0700
Subject: [PATCH] [libc++][CI] Add hermetic Linux builder container and
run-buildbot support
Add a hermetic Linux builder container image and run-buildbot flags so
libc++ can be built and tested with CMake, Ninja, and Clang installed
under /opt/hermetic outside of PATH, catching implicit dependencies on
host build tools or compilers in CMake or Lit test scripts (such as
#224192).
- Add libcxx/utils/ci/docker/linux-builder-hermetic.dockerfile based
on ubuntu:26.04 with CMake, Ninja, and Compiler Explorer Clang
((LLVM_HEAD_VERSION - 1).1.0) installed under /opt/hermetic and no
cmake/ninja/make/gcc/g++/clang in PATH.
- Register libcxx-linux-builder-hermetic in docker-compose.yml and
.github/workflows/libcxx-build-containers.yml.
- Add --hermetic, --cmake, --ninja, --cc, and --cxx flags to
libcxx/utils/ci/run-buildbot, unexporting CMAKE/NINJA/CC/CXX when
--hermetic is set and passing CMAKE_C_COMPILER and CMAKE_CXX_COMPILER
explicitly to CMake.
Assisted-by: Gemini
---
.github/workflows/libcxx-build-containers.yml | 2 +-
libcxx/utils/ci/docker/docker-compose.yml | 10 ++
.../docker/linux-builder-hermetic.dockerfile | 102 ++++++++++++++++++
libcxx/utils/ci/run-buildbot | 44 +++++++-
4 files changed, 153 insertions(+), 5 deletions(-)
create mode 100644 libcxx/utils/ci/docker/linux-builder-hermetic.dockerfile
diff --git a/.github/workflows/libcxx-build-containers.yml b/.github/workflows/libcxx-build-containers.yml
index 5f24cc54021ad..6cce2b239dc19 100644
--- a/.github/workflows/libcxx-build-containers.yml
+++ b/.github/workflows/libcxx-build-containers.yml
@@ -28,7 +28,7 @@ jobs:
if: github.repository_owner == 'llvm'
strategy:
matrix:
- image_name: ['libcxx-linux-builder', 'libcxx-android-builder']
+ image_name: ['libcxx-linux-builder', 'libcxx-linux-builder-hermetic', 'libcxx-android-builder']
permissions:
packages: write
diff --git a/libcxx/utils/ci/docker/docker-compose.yml b/libcxx/utils/ci/docker/docker-compose.yml
index 2070dcd96274c..e2280af3d6ab8 100644
--- a/libcxx/utils/ci/docker/docker-compose.yml
+++ b/libcxx/utils/ci/docker/docker-compose.yml
@@ -17,6 +17,16 @@ services:
GCC_HEAD_VERSION: 17
LLVM_HEAD_VERSION: 23
+ libcxx-linux-builder-hermetic:
+ image: ghcr.io/llvm/libcxx-linux-builder-hermetic:${TAG:-latest}
+ build:
+ context: ../../../.. # monorepo root
+ dockerfile: libcxx/utils/ci/docker/linux-builder-hermetic.dockerfile
+ args:
+ LLVM_HEAD_VERSION: 23
+ CMAKE_VERSION: 4.4.3
+ NINJA_VERSION: 1.13.2
+
libcxx-android-builder:
image: ghcr.io/llvm/libcxx-android-builder:${TAG:-latest}
build:
diff --git a/libcxx/utils/ci/docker/linux-builder-hermetic.dockerfile b/libcxx/utils/ci/docker/linux-builder-hermetic.dockerfile
new file mode 100644
index 0000000000000..3cf1c15eb9431
--- /dev/null
+++ b/libcxx/utils/ci/docker/linux-builder-hermetic.dockerfile
@@ -0,0 +1,102 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+#
+# This file defines the hermetic Linux builder image used for libc++ CI testing
+# where CMake, Ninja, and Clang/LLVM are placed under /opt/hermetic outside of
+# PATH, catching any implicit dependencies on host build tools or compilers.
+#
+# From the root of the monorepo, this image can be built with:
+#
+# $ docker compose --file libcxx/utils/ci/docker/docker-compose.yml build libcxx-linux-builder-hermetic
+#
+
+FROM docker.io/library/ubuntu:26.04
+
+# Changing this file causes a rebuild of the image in a GitHub action.
+RUN echo "Last forced update executed on 2026-09-24."
+
+# Make sure apt-get doesn't try to prompt for stuff like our time zone, etc.
+ENV DEBIAN_FRONTEND=noninteractive
+
+# Populated in the docker-compose file
+ARG LLVM_HEAD_VERSION=23
+ENV LLVM_HEAD_VERSION=${LLVM_HEAD_VERSION}
+
+ARG CMAKE_VERSION=4.4.3
+ENV CMAKE_VERSION=${CMAKE_VERSION}
+
+ARG NINJA_VERSION=1.13.2
+ENV NINJA_VERSION=${NINJA_VERSION}
+
+# Install sudo and setup passwordless sudo.
+RUN apt-get update && \
+ apt-get install -y sudo && \
+ echo "ALL ALL = (ALL) NOPASSWD: ALL" | tee /etc/sudoers
+
+# Installing tzdata before other packages avoids the time zone prompts.
+RUN sudo apt-get update \
+ && sudo apt-get install -y \
+ tzdata
+
+# Install runtime/test utilities and the basic host C sysroot (libc6-dev, libgcc-15-dev).
+# Intentionally OMIT: build-essential, gcc, g++, clang, make, cmake, ninja-build.
+RUN sudo apt-get update \
+ && sudo apt-get install -y \
+ bash \
+ binutils \
+ bzip2 \
+ curl \
+ gdb \
+ git \
+ gpg \
+ language-pack-en \
+ language-pack-fr \
+ language-pack-ja \
+ language-pack-ru \
+ language-pack-zh-hans \
+ libc6-dev \
+ libgcc-15-dev \
+ libstdc++-15-dev \
+ lsb-release \
+ python3 \
+ python3-dev \
+ python3-packaging \
+ python3-psutil \
+ python3-setuptools \
+ python3-venv \
+ python3-yaml \
+ rsync \
+ unzip \
+ wget \
+ xz-utils \
+ && sudo rm -rf /var/lib/apt/lists/*
+
+# These two locales are not enabled by default so generate them
+RUN printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2\n" | sudo tee -a /etc/locale.gen && \
+ sudo mkdir -p /usr/local/share/i1en/ && \
+ printf "fr_CA ISO-8859-1\ncs_CZ ISO-8859-2\n" | sudo tee -a /usr/local/share/i1en/SUPPORTED && \
+ sudo locale-gen
+
+# Fetch CMake and Ninja from official GitHub releases, and Clang from Compiler Explorer
+# (matching linux-builder.dockerfile's ce_install and LLVM_HEAD_VERSION), into /opt/hermetic
+# outside of PATH.
+RUN sudo mkdir -p /opt/hermetic/cmake /opt/hermetic/ninja && \
+ curl -fsSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz" \
+ | sudo tar xzf - --strip-components=1 -C /opt/hermetic/cmake && \
+ curl -fsSL -o /tmp/ninja-linux.zip \
+ "https://github.com/ninja-build/ninja/releases/download/v${NINJA_VERSION}/ninja-linux.zip" && \
+ sudo unzip -q /tmp/ninja-linux.zip -d /opt/hermetic/ninja && \
+ sudo chmod +x /opt/hermetic/ninja/ninja && \
+ rm -f /tmp/ninja-linux.zip && \
+ sudo apt-get update && sudo apt-get install -y make && \
+ sudo git clone --depth 1 https://github.com/compiler-explorer/infra.git /tmp/ce-infra && \
+ (cd /tmp/ce-infra && sudo make ce) && \
+ sudo /tmp/ce-infra/bin/ce_install --dest /opt/hermetic install compilers/c++/clang $((LLVM_HEAD_VERSION - 1)).1.0 && \
+ sudo ln -sfn /opt/hermetic/clang-$((LLVM_HEAD_VERSION - 1)).1.0 /opt/hermetic/llvm && \
+ sudo rm -rf /tmp/ce-infra && \
+ sudo apt-get purge -y make && sudo apt-get autoremove -y && sudo rm -rf /var/lib/apt/lists/*
diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot
index 572f326c4fb0a..c90c2c0d4c393 100755
--- a/libcxx/utils/ci/run-buildbot
+++ b/libcxx/utils/ci/run-buildbot
@@ -28,6 +28,14 @@ ${PROGNAME} [options] <BUILDER>
--build-dir <DIR> The directory to use for building the library. By default,
this is '<llvm-root>/build/<builder>'.
+--cmake <PATH> Path to the cmake binary to use.
+
+--ninja <PATH> Path to the ninja binary to use.
+
+--cc <PATH> Path to the C compiler to use.
+
+--cxx <PATH> Path to the C++ compiler to use.
+
Environment variables
CMAKE The cmake binary to use. This variable is optional.
@@ -89,6 +97,26 @@ while [[ $# -gt 0 ]]; do
BUILD_DIR="${2}"
shift; shift
;;
+ --cmake)
+ CMAKE="${2}"
+ shift; shift
+ ;;
+ --ninja)
+ NINJA="${2}"
+ shift; shift
+ ;;
+ --cc)
+ CC="${2}"
+ shift; shift
+ ;;
+ --cxx)
+ CXX="${2}"
+ shift; shift
+ ;;
+ --hermetic)
+ HERMETIC=true
+ shift
+ ;;
*)
BUILDER="${1}"
shift
@@ -111,15 +139,19 @@ else
fi
if [ -z ${CC+x} ]; then
- error "Environment variable CC must be defined"
+ error "Environment variable CC or --cc must be defined"
exit 1
fi
if [ -z ${CXX+x} ]; then
- error "Environment variable CXX must be defined"
+ error "Environment variable CXX or --cxx must be defined"
exit 1
fi
+if [ -n "${HERMETIC+x}" ]; then
+ export -n CMAKE NINJA CC CXX
+fi
+
# Print the version of a few tools to aid diagnostics in some cases
step "Diagnose tools in use"
${CMAKE} --version
@@ -135,8 +167,10 @@ function generate-cmake-base() {
step "Generating CMake"
# FIXME: This should really be set in the Dockerfile
- export CMAKE_PREFIX_PATH="/opt/compiler-explorer/clang-trunk/lib/cmake"
- export PATH="$PATH:/opt/compiler-explorer/clang-trunk/bin"
+ if [ -z "${HERMETIC+x}" ]; then
+ export CMAKE_PREFIX_PATH="/opt/compiler-explorer/clang-trunk/lib/cmake"
+ export PATH="$PATH:/opt/compiler-explorer/clang-trunk/bin"
+ fi
# We can remove -DCMAKE_INSTALL_MESSAGE=NEVER once https://gitlab.kitware.com/cmake/cmake/-/issues/26085 is fixed.
${CMAKE} \
@@ -144,6 +178,8 @@ function generate-cmake-base() {
-B "${BUILD_DIR}" \
-GNinja \
${MAKE_PROGRAM} \
+ -DCMAKE_C_COMPILER="${CC}" \
+ -DCMAKE_CXX_COMPILER="${CXX}" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
-DLIBCXX_ENABLE_WERROR=YES \
More information about the llvm-commits
mailing list