Skip to content

Commit d212f96

Browse files
committed
Push docker image to DockerHub on merge into master
The rv32emu image build process will take around 6 minutes on GitHub CI. The base image build process will take around 20 and 10 minutes when building a native image on the native arch for gcc and sail, respectively, if internet connection is fast. The multi-arch base image build will take a long time (4 hours on a 8-core machine with fast internet) as we will use QEMU emulation for cross compilation. At the time of writing, we can only run multi-arch build successfully on x86 machines. The base image will need to be built using the script provided in the docker directory, manually. The rv32emu image will be built automatically on PR and merge into the master branch.
1 parent afe4bf6 commit d212f96

File tree

8 files changed

+136
-44
lines changed

8 files changed

+136
-44
lines changed

.github/workflows/docker.yml

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Publish Docker image to Docker Hub
2+
on:
3+
push:
4+
branches: [ master ]
5+
pull_request:
6+
branches: [ master ]
7+
8+
# https://docs.docker.com/build/ci/github-actions/multi-platform/
9+
jobs:
10+
docker:
11+
name: build-and-publish
12+
runs-on: ubuntu-22.04
13+
steps:
14+
15+
- name: Check out the repo
16+
uses: actions/checkout@v4
17+
- name: Test changed files
18+
id: changed-files
19+
uses: tj-actions/changed-files@v40
20+
with:
21+
files: |
22+
src/**
23+
build/**
24+
mk/**
25+
tests/**
26+
tools/**
27+
- name: Set up QEMU
28+
uses: docker/setup-qemu-action@v3
29+
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
30+
- name: Set up Docker Buildx
31+
uses: docker/setup-buildx-action@v3
32+
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
33+
- name: Login to Docker Hub
34+
uses: docker/login-action@v3
35+
if: ${{ steps.changed-files.outputs.any_changed == 'true' && github.event_name == 'push'}}
36+
with:
37+
username: ${{ secrets.DOCKERHUB_USERNAME }}
38+
password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}
39+
- name: Build and push
40+
uses: docker/build-push-action@v5
41+
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
42+
with:
43+
context: .
44+
platforms: linux/amd64,linux/arm64/v8
45+
push: ${{ github.event_name == 'push' }}
46+
tags: sysprog21/rv32emu:latest

Dockerfile

+13-39
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,29 @@
1-
FROM ubuntu:22.04
2-
LABEL maintainer="[email protected]"
1+
FROM sysprog21/rv32emu-gcc as base_gcc
2+
FROM sysprog21/rv32emu-sail as base_sail
33

4-
# Install packages required for the emulator to compile and execute correctly
4+
FROM ubuntu:22.04 as final
5+
6+
# Install extra packages for the emulator to compile and execute with full capabilities correctly
57
RUN apt-get update && \
68
DEBIAN_FRONTEND=noninteractive apt-get install -y \
7-
libsdl2-dev libsdl2-mixer-dev python3-pip git
9+
libsdl2-dev libsdl2-mixer-dev python3-pip git && \
10+
rm -rf /var/lib/apt/lists/*
811

912
RUN python3 -m pip install git+https://github.com/riscv/riscof
1013

1114
# set up the timezone
1215
ENV TZ=Asia/Taipei
1316
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
1417

15-
# when using apt install gcc-riscv64-unknown-elf, this will cause "unsupported ISA subset 'z'" during compilation
16-
# thus, we are building from scratch, following the version here -> https://github.com/sysprog21/rv32emu/blob/master/.ci/riscv-toolchain-install.sh
17-
# for x86, we can optimize this part and take the nightly build directly, but not for aarch64
18-
ENV RISCV=/opt/riscv
19-
ENV PATH=$RISCV/bin:$PATH
20-
WORKDIR $RISCV
21-
RUN apt install -y autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
22-
RUN git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
23-
RUN cd riscv-gnu-toolchain && \
24-
git checkout tags/2023.10.06 && \
25-
./configure --prefix=/opt/riscv --with-arch=rv32gc --with-abi=ilp32d && \
26-
make -j$(nproc) && \
27-
make clean
28-
29-
# the default reference emulator is x86-based
30-
# we need to build it ourselves if we are using it on aarch64
31-
# https://riscof.readthedocs.io/en/stable/installation.html#install-plugin-models
32-
# the above commands are modified to match the current build flow as indicated in the Github CI -> https://github.com/riscv/sail-riscv/blob/master/.github/workflows/compile.yml
33-
WORKDIR /home/root/
34-
RUN apt install -y opam zlib1g-dev pkg-config libgmp-dev z3 device-tree-compiler
35-
RUN opam init --disable-sandboxing -y
36-
RUN opam install -y sail
37-
RUN git clone https://github.com/riscv/sail-riscv.git
38-
# based on this commit https://github.com/sysprog21/rv32emu/commit/01b00b6f175f57ef39ffd1f4fa6a611891e36df3#diff-3b436c5e32c40ecca4095bdacc1fb69c0759096f86e029238ce34bbe73c6e68f
39-
# we infer that the sail-riscv binary was taken from commit 9547a30bf84572c458476591b569a95f5232c1c7
40-
RUN cd sail-riscv && \
41-
git checkout 9547a30bf84572c458476591b569a95f5232c1c7 && \
42-
eval $(opam env) && \
43-
make && \
44-
ARCH=RV32 make
45-
4618
# copy in the source code
4719
WORKDIR /home/root/rv32emu
4820
COPY . .
4921

22+
# Copy the GNU Toolchain files
23+
ENV RISCV=/opt/riscv
24+
ENV PATH=$RISCV/bin:$PATH
25+
COPY --from=base_gcc /opt/riscv/ /opt/riscv/
26+
5027
# replace the emulator (riscv_sim_RV32) with the arch that the container can execute
5128
RUN rm /home/root/rv32emu/tests/arch-test-target/sail_cSim/riscv_sim_RV32
52-
RUN cp /home/root/sail-riscv/c_emulator/riscv_sim_RV32 /home/root/rv32emu/tests/arch-test-target/sail_cSim/riscv_sim_RV32
53-
54-
# clean up apt cache
55-
RUN rm -rf /var/lib/apt/lists/*
29+
COPY --from=base_sail /home/root/riscv_sim_RV32 /home/root/rv32emu/tests/arch-test-target/sail_cSim/riscv_sim_RV32

README.md

+1-5
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,7 @@ The usage and limitations of Doom and Quake demo are listed in [docs/demo.md](do
6767

6868
### Docker image
6969

70-
The image containing all the necessary tools for development and testing can be built by executing `docker build -t rv32emu .`.
71-
72-
This image works for both x86 and aarch64 (Apple's M1 chip) machines. Note that the image building time will be long since it will perform builds of the toolchain and the reference emulator from source. Also, it will take up about 16GB of disk space.
73-
74-
After the image is built, you can create a docker container by executing `docker run -it rv32emu` at the project root. This will give you can interactive bash shell where you can experiment with the current codebase.
70+
The image containing all the necessary tools for development and testing can be executed by `docker run -it sysprog21/rv32emu:latest`. It works for both x86-64 and aarch64 (Apple's M1 chip) machines.
7571

7672
### Customization
7773

docker/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.log

docker/Dockerfile-gcc

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM ubuntu:22.04 as base
2+
3+
# when using apt install gcc-riscv64-unknown-elf, this will cause "unsupported ISA subset 'z'" during compilation
4+
# thus, we are building from scratch, following the version here -> https://github.com/sysprog21/rv32emu/blob/master/.ci/riscv-toolchain-install.sh
5+
# for x86-64, we can optimize this part and take the nightly build directly, but not for aarch64
6+
RUN apt-get update && \
7+
apt install -y \
8+
git autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev && \
9+
rm -rf /var/lib/apt/lists/*
10+
RUN git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
11+
RUN cd riscv-gnu-toolchain && \
12+
git checkout tags/2023.10.06 && \
13+
./configure --prefix=/opt/riscv --with-arch=rv32gc --with-abi=ilp32d && \
14+
make -j$(nproc) && \
15+
make clean
16+
17+
FROM ubuntu:22.04 as final
18+
19+
# Keep the GNU Toolchain files only
20+
COPY --from=base /opt/riscv/ /opt/riscv/

docker/Dockerfile-sail

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# builds the base image of rv32emu (the toolchains)
2+
# docker build --progress=plain -t sysprog21/rv32emu-base -f Dockerfile-base . 2>&1 | tee build.log
3+
FROM ubuntu:22.04 as base
4+
5+
# the default reference emulator is x86-64-based
6+
# we need to build it ourselves if we are using it on aarch64
7+
# https://riscof.readthedocs.io/en/stable/installation.html#install-plugin-models
8+
# the above commands are modified to match the current build flow as indicated in the Github CI -> https://github.com/riscv/sail-riscv/blob/master/.github/workflows/compile.yml
9+
RUN apt-get update && \
10+
apt install -y opam zlib1g-dev pkg-config libgmp-dev z3 device-tree-compiler && \
11+
rm -rf /var/lib/apt/lists/*
12+
RUN opam init --disable-sandboxing -y
13+
RUN opam switch create ocaml-base-compiler.4.13.1 # opam switch list-available
14+
RUN opam search sail
15+
# https://opam.ocaml.org/packages/sail/sail.0.16/
16+
RUN opam install -y sail.0.16 # latest version 0.17.x will cause complication issues for sail-riscv on commit 9547a3
17+
RUN git clone https://github.com/riscv/sail-riscv.git
18+
# based on this commit https://github.com/sysprog21/rv32emu/commit/01b00b6f175f57ef39ffd1f4fa6a611891e36df3#diff-3b436c5e32c40ecca4095bdacc1fb69c0759096f86e029238ce34bbe73c6e68f
19+
# we infer that the sail-riscv binary was taken from commit 9547a30bf84572c458476591b569a95f5232c1c7
20+
RUN cd sail-riscv && \
21+
git checkout 9547a30bf84572c458476591b569a95f5232c1c7 && \
22+
eval $(opam env) && \
23+
make && \
24+
ARCH=RV32 make
25+
26+
FROM ubuntu:22.04 as final
27+
28+
# keep the emulator only
29+
COPY --from=base /sail-riscv/c_emulator/riscv_sim_RV32 /home/root/riscv_sim_RV32

docker/build.sh

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
3+
# To enable multi-arch image build
4+
# https://www.docker.com/blog/how-to-rapidly-build-multi-architecture-images-with-buildx/
5+
docker buildx create --name cross-platform-builder --use --bootstrap
6+
7+
docker buildx build --progress=plain --push --platform linux/amd64,linux/arm64/v8 --tag sysprog21/rv32emu-gcc -f Dockerfile-gcc . 2>&1 | tee build-gcc.log
8+
rm build-gcc.log
9+
10+
docker buildx build --progress=plain --push --platform linux/amd64,linux/arm64/v8 --tag sysprog21/rv32emu-sail -f Dockerfile-sail . 2>&1 | tee build-sail.log
11+
rm build-sail.log

docs/base-image.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Base images
2+
3+
The goal is to support both `x86-64` and `aarch64` docker images for development and testing.
4+
5+
The base images contain `gcc` and `sail` images. We compile from the toolchain from source and use a specific version of the toolchains.
6+
7+
The build process should be used when an update on the toolchain is required. When a new build is made by running `build.sh`, build and push to Docker Hub are automated.
8+
9+
## Details
10+
11+
For `gcc`, we are using the compiler version `tags/2023.10.06`, as using the binaries from `apt install gcc-riscv64-unknown-elf` will cause `"unsupported ISA subset 'z'"` error during the compilation of the emulator on M1.
12+
13+
For `sail`, we set up the toolchain to use `sail-0.16`, as the latest version `0.17.x` series will cause compilation errors.
14+
15+
We are using the commit `9547a30bf84572c458476591b569a95f5232c1c7` from `sail-riscv` for the reference simulator, as this is the commit cloest to the time when the [x86-64 reference sail emulator](https://github.com/sysprog21/rv32emu/commit/01b00b6f175f57ef39ffd1f4fa6a611891e36df3#diff-3b436c5e32c40ecca4095bdacc1fb69c0759096f86e029238ce34bbe73c6e68f) was added to the `rv32emu` Github repo.

0 commit comments

Comments
 (0)