mirror of
https://github.com/OPM/ResInsight.git
synced 2026-11-01 16:43:03 -06:00
210 lines
9.8 KiB
Docker
210 lines
9.8 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# =============================================================================
|
|
# RHEL8 (Rocky Linux 8) CI image for ResInsight.
|
|
#
|
|
# Bakes in:
|
|
# * The toolchain (gcc-toolset-14, libstdc++exp, Qt)
|
|
# * A prebuilt vcpkg binary cache (populated from the manifest)
|
|
# * A warm ResInsight buildcache populated by a full ResInsight-tests compile
|
|
# at the fixed path /src -> /src/cmakebuild.
|
|
#
|
|
# The CI workflow runs inside this image, checks out into /src (path must
|
|
# match the warmup so buildcache hashes line up), and only recompiles
|
|
# translation units that actually changed.
|
|
#
|
|
# Rebuilt nightly by .github/workflows/build-rhel8-image.yml.
|
|
# =============================================================================
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Stage 1: base toolchain
|
|
# -----------------------------------------------------------------------------
|
|
FROM rockylinux:8 AS base
|
|
|
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|
|
|
# Base development tools and libraries.
|
|
RUN dnf install -y epel-release \
|
|
&& dnf config-manager --set-enabled powertools \
|
|
&& dnf install -y \
|
|
gcc gcc-c++ make cmake ninja-build git curl zip unzip tar \
|
|
pkgconfig perl which xz flex bison \
|
|
python39 python39-devel python39-pip \
|
|
mesa-libGL-devel mesa-libGLU-devel mesa-libEGL-devel \
|
|
libxkbcommon-devel libxkbcommon-x11-devel \
|
|
xcb-util-keysyms-devel xcb-util-image-devel xcb-util-wm-devel \
|
|
xcb-util-renderutil-devel \
|
|
fontconfig-devel freetype-devel \
|
|
libX11-devel libXext-devel libXrender-devel \
|
|
&& dnf install -y \
|
|
gcc-toolset-14 gcc-toolset-14-gcc-c++ \
|
|
gcc-toolset-14-libatomic-devel gcc-toolset-14-libstdc++-devel \
|
|
&& dnf clean all
|
|
|
|
# Build libstdc++exp from GCC source to match gcc-toolset-14.
|
|
RUN source /opt/rh/gcc-toolset-14/enable \
|
|
&& GCC_FULL_VERSION=$(gcc -dumpfullversion) \
|
|
&& GCC_MAJOR_MINOR=$(echo "$GCC_FULL_VERSION" | cut -d. -f1,2) \
|
|
&& GCC_VERSION="${GCC_MAJOR_MINOR}.0" \
|
|
&& cd /tmp \
|
|
&& curl -LO "https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.xz" \
|
|
&& tar xf "gcc-${GCC_VERSION}.tar.xz" \
|
|
&& mkdir -p "gcc-${GCC_VERSION}/build-libstdcxx" \
|
|
&& cd "gcc-${GCC_VERSION}/build-libstdcxx" \
|
|
&& ../libstdc++-v3/configure \
|
|
--prefix=/opt/libstdcxx-exp \
|
|
--disable-multilib \
|
|
--disable-libstdcxx-pch \
|
|
--with-gxx-include-dir="/opt/rh/gcc-toolset-14/root/usr/include/c++/${GCC_VERSION}" \
|
|
&& { make -k -j"$(nproc)" || true; } \
|
|
&& test -f src/experimental/.libs/libstdc++exp.a \
|
|
&& mkdir -p /opt/libstdcxx-exp/lib \
|
|
&& cp src/experimental/.libs/libstdc++exp.a /opt/libstdcxx-exp/lib/ \
|
|
&& rm -rf /tmp/gcc-*
|
|
|
|
# Python and Qt.
|
|
ARG QT_VERSION=6.6.3
|
|
RUN alternatives --set python3 /usr/bin/python3.9 \
|
|
&& python3 -m pip install --upgrade pip \
|
|
&& python3 -m pip install grpcio-tools aqtinstall \
|
|
&& python3 -m aqt install-qt linux desktop "${QT_VERSION}" gcc_64 \
|
|
-O /opt/Qt --modules qtnetworkauth
|
|
|
|
ENV Qt6_DIR=/opt/Qt/${QT_VERSION}/gcc_64 \
|
|
CMAKE_PREFIX_PATH=/opt/Qt/${QT_VERSION}/gcc_64 \
|
|
PATH=/opt/Qt/${QT_VERSION}/gcc_64/bin:${PATH}
|
|
|
|
# buildcache (pinned, built from source). When this binary is on PATH at CMake
|
|
# configure time, the project's top-level CMakeLists.txt auto-detects it via
|
|
# find_program() and wires CMAKE_CXX_COMPILER_LAUNCHER. No further CMake
|
|
# plumbing is needed.
|
|
#
|
|
# Built from source rather than downloaded because the upstream
|
|
# `buildcache-linux.tar.gz` release binary is linked against glibc 2.29+, and
|
|
# Rocky Linux 8 ships glibc 2.28 -- the binary loads but crashes the first
|
|
# time the dynamic linker touches libm. Compiling here links against the
|
|
# image's own glibc and is portable (~1-2 minutes).
|
|
# Source from GitLab -- the canonical repo. The GitHub mirror is stale (last
|
|
# tag v0.28.4, 2024-03), while GitLab has progressed to v0.33.0 with the GCC
|
|
# 14 transitive-include fixes that v0.28.x lacks.
|
|
ARG BUILDCACHE_VERSION=v0.33.0
|
|
RUN source /opt/rh/gcc-toolset-14/enable \
|
|
&& git clone --depth 1 --branch "${BUILDCACHE_VERSION}" \
|
|
https://gitlab.com/bits-n-bites/buildcache.git /tmp/buildcache-src \
|
|
&& cmake -S /tmp/buildcache-src/src -B /tmp/buildcache-build -G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
|
|
&& cmake --build /tmp/buildcache-build --target install \
|
|
&& rm -rf /tmp/buildcache-src /tmp/buildcache-build \
|
|
&& buildcache --version
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Stage 2: populate the vcpkg binary cache
|
|
# -----------------------------------------------------------------------------
|
|
FROM base AS vcpkg-builder
|
|
|
|
ENV VCPKG_DEFAULT_BINARY_CACHE=/opt/vcpkg-cache
|
|
|
|
COPY . /src
|
|
|
|
# Running the ResInsight CMake configure triggers a vcpkg manifest install,
|
|
# which compiles every dependency into VCPKG_DEFAULT_BINARY_CACHE. The same
|
|
# toolchain is used here and in the final image, so the vcpkg ABI hashes match
|
|
# and the cache is reused by CI builds. Later configure steps may fail inside
|
|
# the build container; that is tolerated as the dependencies are already built
|
|
# by then.
|
|
#
|
|
# After configure, verify the cache contains a plausible number of entries.
|
|
# vcpkg's `files` binary provider stores one .zip per package under
|
|
# <cache>/<2-hex>/<full-hash>.zip. ResInsight depends on ~30+ packages, so a
|
|
# threshold of 20 catches the failure mode where the configure dies early
|
|
# (e.g. after building only a handful of leaf deps) while staying robust to
|
|
# small manifest churn.
|
|
RUN git config --global --add safe.directory '*' \
|
|
&& cp /src/vcpkg-configuration-rhel8.json /src/vcpkg-configuration.json \
|
|
&& mkdir -p "${VCPKG_DEFAULT_BINARY_CACHE}" \
|
|
&& source /opt/rh/gcc-toolset-14/enable \
|
|
&& ( cd /src/ThirdParty/vcpkg && ./bootstrap-vcpkg.sh ) \
|
|
&& export CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc \
|
|
&& export CXX=/opt/rh/gcc-toolset-14/root/usr/bin/g++ \
|
|
&& { cmake -S /src -B /tmp/cfg -G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DRESINSIGHT_INCLUDE_APPLICATION_UNIT_TESTS=true \
|
|
-DRESINSIGHT_ENABLE_UNITY_BUILD=true \
|
|
-DRESINSIGHT_ENABLE_HDF5=false \
|
|
-DRESINSIGHT_ENABLE_GRPC=false \
|
|
-DRESINSIGHT_GCC_STDCPP_EXP_PATH=/opt/libstdcxx-exp/lib \
|
|
-DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
|
|| true; } \
|
|
&& vcpkg_zip_count=$(find "${VCPKG_DEFAULT_BINARY_CACHE}" -type f -name '*.zip' | wc -l) \
|
|
&& echo "vcpkg binary cache entries: ${vcpkg_zip_count}" \
|
|
&& test "${vcpkg_zip_count}" -ge 20 \
|
|
&& rm -rf /tmp/cfg /src
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Stage 3: warm the ResInsight buildcache by performing a full compile at
|
|
# /src -> /src/cmakebuild. CI runs at the same paths to get cache
|
|
# hits (buildcache hashes the absolute source path).
|
|
# -----------------------------------------------------------------------------
|
|
FROM base AS build-warmup
|
|
|
|
# Cap at 4 GB. The baked cache from this stage is what CI reads, and CI also
|
|
# writes back to the same /opt/buildcache, so the cap must be larger than
|
|
# (baked entries + per-run accumulation) or LRU eviction starts dropping baked
|
|
# entries between nightly rebuilds. 4 GB comfortably exceeds the observed
|
|
# warm cache size for a full ResInsight-tests compile.
|
|
ENV BUILDCACHE_ACCURACY=SLOPPY \
|
|
BUILDCACHE_MAX_CACHE_SIZE=4294967296
|
|
|
|
COPY --from=vcpkg-builder /opt/vcpkg-cache /opt/vcpkg-cache
|
|
COPY . /src
|
|
|
|
# The buildcache directory is mounted as a BuildKit cache mount so it persists
|
|
# across nightly image rebuilds (each rebuild only recompiles drift since the
|
|
# previous run). After the compile finishes the populated cache is copied into
|
|
# /opt/buildcache, a real path that is preserved in the image layer.
|
|
#
|
|
# Unity build is OFF here AND in the consumer workflow: with unity ON, a single
|
|
# .cpp change invalidates the whole unity blob's cache entry, defeating the
|
|
# point. The flag must match between this stage and CI or hit rate collapses
|
|
# (the command line is part of the hash).
|
|
RUN --mount=type=cache,id=ri-rhel8-buildcache,target=/var/cache/buildcache,sharing=locked \
|
|
git config --global --add safe.directory '*' \
|
|
&& cp /src/vcpkg-configuration-rhel8.json /src/vcpkg-configuration.json \
|
|
&& source /opt/rh/gcc-toolset-14/enable \
|
|
&& ( cd /src/ThirdParty/vcpkg && ./bootstrap-vcpkg.sh ) \
|
|
&& export CC=/opt/rh/gcc-toolset-14/root/usr/bin/gcc \
|
|
&& export CXX=/opt/rh/gcc-toolset-14/root/usr/bin/g++ \
|
|
&& export VCPKG_FEATURE_FLAGS=binarycaching \
|
|
&& export VCPKG_BINARY_SOURCES="clear;files,/opt/vcpkg-cache,read" \
|
|
&& export BUILDCACHE_DIR=/var/cache/buildcache \
|
|
&& cmake -S /src -B /src/cmakebuild -G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DRESINSIGHT_INCLUDE_APPLICATION_UNIT_TESTS=true \
|
|
-DRESINSIGHT_ENABLE_UNITY_BUILD=false \
|
|
-DRESINSIGHT_ENABLE_HDF5=false \
|
|
-DRESINSIGHT_ENABLE_GRPC=false \
|
|
-DRESINSIGHT_GCC_STDCPP_EXP_PATH=/opt/libstdcxx-exp/lib \
|
|
-DCMAKE_TOOLCHAIN_FILE=ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
|
&& cmake --build /src/cmakebuild --target ResInsight-tests -- -j"$(nproc)" \
|
|
&& buildcache -s \
|
|
&& mkdir -p /opt/buildcache \
|
|
&& cp -a /var/cache/buildcache/. /opt/buildcache/ \
|
|
&& test -n "$(ls -A /opt/buildcache)" \
|
|
&& rm -rf /src
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Stage 4: final image
|
|
# -----------------------------------------------------------------------------
|
|
FROM base
|
|
|
|
LABEL org.opencontainers.image.source="https://github.com/OPM/ResInsight"
|
|
LABEL org.opencontainers.image.description="RHEL8 CI image for ResInsight with prebuilt toolchain, vcpkg binary cache, and warm ResInsight buildcache"
|
|
|
|
COPY --from=vcpkg-builder /opt/vcpkg-cache /opt/vcpkg-cache
|
|
COPY --from=build-warmup /opt/buildcache /opt/buildcache
|
|
|
|
ENV VCPKG_DEFAULT_BINARY_CACHE=/opt/vcpkg-cache \
|
|
BUILDCACHE_DIR=/opt/buildcache \
|
|
BUILDCACHE_ACCURACY=SLOPPY \
|
|
BUILDCACHE_MAX_CACHE_SIZE=4294967296
|