How to compile Rust and LLVM for ESP32 on a Raspberry Pi (aarch64)

ESP32 is a series of microcontrollers that has the particularity to have both integrated Bluetooth and Wi-Fi. It makes it the perfect microcontroller when you need low-power, networked, and smart hardware that doesn't require an OS.

I had to run compile and run Rust code on an ESP32. Unfortunately, they don't run a traditional architecture but the Xtensa instruction set that is currently not officially supported by the Rust compiler.

The esp-rs GitHub organization contains the fork of the Rust compiler to support the Xtensa architecture.

Unfortunately, it seems that the src/llvm-project submodule is out of date and does not support the aarch64 (arm64) architecture, as when trying to follow the instructions I encountered the following error:

cargo:warning=cc: error: esp32/rust/src/llvm-project/compiler-rt/lib/builtins/aarch64/lse.S: No such file or directory
cargo:warning=cc: fatal error: no input files
cargo:warning=compilation terminated.
exit status: 1

Which, according to this issue, is due to an outdated LLVM version.

Here is how I fixed the build and successfully built Rust and LLVM to compile Rust binaries for ESP32:

The prerequisites

You will need at least 20GB of free space and a Rust toolchain: https://rustup.rs.

Building Rust

# starting from $HOME
$ mkdir esp32
$ cd esp32
$ git clone https://github.com/esp-rs/rust.git
$ cd rust

Here is the trick: you need to update the src/llvm-project submodule:

$ git submodule update --init --recursive --remote src/llvm-project

Then, you can finally build Rust (warning: it will take a lot of time, so I recommend to run it for the night):

$ ./configure --experimental-targets=Xtensa
$ python3 x.py dist --stage 2
# still in esp32/rust
$ rustup toolchain link esp `pwd`/build/aarch64-unknown-linux-gnu/stage2

Building LLVM

Still in your recently cloned rust folder (warning: it will take a lot of time, so I recommend to run it for the night):

$ cd src/llvm-project
$ mkdir build
$ cd build
$ cmake -G Ninja -DLLVM_ENABLE_PROJECTS='clang' -DCMAKE_BUILD_TYPE=Release ../llvm
$ cmake --build .
$ export PATH="$HOME/esp32/rust/src/llvm-project/build/bin:$PATH"

Your Rust toolcahin for ESP32 is now set up!

You can check it by running:

$ rustc --print target-list | grep xtensa

and:

$ which clang

Which should return your newly built clang.

See you tomorrow for a post on how to build and flash a Rust program to an ESP32.

1 email / week to learn how to (ab)use technology for fun & profit: Programming, Hacking & Entrepreneurship.
I hate spam even more than you do. I'll never share your email, and you can unsubscribe at any time.

Tags: programming, rust, tutorial, raspberry-pi, esp32

Want to learn Rust, Cryptography and Security? Get my book Black Hat Rust!