Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 113 additions & 2 deletions .github/workflows/build-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,47 @@ jobs:
library-arch: riscv32-linux-gnu-ilp32
jit_target_arch: "riscv32"

# xtensa build (esp32, lx6)
- os: "ubuntu-24.04"
cc: "xtensa-lx6-linux-gnu-gcc"
cxx: "xtensa-lx6-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}/xtensa_toolchain.cmake"
compiler_pkgs: ""
arch: "xtensa"
library-arch: xtensa-lx6-linux-gnu

# xtensa build + jit (esp32, lx6)
- os: "ubuntu-24.04"
cc: "xtensa-lx6-linux-gnu-gcc"
cxx: "xtensa-lx6-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=xtensa -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/xtensa_toolchain.cmake"
compiler_pkgs: ""
arch: "xtensa"
library-arch: xtensa-lx6-linux-gnu
jit_target_arch: "xtensa"

# JIT + DWARF build (xtensa, esp32, lx6)
- os: "ubuntu-24.04"
cc: "xtensa-lx6-linux-gnu-gcc"
cxx: "xtensa-lx6-linux-gnu-g++"
cflags: "-O2"
otp: "28"
elixir_version: "1.17"
rebar3_version: "3.24.0"
cmake_opts_other: "-DAVM_DISABLE_JIT=OFF -DAVM_DISABLE_JIT_DWARF=OFF -DAVM_JIT_TARGET_ARCH=xtensa -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/xtensa_toolchain.cmake"
compiler_pkgs: ""
arch: "xtensa"
library-arch: xtensa-lx6-linux-gnu
jit_target_arch: "xtensa"

# libsodium enabled build
- os: "ubuntu-24.04"
cc: "cc"
Expand Down Expand Up @@ -458,7 +499,7 @@ jobs:
run: sudo dpkg --add-architecture i386

- name: "Setup cross compilation architecture"
if: matrix.library-arch != '' && matrix.library-arch != 'riscv32-linux-gnu-ilp32'
if: matrix.library-arch != '' && matrix.library-arch != 'riscv32-linux-gnu-ilp32' && matrix.library-arch != 'xtensa-lx6-linux-gnu'
run: |
# Replace Azure mirrors with official Ubuntu repositories
sudo sed -i 's|azure\.||g' /etc/apt/sources.list
Expand Down Expand Up @@ -583,6 +624,76 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: "Setup cross compilation architecture (xtensa)"
if: matrix.library-arch == 'xtensa-lx6-linux-gnu'
run: |
sudo dpkg --add-architecture ${{ matrix.arch }}

# Download packages from pguyot/crossbuild-essential-xtensa
gh release download xtensa-toolchain-14.2.0.20260515 \
-R pguyot/crossbuild-essential-xtensa \
--pattern 'qemu-xtensa-esp_*.deb' \
--pattern 'xtensa-lx6-linux-gnu-toolchain_*.deb' \
--pattern 'libc6-lx6_*.deb' \
--pattern 'libc6-dev-lx6_*.deb' \
--pattern 'libc6-dbg-lx6_*.deb' \
--pattern 'zlib1g-lx6_*.deb' \
--pattern 'zlib1g-dev-lx6_*.deb' \
--pattern 'libmbedcrypto7-lx6_*.deb' \
--pattern 'libmbedx509-1-lx6_*.deb' \
--pattern 'libmbedtls14-lx6_*.deb' \
--pattern 'libmbedtls-dev-lx6_*.deb'

# Install QEMU with binfmt support (activates automatically on systemd)
sudo dpkg -i qemu-xtensa-esp_*.deb

# Install toolchain and add to PATH
sudo dpkg -i xtensa-lx6-linux-gnu-toolchain_*.deb
echo "/opt/xtensa-lx6/bin" >> $GITHUB_PATH

# Install runtime libraries
sudo dpkg -i libc6-lx6_*.deb
sudo dpkg -i libc6-dev-lx6_*.deb
sudo dpkg -i libc6-dbg-lx6_*.deb
sudo dpkg -i zlib1g-lx6_*.deb
sudo dpkg -i zlib1g-dev-lx6_*.deb
sudo dpkg -i libmbedcrypto7-lx6_*.deb
sudo dpkg -i libmbedx509-1-lx6_*.deb
sudo dpkg -i libmbedtls14-lx6_*.deb
sudo dpkg -i libmbedtls-dev-lx6_*.deb

