before removing rustlib
This commit is contained in:
parent
feb3802cc7
commit
b4bba1e5cc
|
|
@ -1,3 +1,3 @@
|
|||
[unstable]
|
||||
build-std = ["std", "panic_abort"]
|
||||
build-std-features = ["panic_immediate_abort"]
|
||||
# build-std-features = ["panic_immediate_abort"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "components/drone_controller"]
|
||||
path = components/drone_controller
|
||||
url = ssh://git@forgejo.galard.uk:222/Cansat/drone_controller.git
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
idf_component_register(SRCS "clib.c"
|
||||
INCLUDE_DIRS "include")
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
# clib
|
||||
|
||||
This component exposes functions and data defined in C that will accessed from Rust.
|
||||
|
||||
The Rust build will automatically generate bindings to these functions by processing the exported header files with bindgen.
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/* Hello World Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#include "CApi.h"
|
||||
|
||||
bool validate_param_in_c(int param, int value)
|
||||
{
|
||||
printf("C validated param #%d = %d\n", param, value);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
/*
|
||||
* C functions exposed to Rust.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern bool validate_param_in_c(int param, int value);
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit ede403613d96b3233e2c8f8be04dc4cb9efd7569
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
set(RUST_DEPS "clib")
|
||||
|
||||
idf_component_register(
|
||||
SRCS "placeholder.c"
|
||||
|
|
|
|||
|
|
@ -2,14 +2,10 @@ use std::env;
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
|
||||
let cargo_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let target_dir = PathBuf::from(env::var("CARGO_BUILD_TARGET_DIR").unwrap());
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
|
||||
run_cbindgen(&cargo_dir, &target_dir);
|
||||
run_bindgen(&target, &out_dir);
|
||||
}
|
||||
|
||||
fn run_cbindgen(cargo_dir: &Path, target_dir: &Path) {
|
||||
|
|
@ -24,34 +20,3 @@ fn run_cbindgen(cargo_dir: &Path, target_dir: &Path) {
|
|||
|
||||
println!("cargo:rerun-if-changed={}", out.display());
|
||||
}
|
||||
|
||||
fn run_bindgen(target: &str, out_dir: &Path) {
|
||||
let header = "../clib/include/CApi.h";
|
||||
let out = out_dir.join("bindings.rs");
|
||||
|
||||
let mut builder = bindgen::Builder::default();
|
||||
builder = builder.header(header);
|
||||
match target {
|
||||
"riscv32imc-esp-espidf" => {
|
||||
builder = builder.clang_arg("--target=riscv32");
|
||||
builder = builder.use_core();
|
||||
builder = builder.ctypes_prefix("crate::ffi");
|
||||
}
|
||||
"xtensa-esp32-espidf" => {
|
||||
// Make sure that LLVM_CONFIG_PATH has been set to point to the
|
||||
// Xtensa build of llvm-config.
|
||||
builder = builder.clang_arg("--target=xtensa-esp32-elf");
|
||||
}
|
||||
_ => {
|
||||
panic!("Unexpect target archtitecture: {}", &target);
|
||||
}
|
||||
}
|
||||
|
||||
let bindings = builder.generate().expect("Couldn't generate bindings!");
|
||||
bindings
|
||||
.write_to_file(&out)
|
||||
.expect("Couldn't save bindings!");
|
||||
|
||||
println!("cargo:rerun-if-changed={}", header);
|
||||
println!("cargo:rerun-if-changed={}", out.display());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#![cfg_attr(not(version("1.59")), feature(asm))]
|
||||
#![cfg_attr(
|
||||
all(version("1.58"), target_arch = "xtensa"),
|
||||
|
|
@ -11,41 +10,13 @@ use core::arch::asm;
|
|||
#[cfg(not(feature = "std"))]
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
|
||||
/// Create aliases for FFI types for esp32c3, which doesn't have std.
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod ffi {
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
pub type c_char = u8;
|
||||
pub type c_int = i32;
|
||||
}
|
||||
|
||||
pub mod sys {
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn add_in_rust(x: i32, y: i32) -> i32 {
|
||||
unsafe {
|
||||
sys::validate_param_in_c(0, x);
|
||||
sys::validate_param_in_c(1, y);
|
||||
}
|
||||
x + y
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn add_in_rust_inline_asm(mut x: i32, y: i32) -> i32 {
|
||||
unsafe {
|
||||
sys::validate_param_in_c(0, x);
|
||||
sys::validate_param_in_c(1, y);
|
||||
}
|
||||
unsafe {
|
||||
// more detail available: https://doc.rust-lang.org/beta/unstable-book/library-features/asm.html
|
||||
asm!("add {0}, {0}, {1}", inout(reg) x, in(reg) y);
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
# Deprecated
|
||||
|
||||
Installation instructions moved to: [esp-rs/rust-build](https://github.com/esp-rs/rust-build)
|
||||
|
||||
# Rust on Xtensa Installation for macOS M1
|
||||
|
||||
Following instructions are specific for ESP32 and ESP32-S series based on Xtensa architecture.
|
||||
|
||||
Instructions for ESP-C series based on RISC-V architecture are described in document for [ESP32-C3](../README.md#esp32-c3).
|
||||
|
||||
Tested OS: macOS Big Sur M1
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- rustup - https://rustup.rs/
|
||||
|
||||
## Installation commands
|
||||
|
||||
```sh
|
||||
rustup toolchain install nightly
|
||||
|
||||
VERSION="1.54.0-dev"
|
||||
ARCH="aarch64-apple-darwin"
|
||||
RUST_DIST="rust-${VERSION}-${ARCH}"
|
||||
RUST_SRC_DIST="rust-src-${VERSION}"
|
||||
TOOLCHAIN_DESTINATION_DIR="~/.rustup/toolchains/esp"
|
||||
|
||||
mkdir -p ${TOOLCHAIN_DESTINATION_DIR}
|
||||
|
||||
curl -O "https://dl.espressif.com/dl/idf-rust/dist/${ARCH}/${RUST_DIST}.tar.xz"
|
||||
tar xvf ${RUST_DIST}.tar.xz
|
||||
./${RUST_DIST}/install.sh --destdir=${TOOLCHAIN_DESTINATION_DIR} --prefix="" --without=rust-docs
|
||||
|
||||
curl -O "https://dl.espressif.com/dl/idf-rust/dist/noarch/${RUST_SRC_DIST}.tar.xz"
|
||||
tar xvf ${RUST_SRC_DIST}.tar.xz
|
||||
./${RUST_SRC_DIST}/install.sh --destdir=${TOOLCHAIN_DESTINATION_DIR} --prefix="" --without=rust-docs
|
||||
|
||||
rustup default esp
|
||||
|
||||
curl -O "https://dl.espressif.com/dl/idf-rust/dist/${ARCH}/xtensa-esp32-elf-llvm11_0_0-aarch64-apple-darwin.tar.xz"
|
||||
tar xf xtensa-esp32-elf-llvm11_0_0-aarch64-apple-darwin.tar.xz
|
||||
export PATH="`pwd`/xtensa-esp32-elf-clang/bin/:$PATH"
|
||||
|
||||
curl -LO "https://github.com/espressif/rust-esp32-example/archive/refs/heads/main.zip"
|
||||
unzip main.zip
|
||||
cd rust-esp32-example-main
|
||||
```
|
||||
|
||||
## Select architecture for the build
|
||||
|
||||
For the ESP32 - default (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32
|
||||
```
|
||||
|
||||
For the ESP32-S2 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s2
|
||||
```
|
||||
|
||||
For the ESP32-S3 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s3
|
||||
```
|
||||
|
||||
## Build and flash
|
||||
|
||||
```sh
|
||||
idf.py build flash
|
||||
```
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
# Deprecated
|
||||
|
||||
Installation instructions moved to: [esp-rs/rust-build](https://github.com/esp-rs/rust-build)
|
||||
|
||||
# Rust on Xtensa Installation for macOS x64
|
||||
|
||||
Following instructions are specific for ESP32 and ESP32-S series based on Xtensa architecture.
|
||||
|
||||
Instructions for ESP-C series based on RISC-V architecture are described in document for [ESP32-C3](../README.md#esp32-c3).
|
||||
|
||||
Tested OS: macOS Big Sur x64
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- rustup - installed with nightly toolchain - https://rustup.rs/
|
||||
|
||||
## Installation commands
|
||||
|
||||
```sh
|
||||
rustup toolchain install nightly
|
||||
|
||||
VERSION="1.54.0-dev"
|
||||
ARCH="x86_64-apple-darwin"
|
||||
RUST_DIST="rust-${VERSION}-${ARCH}"
|
||||
RUST_SRC_DIST="rust-src-${VERSION}"
|
||||
TOOLCHAIN_DESTINATION_DIR="~/.rustup/toolchains/esp"
|
||||
|
||||
mkdir -p ${TOOLCHAIN_DESTINATION_DIR}
|
||||
|
||||
curl -O "https://dl.espressif.com/dl/idf-rust/dist/${ARCH}/${RUST_DIST}.tar.xz"
|
||||
tar xvf ${RUST_DIST}.tar.xz
|
||||
./${RUST_DIST}/install.sh --destdir=${TOOLCHAIN_DESTINATION_DIR} --prefix="" --without=rust-docs
|
||||
|
||||
curl -O "https://dl.espressif.com/dl/idf-rust/dist/noarch/${RUST_SRC_DIST}.tar.xz"
|
||||
tar xvf ${RUST_SRC_DIST}.tar.xz
|
||||
./${RUST_SRC_DIST}/install.sh --destdir=${TOOLCHAIN_DESTINATION_DIR} --prefix="" --without=rust-docs
|
||||
|
||||
rustup default esp
|
||||
|
||||
curl -O "https://dl.espressif.com/dl/idf-rust/dist/${ARCH}/xtensa-esp32-elf-llvm11_0_0-x86_64-apple-darwin.tar.xz"
|
||||
tar xf xtensa-esp32-elf-llvm11_0_0-x86_64-apple-darwin.tar.xz
|
||||
export PATH="`pwd`/xtensa-esp32-elf-clang/bin/:$PATH"
|
||||
|
||||
curl -LO "https://github.com/espressif/rust-esp32-example/archive/refs/heads/main.zip"
|
||||
unzip main.zip
|
||||
cd rust-esp32-example-main
|
||||
```
|
||||
|
||||
## Select architecture for the build
|
||||
|
||||
For the ESP32 - default (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32
|
||||
```
|
||||
|
||||
For the ESP32-S2 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s2
|
||||
```
|
||||
|
||||
For the ESP32-S3 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s3
|
||||
```
|
||||
|
||||
## Build and flash
|
||||
|
||||
```sh
|
||||
idf.py build flash
|
||||
```
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
# Deprecated
|
||||
|
||||
Installation instructions moved to: [esp-rs/rust-build](https://github.com/esp-rs/rust-build)
|
||||
|
||||
# Rust on Xtensa Installation for Windows x64
|
||||
|
||||
Following instructions are specific for ESP32 and ESP32-S series based on Xtensa architecture.
|
||||
|
||||
Instructions for ESP-C series based on RISC-V architecture are described in document for [ESP32-C3](../README.md#esp32-c3).
|
||||
|
||||
Tested OS: Windows 10 x64
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Visual Studio - installed with option Desktop development with C++
|
||||
- rustup - installed with nightly toolchain - https://rustup.rs/
|
||||
- Chocolatey - https://chocolatey.org/
|
||||
|
||||
## Installation commands for PowerShell
|
||||
|
||||
```sh
|
||||
choco install 7zip
|
||||
|
||||
rustup toolchain install nightly
|
||||
|
||||
$Version="1.54.0-dev"
|
||||
$Arch="x86_64-pc-windows-msvc"
|
||||
$RustDist="rust-${VERSION}-${ARCH}"
|
||||
|
||||
mkdir -p ~\.rustup\toolchains\ -ErrorAction SilentlyContinue
|
||||
pushd ~\.rustup\toolchains\
|
||||
|
||||
Invoke-WebRequest "https://dl.espressif.com/dl/idf-rust/dist/${Arch}/${RustDist}.zip" -OutFile "${RustDist}.zip"
|
||||
7z x .\${RustDist}.zip
|
||||
popd
|
||||
|
||||
rustup default esp
|
||||
|
||||
Invoke-WebRequest https://github.com/espressif/llvm-project/releases/download/esp-12.0.1-20210823/xtensa-esp32-elf-llvm12_0_1-esp-12.0.1-20210823-win64.zip -OutFile xtensa-esp32-elf-llvm12_0_1-esp-12.0.1-20210823-win64.zip
|
||||
7z x xtensa-esp32-elf-llvm12_0_1-esp-12.0.1-20210823-win64.zip
|
||||
$env:LIBCLANG_PATH=Join-Path -Path (Get-Location) -ChildPath xtensa-esp32-elf-clang\bin
|
||||
$env:PATH+=";$env:LIBCLANG_PATH"
|
||||
|
||||
Invoke-WebRequest https://github.com/espressif/rust-esp32-example/archive/refs/heads/main.zip -OutFile rust-esp32-example.zip
|
||||
7z x rust-esp32-example.zip
|
||||
cd rust-esp32-example-main
|
||||
```
|
||||
|
||||
## Select architecture for the build
|
||||
|
||||
For the ESP32 - default (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32
|
||||
```
|
||||
|
||||
For the ESP32-S2 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s2
|
||||
```
|
||||
|
||||
For the ESP32-S3 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s3
|
||||
```
|
||||
|
||||
## Build and flash
|
||||
|
||||
```sh
|
||||
idf.py build flash
|
||||
```
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
# Deprecated
|
||||
|
||||
Installation instructions moved to: [esp-rs/rust-build](https://github.com/esp-rs/rust-build)
|
||||
|
||||
# Rust on Xtensa Installation for Linux x64
|
||||
|
||||
Following instructions are specific for ESP32 and ESP32-S series based on Xtensa architecture.
|
||||
|
||||
Instructions for ESP-C series based on RISC-V architecture are described in document for [ESP32-C3](../README.md#esp32-c3).
|
||||
|
||||
Tested OS: Ubuntu 18 x64, Ubuntu 20 x64, Mint 20 x64, OpenSUSE Thumbleweed
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- rustup - installed with nightly toolchain - https://rustup.rs/
|
||||
|
||||
## Installation commands
|
||||
|
||||
```sh
|
||||
sudo apt install gcc wget xz-utils
|
||||
|
||||
rustup toolchain install nightly
|
||||
|
||||
VERSION="1.55.0-dev"
|
||||
ARCH="x86_64-unknown-linux-gnu"
|
||||
RUST_DIST="rust-${VERSION}-${ARCH}"
|
||||
RUST_SRC_DIST="rust-src-${VERSION}"
|
||||
TOOLCHAIN_DESTINATION_DIR="~/.rustup/toolchains/esp"
|
||||
|
||||
mkdir -p ${TOOLCHAIN_DESTINATION_DIR}
|
||||
|
||||
wget https://github.com/esp-rs/rust-build/releases/download/v${VERSION}/${RUST_DIST}.tar.xz
|
||||
tar xvf ${RUST_DIST}.tar.xz
|
||||
./${RUST_DIST}/install.sh --destdir=${TOOLCHAIN_DESTINATION_DIR} --prefix="" --without=rust-docs
|
||||
|
||||
wget https://github.com/esp-rs/rust-build/releases/download/v${VERSION}/${RUST_SRC_DIST}.tar.xz
|
||||
tar xvf ${RUST_SRC_DIST}.tar.xz
|
||||
./${RUST_SRC_DIST}/install.sh --destdir=${TOOLCHAIN_DESTINATION_DIR} --prefix="" --without=rust-docs
|
||||
|
||||
rustup default esp
|
||||
|
||||
wget https://github.com/espressif/llvm-project/releases/download/esp-12.0.1-20210823/xtensa-esp32-elf-llvm12_0_1-esp-12.0.1-20210823-linux-amd64.tar.xz
|
||||
tar xf xtensa-esp32-elf-llvm12_0_1-esp-12.0.1-20210823-linux-amd64.tar.xz
|
||||
export PATH="`pwd`/xtensa-esp32-elf-clang/bin/:$PATH"
|
||||
|
||||
wget --continue https://github.com/espressif/rust-esp32-example/archive/refs/heads/main.zip
|
||||
unzip main.zip
|
||||
cd rust-esp32-example-main
|
||||
```
|
||||
|
||||
## Select architecture for the build
|
||||
|
||||
For the ESP32 - default (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32
|
||||
```
|
||||
|
||||
For the ESP32-S2 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s2
|
||||
```
|
||||
|
||||
For the ESP32-S3 (Xtensa architecture):
|
||||
|
||||
```sh
|
||||
idf.py set-target esp32s3
|
||||
```
|
||||
|
||||
## Build and flash
|
||||
|
||||
```sh
|
||||
idf.py build flash
|
||||
```
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
# Deprecated
|
||||
|
||||
Installation instructions moved to: [esp-rs/rust-build](https://github.com/esp-rs/rust-build)
|
||||
|
||||
# Rust on ESP32 and ESP32-S series (Xtensa)
|
||||
|
||||
Following instructions are specific for ESP32 and ESP32-S series based on Xtensa architecture.
|
||||
|
||||
Instructions for ESP-C series based on RISC-V architecture are described in document for [ESP32-C3](../README.md#esp32-c3).
|
||||
|
||||
## Quick start
|
||||
|
||||
The installation process of ready to use custom build of Rust and LLVM is described here:
|
||||
|
||||
* [Linux Ubuntu 18, Ubuntu 20 x64, Mint 20 x64, OpenSUSE Thumbleweed x64](rust-on-xtensa-installation-x86_64-unknown-linux-gnu.md)
|
||||
* [macOS Big Sur x64](rust-on-xtensa-installation-x86_64-apple-darwin.md)
|
||||
* [macOS Big Sur arm64](rust-on-xtensa-installation-aarch64-apple-darwin.md)
|
||||
* [Windows 10 x64](rust-on-xtensa-installation-x86_64-pc-windows-msvc.md)
|
||||
* Not supported: Linux arm64 - missing support in ESP-IDF - https://github.com/espressif/esp-idf/issues/6475
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Can't find crate for `std`
|
||||
|
||||
Make sure to install Rust toolchain nightly:
|
||||
|
||||
`rustup toolchain install nightly`
|
||||
|
||||
Missing nightly toolchain might result in following error:
|
||||
|
||||
```
|
||||
error[E0463]: can't find crate for `std`
|
||||
|
|
||||
= note: the `xtensa-esp32-none-elf` target may not be installed
|
||||
```
|
||||
|
||||
### Error: use of unstable library feature 'restricted_std'
|
||||
|
||||
Error message:
|
||||
|
||||
```
|
||||
Compiling rustlib v0.1.0 (rust-esp32-example-main/components/rustlib)
|
||||
error[E0658]: use of unstable library feature 'restricted_std'
|
||||
|
|
||||
= help: add `#![feature(restricted_std)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
error: could not compile `rustlib`
|
||||
```
|
||||
|
||||
Solution:
|
||||
|
||||
Change the target to `xtensa-esp32-espidf`.
|
||||
|
||||
### Build fails with panic at `libclang error`
|
||||
|
||||
If you see the following error:
|
||||
|
||||
```
|
||||
error: failed to run custom build command for `rustlib v0.1.0 (/home/brian/src/esp32-rust/rust-esp32-example/components/rustlib)`
|
||||
|
||||
Caused by:
|
||||
process didn't exit successfully: `/home/user/projects/rust-esp32-example/build/esp-idf/rustlib/target/release/build/rustlib-435225cb26b45082/build-script-build` (exit status: 101)
|
||||
--- stdout
|
||||
cargo:rerun-if-changed=/home/user/projects/rust-esp32-example/build/esp-idf/rustlib/target/RustApi.h
|
||||
|
||||
--- stderr
|
||||
thread 'main' panicked at 'libclang error; possible causes include:
|
||||
- Invalid flag syntax
|
||||
- Unrecognized flags
|
||||
- Invalid flag arguments
|
||||
- File I/O errors
|
||||
- Host vs. target architecture mismatch
|
||||
[...]
|
||||
```
|
||||
|
||||
This likely means that the build script is finding the wrong `libclang.so` (or `libclang.dylib` on macOS) file (possibly from your system's global copy of clang). To teach the build where the correct copy of libclang is, set in your environment:
|
||||
|
||||
```
|
||||
export LIBCLANG_PATH=/path/to/xtensa-esp32-elf-clang/lib/libclang.so.12
|
||||
```
|
||||
|
||||
Replace the path above with the correct path on your system. Builds of LLVM project are available at [espressif/llvm-project](https://github.com/espressif/llvm-project/releases)
|
||||
|
||||
For more details about LLVM binary artifact read Quick start section.
|
||||
|
||||
## Building from scratch
|
||||
|
||||
Following text describes the build process when building LLVM and Rust from scratch.
|
||||
|
||||
## Using Rust for ESP32 Development
|
||||
|
||||
Given the popularity of the ESP32 chip, there has been an interest in developing applications for it using the Rust programming language. The ESP32 has traditionally used the Xtensa instruction set, which is not officially supported by Rust.
|
||||
|
||||
A new version of the ESP32, the ESP32-C3, has recently been released. The new C3 variant is based on a RISC-V architecture. RISC-V is a supported architecture for LLVM and Rust. This document, however, will concern itself with the more popular and, at the time of writing, more powerful Xtensa-based systems.
|
||||
|
||||
## Build LLVM for Xtensa
|
||||
|
||||
Although the Xtensa instruction set is not supported by the LLVM project, Espressif has continued to maintain a fork. Unfortunately, these changes have not been migrated upstream into the main project. This would be a prerequisite before official support in Rust is possible.
|
||||
|
||||
The fork is hosted at [espressif/llvm-project](https://github.com/espressif/llvm-project)
|
||||
|
||||
The Rust for for Xtensa fork (see below) includes the LLVM repo as a submodule, so it is not necessary to work with this repository directly. However, it uses an older version of the code. To use the most up to date, we can build the toolchain separately from the main repository.
|
||||
|
||||
Note, however, that while clang will successfully compile code, the toolchain is not able to link final executables for either the host or target systems.
|
||||
|
||||
```
|
||||
% git clone https://github.com/espressif/llvm-project.git
|
||||
% cd llvm-project
|
||||
% mkdir build
|
||||
% cd build
|
||||
% cmake ../llvm -G "Ninja" -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="Xtensa" -DLLVM_ENABLE_PROJECTS="clang" -DCMAKE_INSTALL_PREFIX=/usr/local/xtensa/llvm -DCMAKE_BUILD_TYPE=Release
|
||||
% ninja
|
||||
% sudo ninja install
|
||||
```
|
||||
|
||||
The Xtensa target support can be verified by printing the supported target architectures.
|
||||
|
||||
```
|
||||
% /usr/local/xtensa/llvm/bin/llc --version
|
||||
LLVM (http://llvm.org/):
|
||||
LLVM version 12.0.1
|
||||
Optimized build.
|
||||
Default target: x86_64-apple-darwin20.3.0
|
||||
Host CPU: cascadelake
|
||||
|
||||
Registered Targets:
|
||||
x86 - 32-bit X86: Pentium-Pro and above
|
||||
x86-64 - 64-bit X86: EM64T and AMD64
|
||||
xtensa - Xtensa 32
|
||||
```
|
||||
|
||||
The available CPUs and features for the architecture can also be queried.
|
||||
|
||||
```
|
||||
% /usr/local/xtensa/llvm/bin/llc -march=xtensa -mattr=help
|
||||
Available CPUs for this target:
|
||||
|
||||
esp32 - Select the esp32 processor.
|
||||
esp32-s2 - Select the esp32-s2 processor.
|
||||
esp8266 - Select the esp8266 processor.
|
||||
generic - Select the generic processor.
|
||||
|
||||
Available features for this target:
|
||||
|
||||
atomctl - Enable Xtensa ATOMCTL option.
|
||||
atomctl - Enable Xtensa MEMCTL option.
|
||||
bool - Enable Xtensa Boolean extension.
|
||||
coprocessor - Enable Xtensa Coprocessor option.
|
||||
debug - Enable Xtensa Debug option.
|
||||
density - Enable Density instructions.
|
||||
dfpaccel - Enable Xtensa Double Precision FP acceleration.
|
||||
div32 - Enable Xtensa Div32 option.
|
||||
exception - Enable Xtensa Exception option.
|
||||
exception - Enable Xtensa HighPriInterrupts option.
|
||||
extendedl32r - Enable Xtensa Extended L32R option.
|
||||
fp - Enable Xtensa Single FP instructions.
|
||||
interrupt - Enable Xtensa Interrupt option.
|
||||
loop - Enable Xtensa Loop extension.
|
||||
mac16 - Enable Xtensa MAC16 instructions.
|
||||
miscsr - Enable Xtensa Miscellaneous SR option.
|
||||
mul32 - Enable Xtensa Mul32 option.
|
||||
mul32high - Enable Xtensa Mul32High option.
|
||||
nsa - Enable Xtensa NSA option.
|
||||
prid - Enable Xtensa Processor ID option.
|
||||
regprotect - Enable Xtensa Region Protection option.
|
||||
rvector - Enable Xtensa Relocatable Vector option.
|
||||
s32c1i - Enable Xtensa S32C1I option.
|
||||
sext - Enable Xtensa Sign Extend option.
|
||||
threadptr - Enable Xtensa THREADPTR option.
|
||||
timerint - Enable Xtensa Timer Interrupt option.
|
||||
windowed - Enable Xtensa Windowed Register option.
|
||||
|
||||
Use +feature to enable a feature, or -feature to disable it.
|
||||
For example, llc -mcpu=mycpu -mattr=+feature1,-feature2
|
||||
```
|
||||
|
||||
## Build Rust for Xtensa
|
||||
|
||||
While it should be possible to skip the internal build of LLVM libraries and reuse the LLVM toolchain built above, that didn't work successfully. Instead, use the built in version of the toolchain.
|
||||
|
||||
```
|
||||
% git clone https://github.com/MabezDev/rust-xtensa.git
|
||||
% cd rust-xtensa
|
||||
% git submodule update --init --recursive
|
||||
% ./configure --experimental-targets=Xtensa --prefix=/usr/local/xtensa/rust
|
||||
% python x.py build --stage=2
|
||||
```
|
||||
|
||||
The install option for `x.py` runs into some problems if sudo permissions are needed (requiring cargo dependencies to be vendored), so create an install directory owned by the user.
|
||||
|
||||
```
|
||||
% sudo mkdir -p /usr/local/xtensa/rust
|
||||
% sudo chown `whoami` /usr/local/xtensa/rust
|
||||
% python x.py install
|
||||
```
|
||||
|
||||
Finally, the library source tree needed by `xargo` to build the core library crates needs to be copied into the installation as well.
|
||||
|
||||
```
|
||||
% sudo cp Cargo.* /usr/local/xtensa/rust/
|
||||
% sudo cp -r library /usr/local/xtensa/rust/
|
||||
```
|
||||
|
||||
Finally, install `xargo` to wrap the normal `cargo` command.
|
||||
|
||||
```sh
|
||||
% cargo install xargo
|
||||
```
|
||||
|
||||
## Using Rust
|
||||
|
||||
To build a Rust library for Xtensa, set up the environment for `xargo` to find the custom Rust toolchain and build with `xargo` instead of `cargo`.
|
||||
|
||||
```sh
|
||||
export RUSTC=/usr/local/xtensa/rust/bin/rustc
|
||||
export XARGO_RUST_SRC=/usr/local/xtensa/rust/library
|
||||
xargo build --release --target=xtensa-esp32-none-elf
|
||||
```
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
{
|
||||
"nodes": {
|
||||
"esp-dev": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1767865407,
|
||||
"narHash": "sha256-QWF1rZYd+HvNzLIeRS+OEBX7HF0EhWCGeLbMkgtbsIo=",
|
||||
"owner": "mirrexagon",
|
||||
"repo": "nixpkgs-esp-dev",
|
||||
"rev": "5287d6e1ca9e15ebd5113c41b9590c468e1e001b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "mirrexagon",
|
||||
"repo": "nixpkgs-esp-dev",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1767799921,
|
||||
"narHash": "sha256-r4GVX+FToWVE2My8VVZH4V0pTIpnu2ZE8/Z4uxGEMBE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d351d0653aeb7877273920cd3e823994e7579b0b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1773524153,
|
||||
"narHash": "sha256-Jms57zzlFf64ayKzzBWSE2SGvJmK+NGt8Gli71d9kmY=",
|
||||
"rev": "e9f278faa1d0c2fc835bd331d4666b59b505a410",
|
||||
"revCount": 909435,
|
||||
"type": "tarball",
|
||||
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2511.909435%2Brev-e9f278faa1d0c2fc835bd331d4666b59b505a410/019cf299-7370-7f85-8f75-843d52f00e6c/source.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://flakehub.com/f/NixOS/nixpkgs/0"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"esp-dev": "esp-dev",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
description = "A Nix-flake-based C/C++ development environment";
|
||||
inputs = {
|
||||
nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0"; # stable Nixpkgs
|
||||
esp-dev.url = "github:mirrexagon/nixpkgs-esp-dev";
|
||||
};
|
||||
|
||||
outputs = { self, ... }@inputs:
|
||||
|
||||
let
|
||||
supportedSystems =
|
||||
[ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
|
||||
forEachSupportedSystem = f:
|
||||
inputs.nixpkgs.lib.genAttrs supportedSystems (system:
|
||||
f {
|
||||
pkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ inputs.esp-dev.overlays.default ];
|
||||
config = {
|
||||
permittedInsecurePackages = [ "python3.13-ecdsa-0.19.1" ];
|
||||
};
|
||||
};
|
||||
});
|
||||
in {
|
||||
devShells = forEachSupportedSystem ({ pkgs }: {
|
||||
default = pkgs.mkShell.override { } {
|
||||
packages = with pkgs;
|
||||
[
|
||||
esp-idf-full
|
||||
rustup
|
||||
cargo-generate
|
||||
openssl
|
||||
stdenv.cc.cc.lib
|
||||
libclang
|
||||
] ++ (if system == "aarch64-darwin" then [ ] else [ gdb ]);
|
||||
shellHook = ''
|
||||
export CLANGD_QUERY_DRIVER="$(which clang),$(which clang++)"
|
||||
export CMAKE_EXPORT_COMPILE_COMMANDS=1
|
||||
export IDF_TOOLCHAIN="clang"
|
||||
export NVIM_ESP32_ENV=1
|
||||
|
||||
export PATH="/home/flima/.rustup/toolchains/esp/xtensa-esp-elf/esp-15.2.0_20250920/xtensa-esp-elf/bin:$PATH"
|
||||
export LIBCLANG_PATH="/home/flima/.rustup/toolchains/esp/xtensa-esp32-elf-clang/esp-20.1.1_20250829/esp-clang/lib"
|
||||
|
||||
# export LIBCLANG_PATH="${pkgs.libclang.lib}/lib"
|
||||
export LD_LIBRARY_PATH="${pkgs.stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH"
|
||||
|
||||
'';
|
||||
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
$Command = "esptool.exe"
|
||||
if (Test-Path -Path ".\esptool-v3.1-win64\esptool-v3.1-win64\esptool.exe" -PathType Leaf) {
|
||||
$Command = ".\esptool-v3.1-win64\esptool-v3.1-win64\esptool.exe"
|
||||
}
|
||||
$OldPreference = $ErrorActionPreference
|
||||
$ErrorActionPreference = 'stop'
|
||||
try {if(Get-Command $Command){"$Command exists"}}
|
||||
Catch {
|
||||
"$Command not found. Downloading"
|
||||
Invoke-WebRequest https://github.com/espressif/esptool/releases/download/v3.1/esptool-v3.1-win64.zip -OutFile esptool-v3.1-win64.zip
|
||||
Expand-Archive -Path esptool-v3.1-win64.zip
|
||||
$Command = ".\esptool-v3.1-win64\esptool-v3.1-win64\esptool.exe"
|
||||
$ErrorActionPreference=$OldPreference
|
||||
}
|
||||
|
||||
&$Command -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 esp32-hello-rust.bin
|
||||
Loading…
Reference in New Issue