Skip to content

ESP32: C5 and C61 support #6181

ESP32: C5 and C61 support

ESP32: C5 and C61 support #6181

Workflow file for this run

#
# Copyright 2017-2022 Davide Bettio <[email protected]>
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#
name: Build and Test
on:
push:
paths-ignore:
- 'src/platforms/emscripten/**'
- 'src/platforms/esp32/**'
- 'src/platforms/rp2/**'
- 'src/platforms/stm32/**'
- 'doc/**'
- 'LICENSES/**'
- '*.Md'
- '*.md'
pull_request:
paths-ignore:
- 'src/platforms/emscripten/**'
- 'src/platforms/esp32/**'
- 'src/platforms/rp2/**'
- 'src/platforms/stm32/**'
- 'doc/**'
- 'LICENSES/**'
- '*.Md'
- '*.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref != 'refs/heads/main' && github.ref || github.run_id }}
cancel-in-progress: true
jobs:
build-and-test:
runs-on: ${{ matrix.os || 'ubuntu-24.04' }}
container: ${{ matrix.container }}
strategy:
fail-fast: false
matrix:
# Ubuntu 20.04 has gcc from 7 to 10 ("gcc" is gcc-9)
# Ubuntu 22.04 has gcc from 9 to 12 ("gcc" is gcc-11)
# Ubuntu 24.04 has gcc from 9 to 14 ("gcc" is gcc-13)
# Ubuntu 20.04 has clang 10 and 12 to ("clang" is 10)
# Ubuntu 22.04 has clang from 12 to 15 ("clang" is 14)
# Ubuntu 24.04 has clang from 14 to 18 ("clang" is 18)
# We want to test every compiler but don't need to test every OS
# We only test several OTP versions with default compilers (gcc-9, 11, 13, clang-10, 14, 18)
cc: ["gcc-9", "gcc-11", "gcc-13", "clang-10", "clang-14", "clang-18"]
cflags: ["-O3"]
otp: ["25", "26", "27"]
gleam_version: ["1.11.1"]
include:
- cc: "gcc-7"
cxx: "g++-7"
compiler_pkgs: "gcc-7 g++-7"
container: "ubuntu:20.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "gcc-8"
cxx: "g++-8"
compiler_pkgs: "gcc-8 g++-8"
container: "ubuntu:20.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "gcc-9"
cxx: "g++-9"
compiler_pkgs: "gcc-9 g++-9"
container: "ubuntu:20.04"
# otp: all
- cc: "gcc-10"
cxx: "g++-10"
compiler_pkgs: "gcc-10 g++-10"
# Use Werror for recent GCC versions that have better diagnostics
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-22.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "gcc-11"
cxx: "g++-11"
compiler_pkgs: "gcc-11 g++-11"
# Use Werror for recent GCC versions that have better diagnostics
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-22.04"
# otp: all
- cc: "gcc-12"
cxx: "g++-12"
compiler_pkgs: "gcc-12 g++-12"
# Use Werror for recent GCC versions that have better diagnostics
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-24.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "gcc-13"
cxx: "g++-13"
compiler_pkgs: "gcc-13 g++-13"
# Use Werror for recent GCC versions that have better diagnostics
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-24.04"
# otp: all
- cc: "gcc-14"
cxx: "g++-14"
compiler_pkgs: "gcc-14 g++-14"
# Use Werror for recent GCC versions that have better diagnostics
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-24.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "clang-10"
cxx: "clang++-10"
compiler_pkgs: "clang-10"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
container: "ubuntu:20.04"
# otp: all
- cc: "clang-11"
cxx: "clang++-11"
compiler_pkgs: "clang-11"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
container: "ubuntu:20.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "clang-12"
cxx: "clang++-12"
compiler_pkgs: "clang-12"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-22.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "clang-13"
cxx: "clang++-13"
compiler_pkgs: "clang-13"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-22.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "clang-14"
cxx: "clang++-14"
compiler_pkgs: "clang-14"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-22.04"
# otp: all
- cc: "clang-15"
cxx: "clang++-15"
compiler_pkgs: "clang-15"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-24.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "clang-16"
cxx: "clang++-16"
compiler_pkgs: "clang-16"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-24.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "clang-17"
cxx: "clang++-17"
compiler_pkgs: "clang-17"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-24.04"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- cc: "clang-18"
cxx: "clang++-18"
compiler_pkgs: "clang-18"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON"
os: "ubuntu-24.04"
# otp: all
- otp: "25"
elixir_version: "1.14"
rebar3_version: "3.24.0"
- otp: "26"
elixir_version: "1.17"
rebar3_version: "3.24.0"
- otp: "27"
elixir_version: "1.18"
rebar3_version: "3.24.0"
# Old versions of OTP/Elixir
- container: "ubuntu:20.04"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "21"
elixir_version: "1.7"
rebar3_version: "3.15.2"
compiler_pkgs: "g++"
- container: "ubuntu:20.04"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "22"
elixir_version: "1.8"
rebar3_version: "3.18.0"
compiler_pkgs: "g++"
- container: "ubuntu:20.04"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "23"
elixir_version: "1.11"
rebar3_version: "3.20.0"
compiler_pkgs: "g++"
- container: "ubuntu:20.04"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "24"
elixir_version: "1.14"
rebar3_version: "3.23.0"
compiler_pkgs: "g++"
- os: "ubuntu-24.04"
cc: "cc"
cxx: "c++"
otp: "master"
elixir_version: "main"
rebar3_version: "3.24.0"
# Additional default compiler builds
- container: "ubuntu:20.04"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
compiler_pkgs: "g++"
- os: "ubuntu-22.04"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
# Additional latest & -Os compiler builds
- os: "ubuntu-24.04"
cc: "gcc-14"
cxx: "g++-14"
cflags: "-Os"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
compiler_pkgs: "gcc-14 g++-14"
- os: "ubuntu-24.04"
cc: "clang-18"
cxx: "clang++-18"
cflags: "-Os"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
compiler_pkgs: "clang-18"
# Additional build with 32 bits floats
- os: "ubuntu-24.04"
cc: "cc"
cxx: "c++"
otp: "27"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_USE_32BIT_FLOAT=ON"
# Additional 32 bits build
- container: "ubuntu:20.04"
cc: "gcc-10"
cxx: "g++-10"
cflags: "-m32 -O3"
otp: "23"
elixir_version: "1.11"
rebar3_version: "3.20.0"
# Use Werror so we get an error with 32 bit specific warnings
cmake_opts_other: "-DAVM_CREATE_STACKTRACES=off -DAVM_WARNINGS_ARE_ERRORS=ON"
arch: "i386"
compiler_pkgs: "gcc-10 g++-10 gcc-10-multilib g++-10-multilib libc6-dev-i386
libc6-dbg:i386 zlib1g-dev:i386 libmbedtls-dev:i386"
# JIT build
- os: "ubuntu-24.04"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_DISABLE_JIT=OFF"
jit_target_arch: "x86_64"
# arm64 builds
- os: "ubuntu-24.04-arm"
cc: "cc"
cxx: "c++"
cflags: "-O2"
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=OFF"
- os: "ubuntu-24.04-arm"
cc: "cc"
cxx: "c++"
cflags: ""
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_DISABLE_JIT=OFF"
jit_target_arch: "aarch64"
# armhf builds
- os: "ubuntu-24.04"
cc: "arm-linux-gnueabihf-gcc"
cxx: "arm-linux-gnueabihf-g++"
# -D_FILE_OFFSET_BITS=64 is required for making atomvm:posix_readdir/1 test work
# otherwise readdir will fail due to 64 bits inode numbers with 32 bit ino_t
cflags: "-mcpu=cortex-a7 -mfloat-abi=hard -O2 -mthumb -mthumb-interwork -D_FILE_OFFSET_BITS=64"
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/armhf_toolchain.cmake"
compiler_pkgs: "crossbuild-essential-armhf libc6-dbg:armhf zlib1g-dev:armhf libmbedtls-dev:armhf qemu-user qemu-user-binfmt binfmt-support"
arch: "armhf"
library-arch: arm-linux-gnueabihf
- os: "ubuntu-24.04"
cc: "arm-linux-gnueabihf-gcc"
cxx: "arm-linux-gnueabihf-g++"
# -D_FILE_OFFSET_BITS=64 is required for making atomvm:posix_readdir/1 test work
# otherwise readdir will fail due to 64 bits inode numbers with 32 bit ino_t
cflags: "-mcpu=cortex-a7 -mfloat-abi=hard -O2 -mthumb -mthumb-interwork -D_FILE_OFFSET_BITS=64"
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_DISABLE_JIT=OFF -DAVM_JIT_TARGET_ARCH=armv6m -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/armhf_toolchain.cmake"
compiler_pkgs: "crossbuild-essential-armhf libc6-dbg:armhf zlib1g-dev:armhf libmbedtls-dev:armhf qemu-user qemu-user-binfmt binfmt-support"
arch: "armhf"
library-arch: arm-linux-gnueabihf
jit_target_arch: "armv6m"
# s390x build
- os: "ubuntu-24.04"
cc: "s390x-linux-gnu-gcc"
cxx: "s390x-linux-gnu-g++"
# -D_FILE_OFFSET_BITS=64 is required for making atomvm:posix_readdir/1 test work
# otherwise readdir will fail due to 64 bits inode numbers with 32 bit ino_t
cflags: "-O2"
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/s390x_toolchain.cmake"
compiler_pkgs: "crossbuild-essential-s390x libc6-dbg:s390x zlib1g-dev:s390x libmbedtls-dev:s390x qemu-user qemu-user-binfmt binfmt-support"
arch: "s390x"
library-arch: s390x-linux-gnu
# riscv32-ilp32 build
- os: "ubuntu-24.04"
cc: "riscv32-unknown-linux-gnu-gcc"
cxx: "riscv32-unknown-linux-gnu-g++"
cflags: "-O2"
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/riscv32_ilp32_toolchain.cmake"
compiler_pkgs: "qemu-user qemu-user-binfmt binfmt-support"
arch: "riscv32"
library-arch: riscv32-linux-gnu-ilp32
# riscv32-ilp32 build + jit
- os: "ubuntu-24.04"
cc: "riscv32-unknown-linux-gnu-gcc"
cxx: "riscv32-unknown-linux-gnu-g++"
cflags: "-O2"
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_DISABLE_JIT=OFF -DAVM_JIT_TARGET_ARCH=riscv32 -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/riscv32_ilp32_toolchain.cmake"
compiler_pkgs: "qemu-user qemu-user-binfmt binfmt-support"
arch: "riscv32"
library-arch: riscv32-linux-gnu-ilp32
jit_target_arch: "riscv32"
env:
ImageOS: ${{ matrix.container == 'ubuntu:20.04' && 'ubuntu20' || matrix.os == 'ubuntu-20.04' && 'ubuntu20' || matrix.os == 'ubuntu-22.04' && 'ubuntu22' || matrix.os == 'ubuntu-24.04' && 'ubuntu24' || 'ubuntu24' }}
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
CFLAGS: ${{ matrix.cflags }}
CXXFLAGS: ${{ matrix.cflags }}
DEBIAN_FRONTEND: noninteractive
TZ: "Etc/UTC"
steps:
# Setup
- name: "Install deps for containers"
if: matrix.container != ''
run: apt-get update && apt-get install -y --no-install-recommends sudo unzip git tzdata
- name: "Add i386 architecture"
if: matrix.arch == 'i386'
run: sudo dpkg --add-architecture i386
- name: "Setup cross compilation architecture"
if: matrix.library-arch != '' && matrix.library-arch != 'riscv32-linux-gnu-ilp32'
run: |
# Replace Azure mirrors with official Ubuntu repositories
sudo sed -i 's|azure\.||g' /etc/apt/sources.list
sudo sed -i 's|azure\.||g' /etc/apt/sources.list.d/*.list 2>/dev/null || true
# Handle new DEB822 format
if [ -f /etc/apt/apt-mirrors.txt ]; then
sudo sed -i 's|azure\.||g' /etc/apt/apt-mirrors.txt
fi
sudo dpkg --add-architecture ${{ matrix.arch }}
cat > ${RUNNER_TEMP}/cross-compile-sources.list <<EOF
deb [arch=${{ matrix.arch }}] http://ports.ubuntu.com/ noble main restricted
deb [arch=${{ matrix.arch }}] http://ports.ubuntu.com/ noble-updates main restricted
deb [arch=${{ matrix.arch }}] http://ports.ubuntu.com/ noble universe
deb [arch=${{ matrix.arch }}] http://ports.ubuntu.com/ noble-updates universe
deb [arch=${{ matrix.arch }}] http://ports.ubuntu.com/ noble multiverse
deb [arch=${{ matrix.arch }}] http://ports.ubuntu.com/ noble-updates multiverse
deb [arch=${{ matrix.arch }}] http://ports.ubuntu.com/ noble-backports main restricted universe multiverse
EOF
sudo mv ${RUNNER_TEMP}/cross-compile-sources.list /etc/apt/sources.list.d/
sudo sed -i '/Types: deb/a Architectures: amd64' /etc/apt/sources.list.d/ubuntu.sources
cat > ${RUNNER_TEMP}/${{ matrix.arch }}_toolchain.cmake <<EOF
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_LIBRARY_ARCHITECTURE ${{ matrix.library-arch }})
set(ZLIB_LIBRARY /usr/lib/${{ matrix.library-arch }}/libz.so)
set(MBEDTLS_ROOT_DIR /usr)
set(MBEDTLS_LIBRARIES_DIR /usr/lib/${{ matrix.library-arch }})
EOF
- name: "Setup cross compilation architecture (riscv32)"
if: matrix.library-arch == 'riscv32-linux-gnu-ilp32'
run: |
sudo dpkg --add-architecture ${{ matrix.arch }}
# Download toolchain and libraries from release
gh release download riscv-toolchain-2025.10.18 \
-R pguyot/crossbuild-essential-riscv32 \
--pattern 'riscv32-gnu-toolchain-ilp32_2025.10.18_amd64.deb' \
--pattern 'libc6-ilp32_2.39-0ubuntu1_riscv32.deb' \
--pattern 'libc6-dev-ilp32_2.39-0ubuntu1_riscv32.deb' \
--pattern 'libc6-dbg-ilp32_2.39-0ubuntu1_riscv32.deb' \
--pattern 'zlib1g-ilp32_1.3.1-0ubuntu1_riscv32.deb' \
--pattern 'zlib1g-dev-ilp32_1.3.1-0ubuntu1_riscv32.deb' \
--pattern 'libmbedcrypto7-ilp32_2.28.8-0ubuntu1_riscv32.deb' \
--pattern 'libmbedtls-dev-ilp32_2.28.8-0ubuntu1_riscv32.deb' \
--pattern 'libmbedtls14-ilp32_2.28.8-0ubuntu1_riscv32.deb' \
--pattern 'libmbedx509-1-ilp32_2.28.8-0ubuntu1_riscv32.deb'
# Install the toolchain
sudo dpkg -i riscv32-gnu-toolchain-ilp32_2025.10.18_amd64.deb
# Add to PATH for all subsequent steps
echo "/opt/riscv32-ilp32/bin" >> $GITHUB_PATH
# Install the libs
sudo dpkg -i libc6-ilp32_2.39-0ubuntu1_riscv32.deb
sudo dpkg -i libc6-dev-ilp32_2.39-0ubuntu1_riscv32.deb
sudo dpkg -i libc6-dbg-ilp32_2.39-0ubuntu1_riscv32.deb
sudo dpkg -i zlib1g-ilp32_1.3.1-0ubuntu1_riscv32.deb
sudo dpkg -i zlib1g-dev-ilp32_1.3.1-0ubuntu1_riscv32.deb
# Install mbedtls runtime packages first (in dependency order)
sudo dpkg -i libmbedcrypto7-ilp32_2.28.8-0ubuntu1_riscv32.deb
sudo dpkg -i libmbedx509-1-ilp32_2.28.8-0ubuntu1_riscv32.deb
sudo dpkg -i libmbedtls14-ilp32_2.28.8-0ubuntu1_riscv32.deb
# Then install the dev package
sudo dpkg -i libmbedtls-dev-ilp32_2.28.8-0ubuntu1_riscv32.deb
sudo sed -i '/Types: deb/a Architectures: amd64' /etc/apt/sources.list.d/ubuntu.sources
cat > ${RUNNER_TEMP}/riscv32_ilp32_toolchain.cmake <<'EOF'
# Toolchain file for RISC-V32 ILP32 (RV32-IMAC) cross-compilation
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR riscv32)
set(CMAKE_C_LIBRARY_ARCHITECTURE riscv32-linux-gnu-ilp32)
# Specify the cross compiler
set(CMAKE_C_COMPILER riscv32-unknown-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER riscv32-unknown-linux-gnu-g++)
# Specify the target architecture
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv32imac -mabi=ilp32" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv32imac -mabi=ilp32" CACHE STRING "" FORCE)
# Set up paths for cross-compiled libraries
set(ZLIB_LIBRARY /usr/lib/riscv32-linux-gnu-ilp32/libz.so CACHE FILEPATH "")
set(ZLIB_INCLUDE_DIR /usr/include/riscv32-linux-gnu CACHE PATH "")
set(ZLIB_FOUND TRUE CACHE BOOL "")
# MbedTLS configuration
set(MBEDTLS_ROOT_DIR /usr)
set(MBEDTLS_LIBRARIES_DIR /usr/lib/riscv32-linux-gnu-ilp32)
# Add cross-compilation include path to compiler flags
include_directories(SYSTEM /usr/include/riscv32-linux-gnu)
# Search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Search for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOF
# Set up qemu-user binfmt to find libraries
sudo ln -s /opt/riscv32-ilp32/sysroot/lib/ld-linux-riscv32-ilp32.so.1 /lib/ld-linux-riscv32-ilp32.so.1
sudo mkdir -p /usr/gnemul
sudo ln -s /opt/riscv32-ilp32/sysroot /usr/gnemul/qemu-riscv32
# Copy cross-compiled libraries to sysroot for qemu-user
sudo cp /usr/lib/${{ matrix.library-arch }}/libz.so.1* /opt/riscv32-ilp32/sysroot/lib/
sudo cp /usr/lib/${{ matrix.library-arch }}/libmbedtls.so.14 /opt/riscv32-ilp32/sysroot/lib/
sudo cp /usr/lib/${{ matrix.library-arch }}/libmbedcrypto.so.7 /opt/riscv32-ilp32/sysroot/lib/
sudo cp /usr/lib/${{ matrix.library-arch }}/libmbedx509.so.1 /opt/riscv32-ilp32/sysroot/lib/
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "APT update"
run: sudo apt update -y
- name: "Install deps"
if: matrix.container != ''
run: sudo apt install -y ${{ matrix.compiler_pkgs}} cmake gperf zlib1g-dev doxygen valgrind libmbedtls-dev
- name: "Install deps"
if: matrix.container == ''
run: |
sudo apt install -y ${{ matrix.compiler_pkgs}} cmake gperf zlib1g-dev doxygen libmbedtls-dev libc6-dbg
# Get a more recent valgrind
sudo snap install valgrind --classic
- name: "Checkout repo"
uses: actions/checkout@v4
with:
submodules: 'recursive'
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ matrix.otp }}
elixir-version: ${{ matrix.elixir_version }}
rebar3-version: ${{ matrix.rebar3_version }}
gleam-version: ${{ matrix.gleam_version }}
hexpm-mirrors: |
https://builds.hex.pm
https://repo.hex.pm
https://cdn.jsdelivr.net/hex
# Builder info
- name: "System info"
run: |
echo "**uname:**"
uname -a
echo "**libc version:**"
ldd --version
echo "**C Compiler version:**"
$CC --version
$CXX --version
echo "**Linker version:**"
ld --version
echo "**CMake version:**"
cmake --version
echo "**OTP version:**"
cat $(dirname $(which erlc))/../releases/RELEASES || true
# Build
- name: "Build: create build dir"
run: mkdir build
- uses: actions/cache@v4
id: cache
with:
path: 'build/tests/**/*.beam'
key: ${{ matrix.otp }}-${{ hashFiles('**/build-and-test.yaml', 'tests/**/*.erl', 'tests/**/*.hrl', 'tests/**/*.ex') }}-${{ matrix.jit_target_arch }}
- name: "Build: run cmake"
working-directory: build
run: |
cmake ${{ matrix.cmake_opts_fp }} ${{ matrix.cmake_opts_smp }} ${{ matrix.cmake_opts_other }} ..
# git clone will use more recent timestamps than cached beam files
# touch them so we can benefit from the cache and avoid costly beam file rebuild.
find . -name '*.beam' -exec touch {} \;
- name: "Build: run make"
working-directory: build
run: make -j3
- name: "Build: run dialyzer"
working-directory: build
run: make dialyzer
# Test
- name: "Test: test-erlang with valgrind"
if: matrix.library-arch == ''
timeout-minutes: 30
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./tests/test-erlang -s prime_smp
- name: "Test: test-erlang"
timeout-minutes: 10
working-directory: build
run: |
ulimit -c unlimited
./tests/test-erlang -s prime_smp
- name: "Test: test-enif with valgrind"
if: matrix.library-arch == ''
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./tests/test-enif
- name: "Test: test-enif"
working-directory: build
run: |
ulimit -c unlimited
./tests/test-enif
- name: "Test: test-heap with valgrind"
if: matrix.library-arch == ''
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./tests/test-heap
- name: "Test: test-heap"
working-directory: build
run: |
ulimit -c unlimited
./tests/test-heap
- name: "Test: test-jit_stream_flash with valgrind"
if: matrix.library-arch == ''
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./tests/test-jit_stream_flash
- name: "Test: test-jit_stream_flash"
working-directory: build
run: |
ulimit -c unlimited
./tests/test-jit_stream_flash
- name: "Test: test-mailbox with valgrind"
if: matrix.library-arch == ''
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./tests/test-mailbox
- name: "Test: test-mailbox"
working-directory: build
run: |
ulimit -c unlimited
./tests/test-mailbox
- name: "Test: test-structs with valgrind"
if: matrix.library-arch == ''
timeout-minutes: 10
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./tests/test-structs
- name: "Test: test-structs"
timeout-minutes: 10
working-directory: build
run: |
ulimit -c unlimited
./tests/test-structs
- name: "Test: test_etest.avm with valgrind"
if: matrix.library-arch == ''
timeout-minutes: 5
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./src/AtomVM ./tests/libs/etest/test_etest.avm
- name: "Test: test_etest.avm"
timeout-minutes: 5
working-directory: build
run: |
ulimit -c unlimited
./src/AtomVM ./tests/libs/etest/test_etest.avm
- name: "Test: test_estdlib.avm with valgrind"
if: matrix.library-arch == ''
timeout-minutes: 30
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./src/AtomVM ./tests/libs/estdlib/test_estdlib.avm
- name: "Test: test_estdlib.avm"
timeout-minutes: 20
working-directory: build
run: |
ulimit -c unlimited
./src/AtomVM ./tests/libs/estdlib/test_estdlib.avm
- name: "Test: test_eavmlib.avm with valgrind"
if: matrix.library-arch == ''
timeout-minutes: 10
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./src/AtomVM ./tests/libs/eavmlib/test_eavmlib.avm
- name: "Test: test_eavmlib.avm"
timeout-minutes: 10
working-directory: build
run: |
ulimit -c unlimited
./src/AtomVM ./tests/libs/eavmlib/test_eavmlib.avm
- name: "Test: test_jit.avm with valgrind"
if: matrix.library-arch == '' && matrix.otp != '21' && matrix.otp != '22'
timeout-minutes: 60
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./src/AtomVM tests/libs/jit/test_jit.avm
- name: "Test: test_jit.avm"
timeout-minutes: 60
if: matrix.otp != '21' && matrix.otp != '22'
working-directory: build
run: |
ulimit -c unlimited
./src/AtomVM tests/libs/jit/test_jit.avm
- name: "Test: test_alisp.avm with valgrind"
if: matrix.library-arch == ''
timeout-minutes: 20
working-directory: build
run: |
ulimit -c unlimited
valgrind --error-exitcode=1 ./src/AtomVM ./tests/libs/alisp/test_alisp.avm
- name: "Test: test_alisp.avm"
timeout-minutes: 10
working-directory: build
run: |
ulimit -c unlimited
./src/AtomVM ./tests/libs/alisp/test_alisp.avm
- name: "Test: Tests.avm (Elixir) with valgrind"
if: matrix.library-arch == ''
timeout-minutes: 20
working-directory: build
run: |
ulimit -c unlimited
if command -v elixirc >/dev/null 2>&1 && command -v elixir >/dev/null 2>&1
then
valgrind --error-exitcode=1 ./src/AtomVM ./tests/libs/exavmlib/Tests.avm
else
echo "Elixir not installed, skipping Elixir tests"
fi
- name: "Test: Tests.avm (Elixir)"
timeout-minutes: 10
working-directory: build
run: |
ulimit -c unlimited
if command -v elixirc >/dev/null 2>&1 && command -v elixir >/dev/null 2>&1
then
./src/AtomVM ./tests/libs/exavmlib/Tests.avm
else
echo "Elixir not installed, skipping Elixir tests"
fi
- name: "Install and smoke test"
working-directory: build
run: |
ulimit -c unlimited
sudo PATH=${PATH} make install
atomvm examples/erlang/hello_world.avm
atomvm -v
atomvm -h
- name: "Run coredumpctl info"
if: ${{ failure() }}
run: |
# Wait until systemd-coredump finished
while ps x | grep -cE 'systemd-[c]oredump'; do
echo systemd-coredump is still running
sleep 1
done
# info works on all versions of ubuntu
coredumpctl info || true
# The following only works on recent versions of ubuntu
coredumpctl debug --debugger-arguments="-batch -ex 'info all-registers'" || true
coredumpctl debug --debugger-arguments="-batch -ex 'info threads'" || true
coredumpctl debug --debugger-arguments="-batch -ex 'thread apply all bt full'" || true
coredumpctl debug --debugger-arguments='-batch -ex "display /10i $pc"' || true
coredumpctl dump -o core.dump || true
if [ -e core.dump ]; then
mkdir core
mv core.dump core/
cp build/src/AtomVM core/
cp build/tests/test-* core/
fi
- name: "Upload any dumped core"
uses: actions/upload-artifact@v4
if: ${{ failure() }}
with:
name: core-${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.otp }}-${{ github.run_id }}-${{ github.run_attempt }}
path: |
core/*
retention-days: 5