Five EmbedDev logo Five EmbedDev

An Embedded RISC-V Blog

Containerized Development

Modern development is moving towards packaging tools in containers. There are several benefits to containerizing development tools:

For RISC-V there are a few more benefits:

I’ve put together a set of Docker images and Docker Compose build and run configurations with the aim of deploying them with GitHub’s workflows.

They are located here: https://github.com/five-embeddev/build-and-verify

Image Design

Each image creates a default WORKDIR location /project that is owned by the docker user. The local development directory can be bind mounted to that path.

The path to the tools is always added to the PATH environment variable.

The container runs everything as user docker_user with UID of 1000 by default.

Examples

To build a target binary call docker directly or setup a docker-compose configuration compose.yaml with the container environment. The command line to be run in the container is passed as the arguments following the container run command and it’s arguments.

e.g. Compile test.c in the current directory with the riscv-gnu-toolchain and delete the container after running:

docker \
 run \
     --rm \
     -v `pwd`:/project \
     five_embeddev/riscv_gnu_toolchain_dev_env \
     riscv32-unknown-elf-gcc test.c -o test.elf

OR user docker-compose with all of that captured in a compose.yaml file:

version: "3"
services:

  build_gnu_toolchain:
    image: five_embeddev/riscv_gnu_toolchain_dev_env
    volumes:
        - .:/project
    command: ["riscv32-unknown-elf-gcc", "test.c",  "-o", "test.elf" ]

Then docker-compose can simply run the build.

docker-compose run build_gnu_toolchain

Image Details

The images have been setup with a docker user (by default UID 1000), and the tools are installed to /opt or to the docker user’s home directory and added to the PATH environment variable. There are Makefiles to build the images, if those are used the current user UID is used by the docker image default user. That allows the user’s file system to be mounted within the container and file ownership handled correctly. (By default docker containers runs as root, which can result in root owned target binaries.)

When tools are compiled from source the default method is to shallow clone the source code within the container and build there. This captures the build process in the Dockerfile, but is inefficient due to the docker caching mechanism. The riscv-gnu-toolchain build script does this but requires a large amount of resources.

Due to the resource requirements of building the entire toolchain the riscv-gnu-toolchain-2 build script stores the source and build files in host file system and mounts into the container via docker volumes. Those can’t be used by a docker build process, so the build process is more complex and relies on the Makefile. This build script should be preferred.