# syntax=docker/dockerfile:1

FROM --platform=$BUILDPLATFORM centos:7 AS centos-devtoolset

ARG BUILDARCH
ARG DEVTOOLSET

# devtoolset-12 is only in CentOS buildlogs. The rpms are unsigned since they never were
# published to the official CentOS SCL repos.
RUN if [ "${BUILDARCH}" = "arm64" ]; then export BUILDARCH="aarch64"; fi && \
    if [ "${BUILDARCH}" = "amd64" ]; then export BUILDARCH="x86_64"; fi && \
    printf '%s\n' \
    "[${DEVTOOLSET}-build]" \
    "name=${DEVTOOLSET} - Build" \
    "baseurl=https://buildlogs.centos.org/c7-${DEVTOOLSET}.${BUILDARCH}/" \
    "gpgcheck=0" \
    "enabled=1" \
    > /etc/yum.repos.d/${DEVTOOLSET}-build.repo

# mirrorlist is no longer available since CentOS 7 EOL. The software collection
# stuff for arm64 (aarch64) is in /altarch not /centos on vault.centos.org.
# Make the fixup a script as it needs to be run multiple times as installing
# and updating centos-release-scl-rh leaves the old unavailable URLs.
# https://serverfault.com/a/1161847
RUN printf '%s\n' \
    '#!/bin/sh' \
    "sed -e 's/mirror.centos.org/vault.centos.org/g' \\" \
    "    -e 's/^#.*baseurl=http/baseurl=https/g' \\" \
    "    -e 's/^mirrorlist=http/#mirrorlist=http/g' \\" \
    "    -i /etc/yum.repos.d/*.repo" \
    "if [ \"\$(uname -m)\" = 'aarch64' ]; then" \
    "    sed 's|centos/7/sclo|altarch/7/sclo|' -i /etc/yum.repos.d/*.repo" \
    'fi' \
    > /tmp/fix-yum-repo-list.sh
RUN chmod 755 /tmp/fix-yum-repo-list.sh && \
    /tmp/fix-yum-repo-list.sh

# Install required dependencies.
RUN yum groupinstall -y 'Development Tools' && \
    yum install -y epel-release && \
    yum install -y centos-release-scl-rh && \
    /tmp/fix-yum-repo-list.sh && \
    yum update -y && \
    yum install -y \
    centos-release-scl \
    cmake3 \
    git \
    scl-utils && \
    yum clean all && \
    /tmp/fix-yum-repo-list.sh

# As mentioned above, these packages are unsigned.
RUN yum install --nogpgcheck -y \
    ${DEVTOOLSET}-gcc \
    ${DEVTOOLSET}-gcc-c++ \
    ${DEVTOOLSET}-make && \
    yum clean all

## NINJA-BUILD ###################################################################

## ninja-build is required for building boringssl. The version included in CentOS 7 AMR64
## is too old, so we need to build it from source.
FROM --platform=$BUILDPLATFORM centos-devtoolset AS ninja-build

# Install additional required dependencies.
RUN  yum install -y expat-devel \
    gettext \
    libcurl-devel \
    openssl-devel \
    pcre-devel \
    xmlto \
    zlib-devel \
    && yum clean all

# mno-outline-atomics flag is needed to make the build works on ARM64 docker.
RUN git clone --depth=1 https://github.com/Kitware/CMake.git -b v3.28.1 && \
    cd CMake && \
    [ "$(git rev-parse HEAD)" = '1eed682d7cca9bb2c2b0709a6c3202a3b08613b2' ] && \
    scl enable ${DEVTOOLSET} "if [ "${BUILDARCH}" = "arm64" ]; then export CFLAGS=-mno-outline-atomics; fi &&  ./bootstrap --parallel="$(nproc)" && make -j"$(nproc)" && make install"

ENV PATH="/opt/cmake/bin:$PATH"

RUN git clone --depth=1 https://github.com/ninja-build/ninja.git -b v1.11.1 && \
    cd ninja && \
    [ "$(git rev-parse HEAD)" = 'a524bf3f6bacd1b4ad85d719eed2737d8562f27a' ] && \
    scl enable ${DEVTOOLSET} "cmake -Bbuild-cmake && \
    cmake --build build-cmake -j"$(nproc)" && \
    cmake --build build-cmake --target  install"

