Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/debian.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
paths:
- .github/workflows/debian.yml
- docker/debian/Dockerfile
- test

env:
CONTAINER_REGISTRY: ghcr.io
Expand Down Expand Up @@ -104,7 +105,8 @@ jobs:
GCOVR_VERSION=${{ env.GCOVR_VERSION }}
NONROOT_USER=${{ env.NONROOT_USER }}
DEBIAN_VERSION=${{ matrix.os.release }}
context: docker/debian
context: .
file: docker/debian/Dockerfile
outputs: type=image,name=${{ env.CONTAINER_IMAGE }},push-by-digest=true,name-canonical=true,push=true
platforms: ${{ matrix.architecture.platform }}
provenance: mode=max
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/rhel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
paths:
- .github/workflows/rhel.yml
- docker/rhel/Dockerfile
- test

env:
CONTAINER_REGISTRY: ghcr.io
Expand Down Expand Up @@ -94,7 +95,8 @@ jobs:
GCOVR_VERSION=${{ env.GCOVR_VERSION }}
NONROOT_USER=${{ env.NONROOT_USER }}
RHEL_VERSION=${{ matrix.os.release }}
context: docker/rhel
context: .
file: docker/rhel/Dockerfile
outputs: type=image,name=${{ env.CONTAINER_IMAGE }},push-by-digest=true,name-canonical=true,push=true
platforms: ${{ matrix.architecture.platform }}
provenance: mode=max
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
paths:
- .github/workflows/ubuntu.yml
- docker/ubuntu/Dockerfile
- test

env:
CONTAINER_REGISTRY: ghcr.io
Expand Down Expand Up @@ -102,7 +103,8 @@ jobs:
GCOVR_VERSION=${{ env.GCOVR_VERSION }}
NONROOT_USER=${{ env.NONROOT_USER }}
UBUNTU_VERSION=${{ matrix.os.release }}
context: docker/ubuntu
context: .
file: docker/ubuntu/Dockerfile
outputs: type=image,name=${{ env.CONTAINER_IMAGE }},push-by-digest=true,name-canonical=true,push=true
platforms: ${{ matrix.architecture.platform }}
provenance: mode=max
Expand Down
109 changes: 83 additions & 26 deletions docker/debian/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,44 @@ FROM gcc:${GCC_VERSION}-${DEBIAN_VERSION} AS gcc-src
# ====================== BASE IMAGE ======================
FROM debian:${DEBIAN_VERSION} AS base

# Use Bash as the default shell for RUN commands and as the entrypoint.
SHELL ["/bin/bash", "-c"]
# Use Bash as the default shell for RUN commands, using the options
# `set -o errexit -o pipefail`, and as the entrypoint.
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
ENTRYPOINT ["/bin/bash"]

