# The Dockerfile consists of four stages, each setting up components for a 
# RISC-V development environment.
#
# - Stage 1: Utilises Ubuntu 23.10 to install build tools and dependencies, 
#            then clones, compiles, and installs the RISC-V GNU toolchain in 
#            `/opt/riscv`.
# 
# - Stage 2: Sets up another Ubuntu 23.10 environment, copies the RISC-V 
#            toolchain from Stage 1, installs additional dependencies, and then 
#            clones, compiles, and installs the RISC-V Proxy Kernel.
# 
# - Stage 3: Uses Ubuntu 23.10 again, brings forward tools from previous 
#            stages, installs further dependencies, and then clones, compiles, 
#            and installs the Spike RISC-V ISA simulator.
#
# - Stage 4: Prepares the final Ubuntu 23.10 environment, copies all tools, 
#            updates the PATH to include `/opt/riscv/bin`, and configures the 
#            container to start with a shell for immediate interaction.

############################## Stage 1

FROM ubuntu:23.10 AS stage1

ENV DEBIAN_FRONTEND=noninteractive

WORKDIR /root

# RISC-V toolchain
# Source: https://github.com/riscv-collab/riscv-gnu-toolchain

## Install prerequisites
RUN apt update -qq && apt install -y --no-install-recommends \
    autoconf \
    automake \
    autotools-dev \
    curl \
    python3 \
    python3-pip \
    libmpc-dev \
    libmpfr-dev \
    libgmp-dev \
    gawk \
    build-essential \
    bison \
    flex \
    texinfo \
    gperf \
    libtool \
    patchutils \
    bc \
    zlib1g-dev \
    libexpat-dev \
    ninja-build \
    git \
    cmake \
    libglib2.0-dev \
    libslirp-dev \
    && rm -rf /var/lib/apt/lists/*

## Compile and install
RUN git clone https://github.com/riscv/riscv-gnu-toolchain

WORKDIR /root/riscv-gnu-toolchain

RUN ./configure --prefix=/opt/riscv && \
    make -j8

WORKDIR /root

RUN rm -rf /root/riscv-gnu-toolchain

############################## Stage 2

FROM ubuntu:23.10 AS stage2

COPY --from=stage1 /opt/riscv /opt/riscv

WORKDIR /root

## Install prerequisites
RUN apt update -qq && apt install -y --no-install-recommends \
    autoconf \
    automake \
    autotools-dev \
    curl \
    python3 \
    python3-pip \
    libmpc-dev \
    libmpfr-dev \
    libgmp-dev \
    gawk \
    build-essential \
    bison \
    flex \
    texinfo \
    gperf \
    libtool \
    patchutils \
    bc \
    zlib1g-dev \
    libexpat-dev \
    ninja-build \
    git \
    cmake \
    libglib2.0-dev \
    libslirp-dev \
    && rm -rf /var/lib/apt/lists/*

# RISC-V proxy kernel and boot loader
# Source: https://github.com/riscv-software-src/riscv-pk

## Compile and install
RUN git clone https://github.com/riscv-software-src/riscv-pk

WORKDIR /root/riscv-pk

ENV PATH="${PATH}:/opt/riscv/bin/"

RUN mkdir build && \
    cd build && \
    ../configure --prefix=/opt/riscv --host=riscv64-unknown-elf --with-arch=rv64gc_zifencei && \
    make -j8 && \
    make install

WORKDIR /root

RUN rm -rf /root/riscv-pk

############################## Stage 3

FROM ubuntu:23.10 AS stage3

COPY --from=stage2 /opt/riscv /opt/riscv

WORKDIR /root

## Install prerequisites
RUN apt update -qq && apt install -y --no-install-recommends \
    autoconf \
    automake \
    autotools-dev \
    curl \
    python3 \
    python3-pip \
    libmpc-dev \
    libmpfr-dev \
    libgmp-dev \
    gawk \
    build-essential \
    bison \
    flex \
    texinfo \
    gperf \
    libtool \
    patchutils \
    bc \
    zlib1g-dev \
    libexpat-dev \
    ninja-build \
    git \
    cmake \
    libglib2.0-dev \
    libslirp-dev \
    device-tree-compiler \
    && rm -rf /var/lib/apt/lists/*

# Spike, RISC-V ISA simulator
# Source: https://github.com/riscv-software-src/riscv-isa-sim

## Compile and install
RUN git clone https://github.com/riscv/riscv-isa-sim.git

WORKDIR /root/riscv-isa-sim

RUN mkdir build && \
    cd build && \
    ../configure --prefix=/opt/riscv && \
    make -j8 && \
    make install

WORKDIR /root

RUN rm -rf /root/riscv-isa-sim

############################## Stage 4

FROM ubuntu:23.10 AS stage4

COPY --from=stage3 /opt/riscv /opt/riscv

WORKDIR /root

RUN echo "export PATH=$PATH:/opt/riscv/bin" >> /root/.bashrc

# Pass commands into container
ENTRYPOINT ["bash", "-lc"]