# Use just created devtool image with newer GCC and Cmake
FROM --platform=$BUILDPLATFORM centos-devtoolset as clang12

ARG DEVTOOLSET

# Compile Clang 12.0.0 from source. It is needed to create BoringSSL and BPF files.
# CentOS 7 doesn't provide it as a package unfortunately.
# This version of Clang is explicitly required for FIPS compliance when building BoringSSL.
# For more information please refer to the section 12. Guidance and Secure Operation of:
# TODO(reed) -- fill in URL
# LLVM_INCLUDE_BENCHMARKS must be off, otherwise compilation fails,
# CLANG_BUILD_TOOLS must be on, it builds clang binary,
# LLVM_BUILD_TOOLS must be on, it builds llvm-strip binary.
# the rest is disabled to speedup the compilation.
RUN git clone --branch llvmorg-12.0.0 --depth=1 https://github.com/llvm/llvm-project.git && \
    cd llvm-project/ && \
    [ "$(git rev-parse HEAD)" = 'd28af7c654d8db0b68c175db5ce212d74fb5e9bc' ] && \
    mkdir build && cd build/ && \
    scl enable ${DEVTOOLSET} 'bash -c "cmake3 \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/opt/llvm \
    -DLLVM_ENABLE_PROJECTS=clang \
    -DLLVM_BUILD_TOOLS=ON \
    -G \"Unix Makefiles\" ../llvm && \
    make -j$(grep -c processor /proc/cpuinfo) install-llvm-strip install-clang-format install-clang install-clang-resource-headers install-libclang"' && \
    cd ../.. && \
    rm -rf llvm-project

# Build custom packages with -fPIC for use with other dependencies.
FROM centos-devtoolset as custom-packages

# Create mockbuild user/group for building.
RUN useradd --user-group --create-home --shell=/bin/bash mockbuild

# Recompile and install libelf with -fPIC.
RUN mkdir -p /opt/custom-packages && cd /opt && \
    yumdownloader --source elfutils-libelf-devel-static && \
    yum-builddep -y elfutils-libelf-devel-static && \
    export DIST=$(rpm -qp --queryformat '%{RELEASE}' elfutils-*.src.rpm | cut -d '.' -f 2) && \
    rpmbuild --rebuild --nocheck --define "optflags `rpm -E %{optflags}` -fPIC" --define "dist .${DIST}" elfutils-*.src.rpm && \
    if [ "${BUILDARCH}" = "arm64" ]; then export BUILDARCH="aarch64"; fi && \
    cp /root/rpmbuild/RPMS/${BUILDARCH}/elfutils-libelf-devel-static-*${DIST}.${BUILDARCH}.rpm /opt/custom-packages/

# Recompile and install zlib with -fPIC.
RUN mkdir -p /opt/custom-packages && cd /opt && \
    yumdownloader --source zlib-static && \
    yum-builddep -y zlib-static && \
    export DIST=$(rpm -qp --queryformat '%{RELEASE}' zlib-*.src.rpm | cut -d '.' -f 2) && \
    rpmbuild --rebuild --define "optflags `rpm -E %{optflags}` -fPIC" --define "dist .${DIST}" zlib-*.src.rpm && \
    if [ "${BUILDARCH}" = "arm64" ]; then export BUILDARCH="aarch64"; fi && \
    cp /root/rpmbuild/RPMS/${BUILDARCH}/zlib-static-*${DIST}.${BUILDARCH}.rpm /opt/custom-packages/

# Create the final image with Clang and custom builds only. We're using this Docker image as a tar.gz
# mainly because we want to keep our artifacts on GitHub, and GH doesn't support blobs, only Docker images.
FROM scratch AS buildbox-centos7-assets

# Copy Clang into the final image.
COPY --from=clang12 /opt/llvm /opt/llvm/

# Copy ninja into the final image.
COPY --from=ninja-build /usr/local/bin/ninja /usr/local/bin/ninja

# Copy custom packages into the final image.
COPY --from=custom-packages /opt/custom-packages /opt/custom-packages/
