#
#  Copyright (c) 2024-2026, Intel Corporation
#
#  SPDX-License-Identifier: BSD-3-Clause


FROM ubuntu:18.04
LABEL maintainer="Arina Neshlyaeva <arina.neshlyaeva@intel.com>"
SHELL ["/bin/bash", "-c"]

ARG REPO=ispc/ispc
ARG SHA=main
ARG LTO=OFF
ARG PGO=OFF
ARG XE_DEPS=ON

# !!! Make sure that your docker config provides enough memory to the container,
# otherwise LLVM build may fail, as it will use all the cores available to container.

RUN uname -a

# Packages required to build ISPC and Clang.
# Ubuntu 18.04's default GCC 7.5 is too old to build recent LLVM (>=21) trunk
# (e.g. CTAD failures in clang's LifetimeSafety), so install GCC 11 from the
# ubuntu-toolchain-r PPA and make it the default compiler.
RUN apt-get -y update && apt-get --no-install-recommends install -y wget build-essential gcc g++ git ca-certificates ninja-build gnupg software-properties-common && \
    add-apt-repository -y ppa:ubuntu-toolchain-r/test && \
    apt-get -y update && apt-get --no-install-recommends install -y gcc-11 g++-11 && \
    update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100 \
        --slave /usr/bin/g++ g++ /usr/bin/g++-11 && \
    update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-11 100 && \
    update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-11 100 && \
    rm -rf /var/lib/apt/lists/*

# Install multilib libc needed to build clang_rt
RUN if [[ $(uname -m) =~ "x86" ]]; then \
        export CROSS_LIBS="libc6-dev-i386=2.27-3ubuntu*"; \
    else \
        export CROSS_LIBS="libc6-dev-armhf-cross=2.27-3ubuntu*"; \
    fi && \
    apt-get -y update && apt-get --no-install-recommends install -y "$CROSS_LIBS" && \
    rm -rf /var/lib/apt/lists/*

# Download and install required version of cmake (3.23.5 for both x86 and aarch64) as required for superbuild preset jsons.
RUN if [[ $(uname -m) =~ "x86" ]]; then \
        export CMAKE_URL="https://cmake.org/files/v3.23/cmake-3.23.5-linux-x86_64.sh"; \
    else \
        export CMAKE_URL="https://github.com/Kitware/CMake/releases/download/v3.23.5/cmake-3.23.5-linux-aarch64.sh"; \
    fi && \
    wget -q --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 5 $CMAKE_URL && \
    sh cmake-*.sh --prefix=/usr/local --skip-license && rm -rf cmake-*.sh

# Install TBB from source (required for ISPCRT).
# Build from source to avoid certificate issues with Intel apt repo on Ubuntu 18.04
# and to avoid enum-constexpr-conversion errors with LLVM 21+
# Build TBB with the system GCC 7: for GCC >= 11 TBB enables the WAITPKG
# intrinsics (-mwaitpkg, _tpause), but Ubuntu 18.04's binutils 2.30 assembler
# does not know the 'tpause' instruction (needs >= 2.32), so a GCC 11 build
# fails to assemble. GCC 7 does not enable that code path.
RUN git clone --depth 1 --branch v2021.13.0 https://github.com/oneapi-src/oneTBB.git /tmp/oneTBB && \
    cmake -S /tmp/oneTBB -B /tmp/oneTBB/build -G Ninja \
        -DCMAKE_BUILD_TYPE=Release \
        -DTBB_TEST=OFF \
        -DCMAKE_C_COMPILER=gcc-7 \
        -DCMAKE_CXX_COMPILER=g++-7 \
        -DCMAKE_INSTALL_PREFIX=/opt/intel/oneapi/tbb/2021.13 && \
    cmake --build /tmp/oneTBB/build -j"$(nproc)" && \
    cmake --install /tmp/oneTBB/build && \
    rm -rf /tmp/oneTBB && \
    ln -s /opt/intel/oneapi/tbb/2021.13 /opt/intel/oneapi/tbb/latest

# Set TBB_ROOT to point to oneAPI TBB installation
ENV TBB_ROOT=/opt/intel/oneapi/tbb/latest

# Zlib is required to build Python3
RUN apt-get -y update && \
    apt-get -y --no-install-recommends install zlib1g-dev zlib1g && \
    rm -rf /var/lib/apt/lists/*
ENV PYTHON_VERSION=3.8.19
RUN wget -q --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 5 https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \
    tar xf Python-${PYTHON_VERSION}.tgz && pushd Python-${PYTHON_VERSION} && \
    ./configure CFLAGS=-fPIC CXXFLAGS=-fPIC && make -j"$(nproc)" && make install && \
    popd && rm -rf /usr/local/src/*

# If you are behind a proxy, you need to configure git.
RUN if [ -v http_proxy ]; then git config --global --add http.proxy "$http_proxy"; fi

# Install regular ISPC dependencies
RUN apt-get -y update && apt-get --no-install-recommends install -y m4 bison flex && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /usr/local/src

# Create new non-root user and switch to it
RUN useradd -m -d /home/ispc_user -s /bin/bash -U ispc_user && \
    chown -R ispc_user:ispc_user /usr

USER ispc_user

# Configure and build ISPC
# Build Clang/LLVM, XE dependencies and then ISPC.
RUN git clone https://github.com/$REPO.git ispc && \
    git -C ispc checkout $SHA && \
    cmake ispc/superbuild \
        -B build \
        --preset os \
        -DLTO=$LTO \
        -DXE_DEPS=$XE_DEPS \
        -DINSTALL_ISPC=ON \
        -DINSTALL_TOOLCHAIN=ON \
        -DCMAKE_INSTALL_PREFIX=/usr/local && \
    cmake --build build && \
    (cmake --build build --target ispc-stage2-check-all || true) && \
    mv build/build-ispc-stage2/src/ispc-stage2-build/*.tar.gz ./ && \
    rm -rf build