# Ensure any packages installed directly or indirectly via dpkg do not require
# manual interaction.
ARG DEBIAN_FRONTEND=noninteractive
RUN <<EOF
set -ex
ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
apt update
apt upgrade -y
apt install -y tzdata
apt clean
apt-get update
apt-get upgrade -y
apt-get install -y --no-install-recommends tzdata
apt-get clean
rm -rf /var/lib/apt/lists/*
dpkg-reconfigure --frontend noninteractive tzdata
EOF

# Install tools that are shared by all stages. Run `apt update` again before
# Install tools that are shared by all stages. Run `apt-get update` again before
# installing the packages to ensure the package lists are up-to-date, which is
# especially important when the image is built from a cached layer.
RUN <<EOF
pkgs=()
pkgs+=(bison) # Required build tool.
pkgs+=(ca-certificates) # Enable TLS verification for HTTPS connections by providing trusted root certificates.
pkgs+=(cmake) # Required build tool.
pkgs+=(curl) # Dependency for tools requiring downloading data.
pkgs+=(dpkg-dev) # Required packaging tool.
pkgs+=(file) # Required packaging tool.
pkgs+=(flex) # Required build tool.
pkgs+=(git) # Required build tool.
pkgs+=(gpg) # Dependency for tools requiring signing or encrypting/decrypting.
pkgs+=(jq) # Pretty printing.
pkgs+=(libc6-dev) # Required build tool.
pkgs+=(ninja-build) # Required build tool.
pkgs+=(pipx) # Package manager for Python applications.
pkgs+=(wget) # Required build tool.
apt update
apt install -y --no-install-recommends "${pkgs[@]}"
apt clean
apt-get update
apt-get install -y --no-install-recommends "${pkgs[@]}"
apt-get clean
rm -rf /var/lib/apt/lists/*
EOF

Expand All @@ -72,12 +70,14 @@ RUN useradd -ms /bin/bash ${NONROOT_USER}
# ====================== GCC IMAGE ======================
FROM base AS gcc

# This is not inherited from base image, ensure no manual interaction needed.
ARG DEBIAN_FRONTEND=noninteractive

# Copy GCC from the source image, make the package manager aware of its
# existence, and create the necessary symlinks.
COPY --from=gcc-src /usr/local/ /usr/local/
COPY --from=gcc-src /etc/ld.so.conf.d/*.conf /etc/ld.so.conf.d/
RUN <<EOF
set -ex
ldconfig -v
dpkg-divert --divert /usr/bin/gcc.orig --rename /usr/bin/gcc
dpkg-divert --divert /usr/bin/g++.orig --rename /usr/bin/g++
Expand All @@ -99,12 +99,35 @@ EOF
ENV CC=/usr/bin/gcc
ENV CXX=/usr/bin/g++

# Check that the installed GCC version matches the expected version. We must
# repeat the GCC_VERSION argument here, as it is not inherited from the source
# image.
ARG GCC_VERSION
RUN <<EOF
CC_VER=$(${CC} -dumpversion)
CC_VER=${CC_VER%%.*}
if [[ "${CC_VER}" != "${GCC_VERSION}" ]]; then
echo "ERROR: 'gcc -dumpversion' gives '${CC_VER}', which does not match expected version '${GCC_VERSION}'."
exit 1
fi
CXX_VER=$(${CXX} -dumpversion)
CXX_VER=${CXX_VER%%.*}
if [[ "${CXX_VER}" != "${GCC_VERSION}" ]]; then
echo "ERROR: g++ -dumpversion gives '${CXX_VER}', which does not match expected version '${GCC_VERSION}'."
exit 1
fi
EOF

# Switch to the non-root user.
USER ${NONROOT_USER}
WORKDIR /home/${NONROOT_USER}

# Create a default Conan profile.
RUN conan profile detect
RUN <<EOF
conan profile detect
rm -rf /tmp/*
EOF

# Fix the C++ dialect.
RUN sed -i -e 's|^compiler\.cppstd=.*$|compiler.cppstd=20|' ~/.conan2/profiles/default
# Explicitly set the compiler flags.
Expand All @@ -117,54 +140,88 @@ EOF
# Print the Conan profile to verify the configuration.
RUN conan profile show

# Test the image by compiling a simple C++ program.
RUN --mount=type=bind,source=test,target=/test,readonly <<EOF
cp -r /test test
cd test && ./run.sh && cd ..
rm -rf test
EOF

# ===================== CLANG IMAGE =====================
FROM base AS clang

# This is not inherited from base image, ensure no manual interaction needed.
ARG DEBIAN_FRONTEND=noninteractive

# Install Clang. Use the LLVM apt repository to access the latest versions. We
# must repeat the DEBIAN_VERSION argument here, as it is not inherited from the
# base image.
# base or source images.
ARG DEBIAN_VERSION
ARG CLANG_VERSION
RUN <<EOF
set -ex
curl --no-progress-meter https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor -o /etc/apt/keyrings/llvm.gpg
printf "%s\n%s\n" \
"deb [signed-by=/etc/apt/keyrings/llvm.gpg] https://apt.llvm.org/${DEBIAN_VERSION}/ llvm-toolchain-${DEBIAN_VERSION}-${CLANG_VERSION} main" \
| tee /etc/apt/sources.list.d/llvm.list
apt update
apt install -t llvm-toolchain-${DEBIAN_VERSION}-${CLANG_VERSION} -y --no-install-recommends clang-${CLANG_VERSION} llvm-${CLANG_VERSION}
apt clean
apt-get update
apt-get install -t llvm-toolchain-${DEBIAN_VERSION}-${CLANG_VERSION} -y --no-install-recommends clang-${CLANG_VERSION} llvm-${CLANG_VERSION}
apt-get clean
rm -rf /var/lib/apt/lists/*
EOF
ENV CC=/usr/bin/clang-${CLANG_VERSION}
ENV CXX=/usr/bin/clang++-${CLANG_VERSION}

# Check that the installed Clang version matches the expected version.
RUN <<EOF
CC_VER=$(${CC} -dumpversion)
CC_VER=${CC_VER%%.*}
if [[ "${CC_VER}" != "${CLANG_VERSION}" ]]; then
echo "ERROR: 'clang -dumpversion' gives '${CC_VER}', which does not match expected version '${CLANG_VERSION}'."
exit 1
fi
CXX_VER=$(${CXX} -dumpversion)
CXX_VER=${CXX_VER%%.*}
if [[ "${CXX_VER}" != "${CLANG_VERSION}" ]]; then
echo "ERROR: clang++ -dumpversion gives '${CXX_VER}', which does not match expected version '${CLANG_VERSION}'."
exit 1
fi
EOF

# Switch to the non-root user.
USER ${NONROOT_USER}
WORKDIR /home/${NONROOT_USER}

# Create a default Conan profile.
RUN conan profile detect
RUN <<EOF
conan profile detect
rm -rf /tmp/*
EOF

# Fix the C++ dialect.
RUN sed -i -e 's|^compiler\.cppstd=.*$|compiler.cppstd=20|' ~/.conan2/profiles/default
# Explicitly set the compiler flags. To ensure compatibility with a range of
# Clang compilers, we must also add extra flags that apply to certain versions
# of Clang.
# TODO: Move extra flags into the rippled repository as a custom Conan profile.
RUN <<EOF
CXX_VER=$(${CXX} -dumpversion)
CXX_VER=${CXX_VER%%.*}
cat >>~/.conan2/profiles/default <<EOT
[conf]
tools.build:compiler_executables={"c": "${CC}", "cpp": "${CXX}"}
EOT
if [[ $(clang-${CLANG_VERSION} --version | head -1 | grep -Po 'version \K[0-9]{2}') -ge 20 ]]; then
cat >>~/.conan2/profiles/default <<EOT
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw', '-Wno-deprecated-declarations']
EOT
elif [[ $(clang-${CLANG_VERSION} --version | head -1 | grep -Po 'version \K[0-9]{2}') -eq 19 ]]; then
if [[ ${CXX_VER} -ge 19 ]]; then
cat >>~/.conan2/profiles/default <<EOT
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
EOT
fi
EOF
# Print the Conan profile to verify the configuration.
RUN conan profile show

# Test the image by compiling a simple C++ program.
RUN --mount=type=bind,source=test,target=/test,readonly <<EOF
cp -r /test test
cd test && ./run.sh && cd ..
rm -rf test
EOF
4 changes: 3 additions & 1 deletion docker/debian/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ versions by specifying the `DEBIAN_VERSION` build argument. There are additional
arguments to specify as well, namely `GCC_VERSION` for the GCC flavor and
`CLANG_VERSION` for the Clang flavor.

Run the commands below from the current directory containing the Dockerfile.
Run the commands below from the root directory of the repository.

#### Building the Docker image for GCC.

Expand All @@ -45,6 +45,7 @@ GCOVR_VERSION=8.3
CONTAINER_IMAGE=xrplf/ci/debian-${DEBIAN_VERSION}:gcc-${GCC_VERSION}

docker buildx build . \
--file docker/debian/Dockerfile \
--target gcc \
--build-arg BUILDKIT_DOCKERFILE_CHECK=skip=InvalidDefaultArgInFrom \
--build-arg BUILDKIT_INLINE_CACHE=1 \
Expand All @@ -70,6 +71,7 @@ GCOVR_VERSION=8.3
CONTAINER_IMAGE=xrplf/ci/debian-${DEBIAN_VERSION}:clang-${CLANG_VERSION}

docker buildx build . \
--file docker/debian/Dockerfile \
--target clang \
--build-arg BUILDKIT_DOCKERFILE_CHECK=skip=InvalidDefaultArgInFrom \
--build-arg BUILDKIT_INLINE_CACHE=1 \
Expand Down
Loading