[libcxx-commits] [libcxx] Restrategize compiler installation in libc++ builders. (PR #95706)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jun 16 06:57:35 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Eric (EricWF)
<details>
<summary>Changes</summary>
This patch changes how we install compilers and tools in the libc++
builders. Instead of using apt, we now use separate tool images
containing one tool per image; copying the tool from the tool image
into the builder image directly.
The tool images are created using compiler-explorer-infra, though
this is largely a convience. The important aspect is that each
tool is installed under a different prefix inside the tool image,
meaning each tool is independent and doesn't conflict or clobber
other installations.
This change has passed a few breathing tests, but I'll canary
new generated images today.
---
Full diff: https://github.com/llvm/llvm-project/pull/95706.diff
2 Files Affected:
- (modified) libcxx/utils/ci/Dockerfile (+53-53)
- (added) libcxx/utils/ci/Dockerfile.tools (+115)
``````````diff
diff --git a/libcxx/utils/ci/Dockerfile b/libcxx/utils/ci/Dockerfile
index 54dd0f1186880..0f62026625402 100644
--- a/libcxx/utils/ci/Dockerfile
+++ b/libcxx/utils/ci/Dockerfile
@@ -48,14 +48,6 @@ FROM $BASE_IMAGE AS builder-base
# 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 GCC_LATEST_VERSION
-ENV GCC_LATEST_VERSION=${GCC_LATEST_VERSION}
-
-# populated in the docker-compose file
-ARG LLVM_HEAD_VERSION
-ENV LLVM_HEAD_VERSION=${LLVM_HEAD_VERSION}
-
# HACK: The github actions runner image already has sudo and requires its use. The buildkite base image does not.
# Reconcile this.
RUN <<EOF
@@ -73,6 +65,7 @@ RUN sudo apt-get update \
RUN sudo apt-get update \
&& sudo apt-get install -y \
bash \
+ build-essential \
ccache \
curl \
gdb \
@@ -101,16 +94,6 @@ RUN sudo apt-get update \
&& sudo rm -rf /var/lib/apt/lists/*
-# Install various tools used by the build or the test suite
-#RUN apt-get update && apt-get install -y ninja-build python3 python3-distutils python3-psutil git gdb ccache
-# TODO add ninja-build once 1.11 is available in Ubuntu, also remove the manual installation.
-RUN <<EOF
- wget -qO /tmp/ninja.gz https://github.com/ninja-build/ninja/releases/latest/download/ninja-linux.zip
- gunzip /tmp/ninja.gz
- chmod a+x /tmp/ninja
- sudo mv /tmp/ninja /usr/local/bin/ninja
-EOF
-
# These two locales are not enabled by default so generate them
RUN <<EOF
@@ -120,43 +103,60 @@ RUN <<EOF
sudo locale-gen
EOF
-# Install Clang <latest>, <latest-1> and ToT, which are the ones we support.
-# We also install <latest-2> because we need to support the "latest-1" of the
-# current LLVM release branch, which is effectively the <latest-2> of the
-# tip-of-trunk LLVM. For example, after branching LLVM 14 but before branching
-# LLVM 15, we still need to have Clang 12 in this Docker image because the LLVM
-# 14 release branch CI uses it. The tip-of-trunk CI will never use Clang 12,
-# though.
-RUN <<EOF
- sudo apt-get update
- wget https://apt.llvm.org/llvm.sh -O /tmp/llvm.sh
- chmod +x /tmp/llvm.sh
- sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 3)) all # for CI transitions
- sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 2)) all # previous release
- sudo /tmp/llvm.sh $(($LLVM_HEAD_VERSION - 1)) all # latest release
- sudo /tmp/llvm.sh $LLVM_HEAD_VERSION all # current ToT
- sudo apt-get install -y libomp5-$LLVM_HEAD_VERSION
- sudo rm -rf /var/lib/apt/lists/*
-EOF
+# See Dockerfile.tools for information on how to produce the tool images.
+RUN sudo mkdir /opt/libcxx-infra && sudo chown -R $(whoami):$(whoami) /opt/libcxx-infra
+COPY --from=ghcr.io/libcxx/tools:cmake-3.27.9 /opt/libcxx-infra/cmake-v3.27.9 /opt/libcxx-infra/cmake-3.27.9
+COPY --from=ghcr.io/libcxx/tools:ninja-1.11.1 /opt/libcxx-infra/ninja-v1.11.1 /opt/libcxx-infra/ninja-1.11.1
-# Install the most recent GCC, like clang install the previous version as a transition.
-RUN <<EOF
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test
- sudo apt-get update
- sudo apt-get install -y \
- gcc-$((GCC_LATEST_VERSION - 1)) \
- g++-$((GCC_LATEST_VERSION - 1)) \
- gcc-$GCC_LATEST_VERSION \
- g++-$GCC_LATEST_VERSION
- sudo rm -rf /var/lib/apt/lists/*
-EOF
+# Install the GCC versions
+COPY --from=ghcr.io/libcxx/tools:gcc-13.3.0 /opt/libcxx-infra/gcc-13.3.0 /opt/libcxx-infra/gcc-13.3.0
+COPY --from=ghcr.io/libcxx/tools:gcc-14.1.0 /opt/libcxx-infra/gcc-14.1.0 /opt/libcxx-infra/gcc-14.1.0
-RUN <<EOF
- # Install a recent CMake
- wget https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.sh -O /tmp/install-cmake.sh
- sudo bash /tmp/install-cmake.sh --prefix=/usr --exclude-subdir --skip-license
- rm /tmp/install-cmake.sh
-EOF
+COPY --from=ghcr.io/libcxx/tools:clang-16.0.0 /opt/libcxx-infra/clang-16.0.0 /opt/libcxx-infra/clang-16.0.0
+COPY --from=ghcr.io/libcxx/tools:clang-17.0.1 /opt/libcxx-infra/clang-17.0.1 /opt/libcxx-infra/clang-17.0.1
+COPY --from=ghcr.io/libcxx/tools:clang-18.1.0 /opt/libcxx-infra/clang-18.1.0 /opt/libcxx-infra/clang-18.1.0
+COPY --from=ghcr.io/libcxx/tools:clang-trunk-20240615 /opt/libcxx-infra/clang-trunk-20240615 /opt/libcxx-infra/clang-trunk
+
+# Create /opt/libcxx-infra/bin/ to store the executables we want to use/test against for both the tools (ninja/cmake)
+# and the compilers (clang/gcc). The compilers are symlinked with a name that includes the major version.
+#
+# The binaries that are symlinked are:
+# - ninja
+# - cmake
+# - clang-<version>
+# - clang++-<version>
+# - gcc-<version>
+# - g++-<version>
+# - llvm-symbolizer-<version> (likely only the latest clang version)
+RUN mkdir /opt/libcxx-infra/bin/ \
+ && ln -s /opt/libcxx-infra/ninja-1.11.1/ninja /opt/libcxx-infra/bin/ninja \
+ && ln -s /opt/libcxx-infra/cmake-3.27.9/bin/cmake /opt/libcxx-infra/bin/cmake \
+ && ln -s /opt/libcxx-infra/clang-16.0.0/bin/clang /opt/libcxx-infra/bin/clang-16 \
+ && ln -s /opt/libcxx-infra/clang-16.0.0/bin/clang++ /opt/libcxx-infra/bin/clang++-16 \
+ && ln -s /opt/libcxx-infra/clang-17.0.1/bin/clang /opt/libcxx-infra/bin/clang-17 \
+ && ln -s /opt/libcxx-infra/clang-17.0.1/bin/clang++ /opt/libcxx-infra/bin/clang++-17 \
+ && ln -s /opt/libcxx-infra/clang-18.1.0/bin/clang /opt/libcxx-infra/bin/clang-18 \
+ && ln -s /opt/libcxx-infra/clang-18.1.0/bin/clang++ /opt/libcxx-infra/bin/clang++-18 \
+ && ln -s /opt/libcxx-infra/clang-trunk/bin/clang /opt/libcxx-infra/bin/clang-19 \
+ && ln -s /opt/libcxx-infra/clang-trunk/bin/clang++ /opt/libcxx-infra/bin/clang++-19 \
+ && ln -s /opt/libcxx-infra/clang-trunk/bin/llvm-symbolizer /opt/libcxx-infra/bin/llvm-symbolizer-19 \
+ && ln -s /opt/libcxx-infra/gcc-13.3.0/bin/gcc /opt/libcxx-infra/bin/gcc-13 \
+ && ln -s /opt/libcxx-infra/gcc-13.3.0/bin/g++ /opt/libcxx-infra/bin/g++-13 \
+ && ln -s /opt/libcxx-infra/gcc-14.1.0/bin/gcc /opt/libcxx-infra/bin/gcc-14 \
+ && ln -s /opt/libcxx-infra/gcc-14.1.0/bin/g++ /opt/libcxx-infra/bin/g++-14
+
+
+ENV PATH="/opt/libcxx-infra/bin:${PATH}"
+
+RUN echo "testing Ninja" && ninja --version \
+ && echo "testing CMake" && cmake --version \
+ && echo "testing Clang 16" && clang-16 --version \
+ && echo "testing Clang 17" && clang-17 --version \
+ && echo "testing Clang 18" && clang-18 --version \
+ && echo "testing Clang 19" && clang-19 --version \
+ && echo "testing LLVM symbolizer 19" && llvm-symbolizer-19 --version \
+ && echo "testing GCC 13" && gcc-13 --version \
+ && echo "testing GCC 14" && gcc-14 --version
# ===----------------------------------------------------------------------===##
# Android Buildkite Image
diff --git a/libcxx/utils/ci/Dockerfile.tools b/libcxx/utils/ci/Dockerfile.tools
new file mode 100644
index 0000000000000..fc3cf84103f36
--- /dev/null
+++ b/libcxx/utils/ci/Dockerfile.tools
@@ -0,0 +1,115 @@
+#===----------------------------------------------------------------------===##
+#
+# 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 image is used to create the ghcr.io/tools:<tool:version> packages consumed by the libc++ builders.
+# Each image contains a single tool, and is created by installing the tool from Compiler Explorer's infra repository
+# into /opt/libcxx-infra/<tool>-<version>.
+#
+# The image is then copied into the final image libc++ builder image.
+#
+# This allows us to install tools independently of APT, and allows us to version the tools using docker tags, avoiding
+# issues with nightly builds polluting the other packages installed via apt.
+#
+# See https://github.com/compiler-explorer/infra for more information on the tools available.
+#
+# To create a new tool image using this Dockerfile, you need to set the following build arguments:
+# - TOOL_ID: The ID of the tool to install. This is the name of the tool as it appears in the list of tools available
+# in the infra repository.
+# Some examples of tool id's are:
+# - compilers/c++/clang 16.0.0
+# - compilers/c++/clang trunk (the nightly)
+# - compilers/c++/x86/gcc 13.0.0
+# - tools/ninja 1.11.1
+# - tools/cmake 3.22.0
+# - NIGHTLY: Whether to install the nightly version of the tool. This is a boolean value, and must be either 'true' or
+# 'false'. Must be set to 'true' to install the nightly version of the tool.
+#
+# Example usage:
+# docker build \
+# --build-arg 'TOOL_ID=compilers/c++/clang trunk' \
+# --build-arg NIGHTLY=true \
+# -t ghcr.io/libcxx/tools:clang-trunk-YYYYMMDD \
+# -f Dockerfile.tools .
+
+# Images built from nightly tools should be tagged with the suffix -YYYYMMDD, where YYYYMMDD is the date of the nightly
+# See the build-tool-image.yaml workflow in github.com/libcxx/builders
+FROM ubuntu:jammy-20240530 AS tool-installer
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ bash \
+ curl \
+ git \
+ make \
+ python3 \
+ python3-venv \
+ python3-pip \
+ uuid-dev \
+ wget \
+ unzip \
+ xz-utils \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN git clone --depth=1 https://github.com/compiler-explorer/infra.git infra \
+ && cd infra/ \
+ && rm -rf .git \
+ && python3 -m venv .venv \
+ && . ./.venv/bin/activate \
+ && make ce \
+ && ./bin/ce_install list
+
+
+COPY <<EOF /usr/bin/installer
+#!/usr/bin/env bash
+set -ex
+set -o pipefail
+
+
+ARGS=()
+
+. /infra/.venv/bin/activate
+
+mkdir /tmp/staging
+mkdir /opt/libcxx-infra
+
+if [[ "\$NIGHTLY" == "true" ]]; then
+ ARGS+=("--enable" "nightly")
+elif [[ "\$NIGHTLY" == "false" ]]; then
+ echo "Not nightly"
+else
+ echo "NIGHTLY must be either 'true' or 'false'"
+ exit 1
+fi
+
+if [[ -z "\$TOOL_ID" ]]; then
+ echo "TOOL_ID must be set"
+ exit 1
+fi
+
+/infra/bin/ce_install --staging-dir /tmp/staging --dest /opt/libcxx-infra "\${ARGS[@]}" install "\$TOOL_ID"
+
+rm -rf /tmp/staging
+EOF
+
+RUN chmod +x /usr/bin/installer
+
+FROM tool-installer AS install-tool
+
+ARG TOOL_ID
+ENV TOOL_ID=${TOOL_ID}
+
+ARG NIGHTLY=false
+ENV NIGHTLY=${NIGHTLY}
+
+
+RUN /usr/bin/installer
+
+# Use alpine as the base for the minimal final image. The image should only contain the tool, and will be copied into
+# other images that will eventually use it.
+FROM alpine AS installed-tool
+
+COPY --from=install-tool /opt/libcxx-infra /opt/libcxx-infra
``````````
</details>
https://github.com/llvm/llvm-project/pull/95706
More information about the libcxx-commits
mailing list