# Create CMake toolchain file
cat > ${RUNNER_TEMP}/xtensa_toolchain.cmake <<'EOF'
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR xtensa)

set(CMAKE_C_COMPILER /opt/xtensa-lx6/bin/xtensa-lx6-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /opt/xtensa-lx6/bin/xtensa-lx6-linux-gnu-g++)

set(CMAKE_SYSROOT /opt/xtensa-lx6/xtensa-lx6-linux-gnu/sysroot)
list(APPEND CMAKE_FIND_ROOT_PATH /usr)
set(CMAKE_C_LIBRARY_ARCHITECTURE xtensa-lx6-linux-gnu)

include_directories(SYSTEM /usr/xtensa-lx6-linux-gnu/include)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(ZLIB_LIBRARY /usr/xtensa-lx6-linux-gnu/lib/libz.so)
set(MBEDTLS_ROOT_DIR /usr)
set(MBEDTLS_LIBRARIES_DIR /usr/xtensa-lx6-linux-gnu/lib)
EOF

# Register binfmt if not activated automatically
if [ ! -f /proc/sys/fs/binfmt_misc/qemu-xtensa-esp32 ]; then
echo ':qemu-xtensa-esp32:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x5e\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-xtensa:' | sudo tee /proc/sys/fs/binfmt_misc/register || true
fi

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: "APT update"
run: sudo apt update -y

Expand Down Expand Up @@ -818,7 +929,7 @@ jobs:
valgrind --error-exitcode=1 ./src/AtomVM tests/libs/jit/test_jit.avm

- name: "Test: test_jit.avm"
timeout-minutes: 60
timeout-minutes: 120
working-directory: build
run: |
ulimit -c unlimited
Expand Down
37 changes: 33 additions & 4 deletions .github/workflows/esp32-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,36 @@ jobs:
- 'v5.3.4'
- 'v5.4.3'
- 'v5.5.3'
jit: [false]

include:
- esp-idf-target: "esp32p4"
idf-version: 'v5.4.4'
jit: false
- esp-idf-target: "esp32p4"
idf-version: 'v5.5.3'
jit: false
- esp-idf-target: "esp32s3"
idf-version: 'v5.5.3'
jit: false
- esp-idf-target: "esp32s3"
idf-version: 'v5.5.3'
usb-serial: 'ON'
jit: false
- esp-idf-target: "esp32"
idf-version: 'v5.4.3'
libsodium: 'ON'
jit: false
# JIT builds (v5.5.3 only)
- esp-idf-target: "esp32c3"
idf-version: 'v5.5.3'
jit: true
- esp-idf-target: "esp32"
idf-version: 'v5.5.3'
jit: true
- esp-idf-target: "esp32s3"
idf-version: 'v5.5.3'
jit: true

steps:
- name: Checkout repo
Expand Down Expand Up @@ -105,8 +121,13 @@ jobs:
echo 'CONFIG_USE_USB_SERIAL=y' >> sdkconfig.defaults.in
fi
export IDF_TARGET=${{matrix.esp-idf-target}}
idf.py set-target ${{matrix.esp-idf-target}}
idf.py ${{ matrix.libsodium == 'ON' && '-DAVM_USE_LIBSODIUM=ON' || '' }} build
if [ "${{ matrix.jit }}" = "true" ]; then
SDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.jit" idf.py set-target ${{matrix.esp-idf-target}}
SDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.jit" idf.py build
else
idf.py set-target ${{matrix.esp-idf-target}}
idf.py ${{ matrix.libsodium == 'ON' && '-DAVM_USE_LIBSODIUM=ON' || '' }} build
fi
idf.py size

