11# Base Image (ci-base)
2+ #
3+ # This image contains all tools required for CI operation, except the Zephyr SDK.
24
35FROM ubuntu:24.04
46
57ARG USERNAME=user
68ARG UID=1000
79ARG GID=1000
810ARG PYTHON_VENV_PATH=/opt/python/venv
11+ ARG WGET_ARGS="-q --show-progress --progress=bar:force:noscroll"
912ARG UBUNTU_MIRROR_ARCHIVE=archive.ubuntu.com/ubuntu
1013ARG UBUNTU_MIRROR_SECURITY=security.ubuntu.com/ubuntu
1114ARG UBUNTU_MIRROR_PORTS=ports.ubuntu.com/ubuntu-ports
1215
16+ ARG KITWARE_NINJA_VERSION=1.11.1.g95dee.kitware.jobserver-1
17+ ENV KITWARE_NINJA_VERSION=$KITWARE_NINJA_VERSION
18+ ARG CCACHE_VERSION=4.9.1
19+ ENV CCACHE_VERSION=$CCACHE_VERSION
20+ ARG DOXYGEN_VERSION=1.14.0
21+ ENV DOXYGEN_VERSION=$DOXYGEN_VERSION
22+ ARG RENODE_VERSION=1.15.3
23+ ENV RENODE_VERSION=$RENODE_VERSION
24+ ARG LLVM_VERSION=20
25+ ENV LLVM_VERSION=$LLVM_VERSION
26+ ARG BSIM_VERSION=v2.7
27+ ENV BSIM_VERSION=$BSIM_VERSION
28+ ARG SPARSE_VERSION=9212270048c3bd23f56c20a83d4f89b870b2b26e
29+ ENV SPARSE_VERSION=$SPARSE_VERSION
30+ ARG PROTOC_VERSION=21.7
31+ ENV PROTOC_VERSION=$PROTOC_VERSION
32+ ARG FVP_BASE_REVC_VERSION=11.27_19
33+ ENV FVP_BASE_REVC_VERSION=$FVP_BASE_REVC_VERSION
34+ ARG FVP_BASE_AEMV8R_VERSION=11.27_19
35+ ENV FVP_BASE_AEMV8R_VERSION=$FVP_BASE_AEMV8R_VERSION
36+ ARG FVP_CORSTONE300_VERSION=11.27_42
37+ ENV FVP_CORSTONE300_VERSION=$FVP_CORSTONE300_VERSION
38+ ARG FVP_CORSTONE310_VERSION=11.27_42
39+ ENV FVP_CORSTONE310_VERSION=$FVP_CORSTONE310_VERSION
40+ ARG FVP_CORSTONE315_VERSION=11.27_42
41+ ENV FVP_CORSTONE315_VERSION=$FVP_CORSTONE315_VERSION
42+ ARG FVP_CORSTONE320_VERSION=11.27_25
43+ ENV FVP_CORSTONE320_VERSION=$FVP_CORSTONE320_VERSION
44+
1345# Set default shell during Docker image build to bash
1446SHELL ["/bin/bash", "-eo", "pipefail", "-c"]
1547
@@ -123,6 +155,17 @@ RUN <<EOF
123155 libsdl2-dev:i386
124156 fi
125157
158+ # Install LLVM and Clang
159+ wget ${WGET_ARGS} https://apt.llvm.org/llvm.sh
160+ chmod +x llvm.sh
161+ ./llvm.sh ${LLVM_VERSION} all
162+ rm -f llvm.sh
163+
164+ # Install Python 3.9 for FVP
165+ add-apt-repository -y ppa:deadsnakes/ppa
166+ apt-get update -y
167+ apt-get install -y python3.9-dev
168+
126169 # Clean up stale packages
127170 apt-get autoremove --purge -y
128171
@@ -136,6 +179,10 @@ RUN <<EOF
136179 popd
137180EOF
138181
182+ # Set build environment variables
183+ ENV PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
184+ ENV OVMF_FD_PATH=/usr/share/ovmf/OVMF.fd
185+
139186# Initialise system locale
140187RUN locale-gen en_US.UTF-8
141188ENV LANG=en_US.UTF-8
@@ -182,6 +229,159 @@ EOF
182229# Make Zephyr Python virtual environment available globally
183230ENV PATH=${PYTHON_VENV_PATH}/bin:$PATH
184231
232+ # Install Kitware ninja
233+ # NOTE: Pre-built Kitware ninja binaries are only available for x86_64 host.
234+ RUN <<EOF
235+ if [ "${HOSTTYPE}" = "x86_64" ]; then
236+ wget ${WGET_ARGS} https://github.com/Kitware/ninja/releases/download/v${KITWARE_NINJA_VERSION}/ninja-${KITWARE_NINJA_VERSION}_x86_64-linux-gnu.tar.gz
237+ tar xf ninja-${KITWARE_NINJA_VERSION}_x86_64-linux-gnu.tar.gz -C /opt
238+ ln -s /opt/ninja-${KITWARE_NINJA_VERSION}_x86_64-linux-gnu/ninja /usr/local/bin
239+ rm ninja-${KITWARE_NINJA_VERSION}_x86_64-linux-gnu.tar.gz
240+ fi
241+ EOF
242+
243+ # Install ccache
244+ # NOTE: Pre-built ccache binaries are only available for x86_64 host.
245+ RUN <<EOF
246+ if [ "${HOSTTYPE}" = "x86_64" ]; then
247+ wget ${WGET_ARGS} https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}-linux-x86_64.tar.xz
248+ tar xf ccache-${CCACHE_VERSION}-linux-x86_64.tar.xz -C /opt
249+ ln -s /opt/ccache-${CCACHE_VERSION}-linux-x86_64/ccache /usr/local/bin
250+ rm ccache-${CCACHE_VERSION}-linux-x86_64.tar.xz
251+ fi
252+ EOF
253+
254+ # Install Doxygen (x86 only)
255+ # NOTE: Pre-built Doxygen binaries are only available for x86_64 host.
256+ RUN <<EOF
257+ if [ "${HOSTTYPE}" = "x86_64" ]; then
258+ wget ${WGET_ARGS} "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz"
259+ tar xf doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz -C /opt
260+ ln -s /opt/doxygen-${DOXYGEN_VERSION}/bin/doxygen /usr/local/bin
261+ rm doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz
262+ fi
263+ EOF
264+
265+ # Install BSIM
266+ # Note: west needs an extra folder level, so we create a link to the old location to be backwards compatible
267+ RUN <<EOF
268+ mkdir -p /opt/bsim_west
269+ cd /opt/
270+ west init -m https://github.com/zephyrproject-rtos/babblesim-manifest.git --mr ${BSIM_VERSION} bsim_west
271+ cd bsim_west/bsim
272+ west update
273+ make everything -j 8
274+ echo ${BSIM_VERSION} > ./version
275+ chmod ag+w . -R
276+ ln -s /opt/bsim_west/bsim /opt/bsim
277+ EOF
278+
279+ # Install sparse package for static analysis
280+ RUN <<EOF
281+ mkdir -p /opt/sparse
282+ cd /opt/sparse
283+ git clone https://git.kernel.org/pub/scm/devel/sparse/sparse.git
284+ cd sparse
285+ git checkout ${SPARSE_VERSION}
286+ make -j8
287+ PREFIX=/opt/sparse make install
288+ rm -rf /opt/sparse/sparse
289+ EOF
290+
291+ # Install protobuf-compiler
292+ RUN <<EOF
293+ mkdir -p /opt/protoc
294+ cd /opt/protoc
295+ PROTOC_HOSTTYPE=$(case $HOSTTYPE in x86_64) echo "x86_64";; aarch64) echo "aarch_64";; esac)
296+ wget ${WGET_ARGS} https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-${PROTOC_HOSTTYPE}.zip
297+ unzip protoc-${PROTOC_VERSION}-linux-${PROTOC_HOSTTYPE}.zip
298+ ln -s /opt/protoc/bin/protoc /usr/local/bin
299+ rm -f protoc-${PROTOC_VERSION}-linux-${PROTOC_HOSTTYPE}.zip
300+ EOF
301+
302+ # Install renode (x86 only)
303+ # NOTE: Renode is currently only available for x86_64 host.
304+ # We're using the portable version of Renode, which is self-contained and includes dotnet
305+ RUN <<EOF
306+ if [ "${HOSTTYPE}" = "x86_64" ]; then
307+ RENODE_FILE=renode-${RENODE_VERSION}.linux-portable-dotnet.tar.gz
308+ wget ${WGET_ARGS} https://github.com/renode/renode/releases/download/v${RENODE_VERSION}/${RENODE_FILE}
309+ mkdir -p /opt/renode
310+ tar xf ${RENODE_FILE} -C /opt/renode --strip-components=1
311+ rm ${RENODE_FILE}
312+ pip3 install -r /opt/renode/tests/requirements.txt --no-cache-dir
313+ fi
314+ EOF
315+
316+ # Add renode to path, make sure not to use the host's path,
317+ # see https://stackoverflow.com/a/65119275
318+ ENV PATH="/opt/renode:$PATH"
319+
320+ # Install FVP
321+ #
322+ # Ecosystem FVP License permits redistribution (refer to the relevant license available in the container).
323+ RUN <<EOF
324+ mkdir -p /opt/fvps
325+ cd /opt/fvps
326+
327+ if [ "${HOSTTYPE}" = "x86_64" ]; then
328+ SUFFIX=""
329+ else
330+ SUFFIX="_armv8l"
331+ fi
332+
333+ declare -A FVP_INSTALLABLE=(
334+ ["300"]="${FVP_CORSTONE300_VERSION}"
335+ ["310"]="${FVP_CORSTONE310_VERSION}"
336+ ["315"]="${FVP_CORSTONE315_VERSION}"
337+ ["320"]="${FVP_CORSTONE320_VERSION}"
338+ )
339+ for corstone in ${!FVP_INSTALLABLE[@]}; do
340+ version_build="${FVP_INSTALLABLE[$corstone]}"
341+ echo "Downloading Corstone-${corstone} ${version_build}"
342+ wget ${WGET_ARGS} -O- https://developer.arm.com/-/cdn-downloads/permalink/FVPs-Corstone-IoT/Corstone-${corstone}/FVP_Corstone_SSE-${corstone}_${version_build}_Linux64${SUFFIX}.tgz | tar xz
343+ ./FVP_Corstone_SSE-${corstone}.sh --no-interactive --i-agree-to-the-contained-eula -d /opt/fvps/Corstone-${corstone}
344+ rm FVP_Corstone_SSE-${corstone}.sh
345+ ln -s /opt/fvps/Corstone-${corstone}/models/*/FVP_* /usr/local/bin
346+ done
347+
348+ declare -A FVP_EXTRACTABLE=(
349+ ["RevC-2xAEMvA"]="${FVP_BASE_REVC_VERSION}"
350+ ["AEMv8R"]="${FVP_BASE_AEMV8R_VERSION}"
351+ )
352+ for base in ${!FVP_EXTRACTABLE[@]}; do
353+ version_build="${FVP_EXTRACTABLE[$base]}"
354+ echo "Downloading Base-${base} ${FVP_EXTRACTABLE[$base]}"
355+ IFS="_" read version build <<< "${version_build}"
356+ wget ${WGET_ARGS} -O- https://developer.arm.com/-/cdn-downloads/permalink/FVPs-Architecture/FM-${version}/FVP_Base_${base}_${version_build}_Linux64${SUFFIX}.tgz | tar xz
357+ done
358+
359+ ln -s /opt/fvps/*_pkg/models/*/FVP_* /usr/local/bin
360+ EOF
361+
362+ ENV ARMFVP_BIN_PATH=/usr/local/bin
363+
364+ # Set up Rust
365+ RUN <<EOF
366+ # Install Cargo package manager
367+ wget -q -O- "https://sh.rustup.rs" | sh -s -- -y --default-toolchain 1.86
368+
369+ # Make Cargo globally available for subsequent steps
370+ PATH=~/.cargo/bin:$PATH
371+
372+ # Install uefi-run utility
373+ cargo install uefi-run --root /usr
374+
375+ # Install Rust target support required by Zephyr
376+ rustup target install riscv32i-unknown-none-elf
377+ rustup target install riscv64imac-unknown-none-elf
378+ rustup target install thumbv6m-none-eabi
379+ rustup target install thumbv7em-none-eabi
380+ rustup target install thumbv7m-none-eabi
381+ rustup target install thumbv8m.main-none-eabi
382+ rustup target install x86_64-unknown-none
383+ EOF
384+
185385# Create user account
186386RUN <<EOF
187387 # Remove 'ubuntu' user to free UID 1000
0 commit comments