Skip to content

Conversation

@pxp9
Copy link
Contributor

@pxp9 pxp9 commented Dec 27, 2025

the purpose from this task is to make easy to test Elixir AtomVM with main branch code from the AtomVM repository for ESP32.

this task requires idf.py installed or docker for compiling the AtomVM from source.

feel free to comment any issue in the implementation as well.

Thank you for your attention.

Workflow with custom build

mix atomvm.esp32.build --atomvm-path ./_build/atomvm_source/AtomVM/ --use-docker --chip esp32s3
mix atomvm.esp32.install --image ./_build/atomvm_source/AtomVM/src/platforms/esp32/build/atomvm-esp32s3.img
image

Using ESP-IDF Docker container

image

Copy link
Contributor

@UncleGrumpy UncleGrumpy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very cool feature! One that has been on my todo list to add to the atomvm_rebar3_plugin for a while. I work much more in Erlang, so my Elixir is not that great, but I did spot a few problems, and have some suggestions on improving usability.

@UncleGrumpy
Copy link
Contributor

It might also be good to consider allowing a ESP-IDF docker image. I suspect many more Elixir developers will already have docker installed (or at least be more familiar with it than ESP-IDF), so it would be extra cool to pull in a docker image of ESP-IDF if they don't already have it installed.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 28, 2025

Hey @UncleGrumpy , when i try to build AtomVM , the build fails because we are using the the stat struct but the header <sys/stat.h> is missing, is there something i need to add in the args of cmake to build it correctly or is this a bug in AtomVM main branch build ?