- name: Print component size info with idf.py
Expand Down Expand Up @@ -216,6 +237,9 @@ jobs:
echo "CONFIG_HEAP_POISONING_COMPREHENSIVE=y" >> sdkconfig.defaults
echo "CONFIG_ESP_WIFI_IRAM_OPT=n" >> sdkconfig.defaults
echo "CONFIG_ESP_WIFI_RX_IRAM_OPT=n" >> sdkconfig.defaults
if [ "${{ matrix.jit }}" = "true" ]; then
echo "CONFIG_JIT_ENABLED=y" >> sdkconfig.defaults
fi
. $IDF_PATH/export.sh
export IDF_TARGET=${{matrix.esp-idf-target}}
idf.py set-target ${{matrix.esp-idf-target}}
Expand All @@ -239,7 +263,7 @@ jobs:
if: failure() && matrix.esp-idf-target != 'esp32p4'
uses: actions/upload-artifact@v4
with:
name: atomvm-esp32-test-${{ matrix.esp-idf-target }}-${{ matrix.idf-version }}-memcheck.elf
name: atomvm-esp32-test-${{ matrix.esp-idf-target }}-${{ matrix.idf-version }}${{ matrix.jit && '-jit' || '' }}-memcheck.elf
path: ./src/platforms/esp32/test/build/atomvm-esp32-test.elf
if-no-files-found: error

Expand All @@ -252,6 +276,10 @@ jobs:
. $IDF_PATH/export.sh
export IDF_TARGET=${{matrix.esp-idf-target}}
export PATH=${PATH}:${HOME}/.cache/rebar3/bin
cp sdkconfig.defaults sdkconfig.defaults.backup
if [ "${{ matrix.jit }}" = "true" ]; then
echo "CONFIG_JIT_ENABLED=y" >> sdkconfig.defaults
fi
idf.py set-target ${{matrix.esp-idf-target}}
idf.py build

Expand All @@ -265,12 +293,13 @@ jobs:
. $IDF_PATH/export.sh
export PATH=/opt/qemu/bin:${PATH}
pytest --target=${{matrix.esp-idf-target}} --embedded-services=idf,qemu -s
cp sdkconfig.defaults.backup sdkconfig.defaults

- name: Upload ESP32 tests ELF artifact
# TODO: remove the following exclusion when ESP32P4 support is added to espressif/qemu
if: failure() && matrix.esp-idf-target != 'esp32p4'
uses: actions/upload-artifact@v4
with:
name: atomvm-esp32-test-${{ matrix.esp-idf-target }}-${{ matrix.idf-version }}.elf
name: atomvm-esp32-test-${{ matrix.esp-idf-target }}-${{ matrix.idf-version }}${{ matrix.jit && '-jit' || '' }}.elf
path: ./src/platforms/esp32/test/build/atomvm-esp32-test.elf
if-no-files-found: error
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `"USB_SERIAL_JTAG"` peripheral to the ESP32 `uart` module on chips with a built-in
USB-Serial-JTAG controller (C3/C5/C6/C61/H2/H21/H4/P4/S3)
- Added support for the `safe` option in `erlang:binary_to_term/2`
- Added xtensa JIT backend for esp32 platform

### Changed
- Updated network type db() to dbm() to reflect the actual representation of the type
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ if (NOT AVM_DISABLE_JIT AND NOT DEFINED AVM_JIT_TARGET_ARCH)
set(AVM_JIT_TARGET_ARCH "arm32")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv64$")
set(AVM_JIT_TARGET_ARCH "riscv64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^xtensa")
set(AVM_JIT_TARGET_ARCH "xtensa")
else()
message(FATAL_ERROR "JIT is not supported on ${CMAKE_SYSTEM_PROCESSOR}")
endif()
endif()

set(AVM_PRECOMPILED_TARGETS "x86_64;aarch64;arm32;armv6m;armv6m+float32;armv6m+thumb2;riscv32;riscv64;wasm32" CACHE STRING "Targets to precompile code to if AVM_DISABLE_JIT is OFF or AVM_ENABLE_PRECOMPILED is ON")
set(AVM_PRECOMPILED_TARGETS "x86_64;aarch64;arm32;armv6m;armv6m+thumb2;armv6m+thumb2+float32;riscv32;riscv64;wasm32;xtensa;xtensa+float32" CACHE STRING "Targets to precompile code to if AVM_DISABLE_JIT is OFF or AVM_ENABLE_PRECOMPILED is ON")

# DWARF is not supported on wasm32
if (NOT AVM_DISABLE_JIT_DWARF)
Expand Down
Loading
Loading