[913/1054] Building C object esp-idf/avm_sys/CMakeFiles/__idf_avm_sys.dir/sys.c.obj
  FAILED: [code=1] esp-idf/avm_sys/CMakeFiles/__idf_avm_sys.dir/sys.c.obj

  /home/pxp9/Programming/try_nerves/atom_vm_firmware/esp32_s3/_build/atomvm_source/AtomVM/src/platforms/esp32/components/avm_sys/sys.c: In function 'sys_open_avm_from_file':

  /home/pxp9/Programming/try_nerves/atom_vm_firmware/esp32_s3/_build/atomvm_source/AtomVM/src/platforms/esp32/components/avm_sys/sys.c:413:21: error: storage size of 'file_stats' isn't known
    413 |         struct stat file_stats;
        |                     ^~~~~~~~~~

  /home/pxp9/Programming/try_nerves/atom_vm_firmware/esp32_s3/_build/atomvm_source/AtomVM/src/platforms/esp32/components/avm_sys/sys.c:414:22: error: implicit declaration of function 'stat' [-Wimplicit-function-declaration]
    414 |         if (UNLIKELY(stat(path, &file_stats) < 0)) {
        |                      ^~~~

  /home/pxp9/Programming/try_nerves/atom_vm_firmware/esp32_s3/_build/atomvm_source/AtomVM/src/platforms/esp32/components/avm_sys/sys.c:413:21: warning: unused variable 'file_stats' [-Wunused-variable]
    413 |         struct stat file_stats;
        |                     ^~~~~~~~~~

  Build stopped:
  ninja: build stopped: subcommand failed.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 28, 2025

@pxp9 pxp9 requested review from UncleGrumpy December 28, 2025 15:47
@UncleGrumpy
Copy link
Contributor

UncleGrumpy commented Dec 28, 2025

Hey @UncleGrumpy , when i try to build AtomVM , the build fails because we are using the the stat struct but the header <sys/stat.h> is missing, is there something i need to add in the args of cmake to build it correctly or is this a bug in AtomVM main branch build ?

This is not something I have seen before, and I have been working almost exclusively with main branch for at least the last few months.

Was this testing a docker build, or did this happen with an installed ESP-IDF? It has been a few ESP-IDF releases since I last used an esp-idf docker image, although we do use them in the AtomVM CI, so I don’t think that would be the problem.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 28, 2025

@UncleGrumpy , this issue from the missing header happened with both toolchains. Esp idf installed and docker

@UncleGrumpy
Copy link
Contributor

UncleGrumpy commented Dec 28, 2025

Interesting. Which ESP-IDF version? I think I am a point release behind locally (still using 5.5.1). I will try updating my toolchain this evening and see if I can reproduce the problem, I believe the AtomVM CI may also need to be bumped to 5.5.2, I will look into that too. This may be a new issue that you were the first to discover. I think you should open an issue in the AtomVM repo, and be sure to include Host OS, and ESP-IDF version in the report, along with the error and any other details that might be relevant.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 28, 2025

I tried with the last ESP version 6.X and then I tried with 5.4.1 which afaik is the last supported by AtomVM but not sure. It happens the same with both versions.

@UncleGrumpy
Copy link
Contributor

I tried with the last ESP version 6.X and then I tried with 5.4.1 which afaik is the last supported by AtomVM but not sure.

I have not tried 6.0 yet, but I believe a PR was recently merged to allow ESP-IDF 6.0 builds. ESP-IDF 5.5.1 is definitely working for main branch, we might not have updated the main branch docs to reflect this, that is something we will need to make sure is up to date before a 0.7.0 release of AtomVM. Since you are hitting this error with ESP-IDF 5.4.1 and 6.0 then I don’t think just switching to 5.5.x will be any different.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 29, 2025

Okay @UncleGrumpy , today I will post an issue in AtomVM with this error and how to reproduce it.

Meanwhile could you review the code and see if everything is fine ?

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 29, 2025

Hey @UncleGrumpy , I tried 4 times to compile the AtomVM cloning each time just in case and it seems to be fixed.

this command but with each version

mix atomvm.esp32.build --use-docker --chip esp32s3 --idf-version latest
  1. I tried with v5.4.1 ESP-IDF container and it worked
  2. I tried with v5.5.1 ESP-IDF container and it worked
  3. I tried with latest (v6.1) ESP-IDF container and it did not work
  4. I tried with (the tag release-v6.0) ESP-IDF container and it did not work

it seems i had something weird in the cache or it has been fixed.

by default --use-docker uses the version v5.4.1

@UncleGrumpy
Copy link
Contributor

Hey @UncleGrumpy , I tried 4 times to compile the AtomVM cloning each time just in case and it seems to be fixed.

this command but with each version

mix atomvm.esp32.build --use-docker --chip esp32s3 --idf-version latest
  1. I tried with v5.4.1 ESP-IDF container and it worked
  2. I tried with v5.5.1 ESP-IDF container and it worked
  3. I tried with latest (v6.1) ESP-IDF container and it did not work
  4. I tried with (the tag release-v6.0) ESP-IDF container and it did not work

it seems i had something weird in the cache or it has been fixed.

by default --use-docker uses the version v5.4.1

That is great! I would not necessarily expect any of the 6.x IDF versions to work at the moment. I think AtomVM itself will need some updating. If it works with stable releases from 5.1 (or 5.2) to 5.5 that is all that would be expected at the moment. The AtomVM main branch uses 5.5.x for release builds so that should probably be the default here too. I believe 5.5.2 is the latest, we still need to bump that in the AtomVM CI, which I believe is still using 5.5.1. There shouldn’t be any breakage between these versions since the point releases are usually just bug fixes.

@UncleGrumpy
Copy link
Contributor

Meanwhile could you review the code and see if everything is fine ?

I will take another look this evening, but I think you will get some much more useful feedback when some of devs that work more in Elixir have a chance to review this, especially @bettio and @petermm.

@pxp9 pxp9 requested a review from petermm December 29, 2025 22:40
selected_device <- EsptoolHelper.select_device(),
:ok <- confirm_erase_and_flash(selected_device, image_path),
true <-
EsptoolHelper.erase_flash([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think we will need a --no_erase (or better name?) option both for release and custom_image, but we can always do that in a follow up PR..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one erases as well, it has the same behavior as the release, what i wonder is why if i try the full workflow in a real board with a simple project it does not work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think there is a bug on later elixir like 1.19 - where we need to add @requirements ["app.config"] eg:

  use Mix.Task
  @requirements ["app.config"]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird I am using Elixir 1.18.4 and Erlang 27

end
end

defp build_generic_unix(atomvm_path) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should build in docker if that option is set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is fine bc this is built with generic c compiler toolchain, since we dont need the idf toolchain for this i think is fine to keep it like this even if the docker is specified.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, building fails since macos homebrew now has mbedtls@4 default, and one needs to build atomvm libs with:

export MBEDTLS_PREFIX="/opt/homebrew/opt/mbedtls@3"
cmake .. ${MBEDTLS_PREFIX:+-DCMAKE_PREFIX_PATH="$MBEDTLS_PREFIX"} -G Ninja

So as a user I expected it to use docker and "just work", so a bit confusing..

don't know if elixir:1.19-otp-28 https://hub.docker.com/layers/library/elixir/1.19.4-otp-28/ family of docker images has enough to build atomvm libs?

either way PR is huge DX improvement

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one reason as well is that cmake only builds the elixir stuff if it is detected in the env and the container does not have elixir installed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't know if elixir:1.19-otp-28 https://hub.docker.com/layers/library/elixir/1.19.4-otp-28/ family of docker images has enough to build atomvm libs?

ah okay i understood, i believe in this image from elixir is missing some libs required for building atomVM

Copy link
Contributor Author

@pxp9 pxp9 Dec 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does not have cmake neither make, an alternative would be to make a custom docker image with all the tooling but this would require to do it in AtomVM repo.

Copy link
Contributor

@UncleGrumpy UncleGrumpy Dec 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a better solution for the time being would be to add a —mbedtls_dir option, and if that is not given use MBEDTLS_PREFIX if that is exported to the environment.

I think it should be reasonable to expect cmake, either ninja or make, OTP, Elixir and either docker or ESP-IDF to already be installed on the build host. I would say to simplify the options look for and use ninja first, and if that isn’t found fall back to make. We will just need to be sure this is included in the documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 30, 2025

@UncleGrumpy and @petermm , could you try to build it with docker ? i believe there is something weird but i am not sure why.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 30, 2025

i believe i broke something in the build when i have changed to the elixir boot.

I (31) boot: ESP-IDF v5.4.1 2nd stage bootloader
I (31) boot: compile time Dec 30 2025 10:32:36
I (31) boot: Multicore bootloader
I (31) boot: chip revision: v0.2
I (34) boot: efuse block revision: v1.3
I (38) boot.esp32s3: Boot SPI Speed : 80MHz
I (42) boot.esp32s3: SPI Mode       : DIO
I (45) boot.esp32s3: SPI Flash Size : 4MB
I (49) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (56) boot: ## Label            Usage          Type ST Offset   Length
I (63) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (69) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (76) boot:  2 factory          factory app      00 00 00010000 001c0000
I (82) boot:  3 boot.avm         RF data          01 01 001d0000 00040000
I (89) boot:  4 main.avm         RF data          01 01 00210000 00100000
I (95) boot: End of partition table
I (98) esp_image: segment 0: paddr=00010020 vaddr=3c140020 size=36980h (223616) map
E (145) esp_image: invalid segment length 0x69742064
E (145) boot: Factory app partition is not bootable
E (146) boot: No bootable app partitions in the partition table
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xa (SPI_FAST_FLASH_BOOT)
Saved PC:0x403cceb5
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2810,len:0x15a0
load:0x403c8700,len:0x4
load:0x403c8704,len:0xd20
load:0x403cb700,len:0x2f00
entry 0x403c8928

output of boot in my esp-s3

EDIT: I managed to fix the build in the esp-idf natively but docker build is still buggy.

EDIT 2: I am trying to debug why Docker esp-idf container produces a different image than the Esp-idf installed natively.

@UncleGrumpy
Copy link
Contributor

E (145) boot: Factory app partition is not bootable

This seems more like it was flashed to the wrong offset than a library problem. It isn’t finding the partition with AtomVM, so it hasn’t made it as far as trying to load the library partition.

@UncleGrumpy
Copy link
Contributor

Actually the offset must have been correct, it did find the partition table, so the problem is with the compiled VM.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 30, 2025

Actually the offset must have been correct, it did find the partition table, so the problem is with the compiled VM.

yup the result of the docker build is like this, but the native AtomVM build it is working. i believe it is bug with the docker flow in the tool, but it is hard to find.

@UncleGrumpy
Copy link
Contributor

yup the result of the docker build is like this, but the native AtomVM build it is working. i believe it is bug with the docker flow in the tool, but it is hard to find.

So for debugging in the docker container you can start a shell (docker run sh) and then use the commands the same as you would for a local install of ESP-IDF.

My last 4 days have been brutal at work, but I will try building with docker this evening if I can stay awake long enough ;-)

@UncleGrumpy
Copy link
Contributor

UncleGrumpy commented Dec 31, 2025

yup the result of the docker build is like this, but the native AtomVM build it is working. i believe it is bug with the docker flow in the tool, but it is hard to find.

I discovered the problem with the docker container. I am working on a fix for the AtomVM repo that will change the configuration of the mkimage.sh and mkimage.config. The problem is that the paths to the binary files are configured by cmake in the container and then need to be executed in the host environment to use OTP to execute the escript. I can change the mkimage.sh script to find the esp32/build dir at runtime (rather than have it set by cmake) and pass that directly to the escript to use as the base for finding the partition binaries.

We should fix this there so users, other tools, and IDEs can use docker builds.

@pxp9
Copy link
Contributor Author

pxp9 commented Dec 31, 2025

Amazing I had a mini fix which was patching the paths for the container build but it seems that is not working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants