(Espressif's IoT Development Framework)
The ESP-IDF API in Rust, with support for each ESP chip (ESP32, ESP32S2, ESP32S3, ESP32C3, etc.) based on the Rust target.
For more information, check out: * The Rust on ESP Book * The esp-idf-template project * The esp-idf-svc project * The esp-idf-hal project * The Rust for Xtensa toolchain * The Rust-with-STD demo project
Table of contents - Build - Features - sdkconfig - Build configuration - Extra esp-idf components - Conditional compilation - More info
native
(default): utilizing native ESP-IDF tooling via the embuild crate orpio
(backup): utilizing PlatformIO (also via the embuild crate).native
This is the default feature for downloading all tools and building the ESP-IDF framework using the framework's "native" (own) tooling. It relies on build and installation utilities available in the embuild crate.
The native
builder installs all needed tools to compile this crate as well as the ESP-IDF framework itself.
pio
This is a backup feature for installing all build tools and building the ESP-IDF framework. It uses PlatformIO via the embuild crate.
Similarly to the native
builder, the pio
builder also automatically installs all needed tools (PlatformIO packages and frameworks in this case) to compile this crate as well as the ESP-IDF framework itself.
⚠️ The
pio
builder is less flexible than the defaultnative
builder in that it can work with only one, specific version of ESP-IDF. At the time of writing, this is V4.3.2.
binstart
Defines the esp-idf entry-point for when the root crate is a binary
crate that
defines a
main
function.
libstart
Defines the esp-idf entry-point for when the root crate is a library crate. the root crate is expected to provide a ```rust
fn main() {} ``` function.
The esp-idf makes use of an sdkconfig file for its compile-time component configuration (see the esp-idf docs for more information). This config is separate from the build configuration.
sdkconfig
fileTBD: Upcoming
sdkconfig
fileTo enable Bluetooth, or do other configurations to the ESP-IDF sdkconfig you might take advantage of the cargo-pio Cargo subcommand:
* To install it, issue cargo install cargo-pio --git https://github.com/ivmarkov/cargo-pio
* To open the ESP-IDF interactive menuconfig system, issue cargo pio espidf menuconfig
in the root of your binary crate project
* To use the generated/updated sdkconfig
file, follow the steps described in the "Bluetooth Support" section
There are two ways to configure how the ESP-IDF framework is compiled:
1. Environment variables, denoted by $VARIABLE
;
The environment variables can be passed on the command line, or put into the
[env]
section of a.cargo/config.toml
file (see cargo reference).
The [package.metadata.esp-idf-sys]
section of the Cargo.toml
, denoted by field
.
Note
Configuration can only come from the root crate'sCargo.toml
. The root crate is the package in the workspace directory. If there is not root crate in case of a virtual workspace, its name can be specified with theESP_IDF_SYS_ROOT_CRATE
environment variable.
⚠️ Environment variables always take precedence over
Cargo.toml
metadata.
Note: workspace directory
The workspace directory mentioned here is always the directory containing theCargo.lock
file and thetarget
directory (where the build artifacts are stored). It can be overridden with theCARGO_WORKSPACE_DIR
environment variable, should this not be the right directory.
(Seeembuild::cargo::workspace_dir
for more information).There is no need to explicitly add a
[workspace]
section to theCargo.toml
of the workspace directory.
The following configuration options are available:
esp_idf_sdkconfig_defaults
, $ESP_IDF_SDKCONFIG_DEFAULTS
A single path or a list of paths to sdkconfig.defaults
files to be used as base
values for the sdkconfig
. If such a path is
relative, it will be relative to the workspace directory.
Defaults to sdkconfig.defaults
.
In case of the environment variable, multiple elements should be ;
-separated.
Note
For each defaults file in this list, a more specific file will also be searched and used. This happens with the following patterns and order (least to most specific):
<path>
<path>.<profile>
<path>.<mcu>
<path>.<profile>.<mcu>
where
<profile>
is the current cargo profile used (debug
/release
) and<mcu>
specifies the mcu for which this is currently compiled for (see themcu
configuration option below).
⚠️ A setting contained in a more specific defaults file will override the same setting specified in a less specific one. For example, in a debug build, flags in
sdkconfig.debug
override those insdkconfig.defaults
.
esp_idf_sdkconfig
, $ESP_IDF_SDKCONFIG
The sdkconfig
file used to configure the
esp-idf
.
If this is a relative path, it is relative to the workspace directory.
Defaults to sdkconfig
.
Note
Similar to thesdkconfig.defaults
-file a more specificsdkconfig
-file will be selected if available. This happens with the following patterns and precedence:
<path>.<profile>.<mcu>
<path>.<mcu>
<path>.<profile>
<path>
Note: native builder only
The cargo optimization options (debug
andopt-level
) are used by default to determine the compiler optimizations of theesp-idf
, however if the compiler optimization options are already set in thesdkconfig
they will be used instead.
esp_idf_tools_install_dir
, $ESP_IDF_TOOLS_INSTALL_DIR
The install location for the ESP-IDF framework tooling.
Note
The framework tooling is either PlatformIO when thepio
builder is used, or the ESP-IDF native toolset when thenative
builder is used (default).
This option can take one of the following values:
workspace
(default) - the tooling will be installed or used in
<crate-workspace-dir>/.embuild/platformio
for pio
, and
<crate-workspace-dir>/.embuild/espressif
for the native
builder;out
- the tooling will be installed or used inside esp-idf-sys's build output
directory,
and will be deleted when cargo clean
is invoked;global
- the tooling will be installed or used in its standard directory
(~/.platformio
for PlatformIO, and ~/.espressif
for the native ESP-IDF toolset);custom:<dir>
- the tooling will be installed or used in the directory specified by
<dir>
. If this directory is a relative location, it is assumed to be relative to
the workspace directory;fromenv
- use the build framework from the environment
platformio
from the environment (i.e. $PATH
)and error if this is not possible.
⚠️ Please be extra careful with the
custom:<dir>
setting when switching frompio
tonative
and the other way around, because the builder will install the tooling in<dir>
without using any additionalplatformio
orespressif
subdirectories, so if you are not careful, you might end up with both PlatformIO, as well as the ESP-IDF native tooling intermingled together in a single folder.
Note
The ESP-IDF git repository will be cloned inside the tooling directory. The native builder will use the esp-idf atidf_path
of available.
idf_path
, $IDF_PATH
(native builder only)A path to a user-provided local clone of the esp-idf, that will be used instead of the one downloaded by the build script.
esp_idf_version
, $ESP_IDF_VERSION
(native builder only)The version used for the esp-idf
, can be one of the following:
commit:<hash>
: Uses the commit <hash>
of the esp-idf
repository.
Note that this will clone the whole esp-idf
not just one commit.tag:<tag>
: Uses the tag <tag>
of the esp-idf
repository.branch:<branch>
: Uses the branch <branch>
of the esp-idf
repository.v<major>.<minor>
or <major>.<minor>
: Uses the tag v<major>.<minor>
of the esp-idf
repository.<branch>
: Uses the branch <branch>
of the esp-idf
repository.Defaults to v4.4.1
.
esp_idf_repository
, $ESP_IDF_REPOSITORY
(native builder only)The URL to the git repository of the esp-idf
, defaults to https://github.com/espressif/esp-idf.git.
Note
When thepio
builder is used, it is possible to achieve something similar toESP_IDF_VERSION
andESP_IDF_REPOSITORY
by using theplatform_packages
PlatformIO option as follows:
ESP_IDF_PIO_CONF="platform_packages = framework-espidf @ <git-url> [@ <git-branch>]"
The above approach however has the restriction that PlatformIO will always use the ESP-IDF build tooling from its own ESP-IDF distribution, so the user-provided ESP-IDF branch may or may not compile. The current PlatformIO tooling is suitable for compiling ESP-IDF branches derived from versions 4.3.X and 4.4.X.
$ESP_IDF_GLOB[_XXX]_BASE
and $ESP_IDF_GLOB[_XXX]_YYY
A pair of environment variable prefixes that enable copying files and directory trees that match a certain glob mask into the native C project used for building the ESP-IDF framework:
ESP_IDF_GLOB[_XXX]_BASE
specifies the base directory which will be glob-ed for resources to be copiedESP_IDF_GLOB[_XXX]_BASE_YYY
specifies one or more environment variables that represent the glob masks of resources to be searched for and copied, using the directory designated by the ESP_IDF_GLOB[_XXX]_BASE
environment variable as the root. For example, if the following variables are specified:ESP_IDF_GLOB_HOMEDIR_BASE=/home/someuser
ESP_IDF_GLOB_HOMEDIR_FOO=foo*
ESP_IDF_GLOB_HOMEDIR_BAR=bar*
... then all files and directories matching 'foo' or 'bar' from the home directory of the user will be copied into the ESP-IDF C project.Note also that _HOMEDIR
in the above example is optional, and is just a mechanism allowing the user to specify more than one base directory and its glob patterns.
$ESP_IDF_PIO_CONF_XXX
(pio builder only)A PlatformIO setting (or multiple settings separated by a newline) that will be passed
as-is to the platformio.ini
file of the C project that compiles the ESP-IDF.
Check the PlatformIO documentation for more information as to what settings you can pass via this variable.
Note
This is not one variable, but rather a family of variables all starting withESP_IDF_PIO_CONF_
. For example, passingESP_IDF_PIO_CONF_1
as well asESP_IDF_PIO_CONF_FOO
is valid and all such variables will be honored.
esp_idf_cmake_generator
, $ESP_IDF_CMAKE_GENERATOR
(native builder only)The CMake generator to be used when building the ESP-IDF.
If not specified or set to default
, Ninja will be used on all platforms except
Linux/aarch64, where (for now) the Unix Makefiles generator will be used, as there are
no Ninja builds for that platform provided by Espressif yet.
Possible values for this environment variable are the names of all command-line generators that CMake supports with spaces and hyphens removed.
mcu
, $MCU
The MCU name (i.e. esp32
, esp32s2
, esp32s3
esp32c3
and esp32h2
).
If not set this will be automatically detected from the cargo target.
⚠️ Older ESP-IDF versions might not support all MCUs from above.
esp_idf_components
, $ESP_IDF_COMPONENTS
(native builder only)The (;
-separated for the environment variable) list of esp-idf component names that
should be built. This list is used to trim the esp-idf build. Any component that is a
dependency of a component in this list will also automatically be built.
Defaults to all components being built.
Note
Some components must be explicitly enabled in the sdkconfig.
Extra components must also be added to this list if they are to be built.
Note
By only specifying thebindings_header
field, one can extend the set of esp-idf bindings that were generated from src/include/esp-idf/bindings.h. To do this you need to create a*.h
header file in your project source, and reference that in thebindings_header
variable. You can then include extra esp-idf header files from there.
An extra component can be specified like this:
```toml [[package.metadata.esp-idf-sys.extra_components]]
Cargo.toml
.[Self::bindings_header]
will still be generated.component_dirs = ["dir1", "dir2"] # or "dir"
#
Cargo.toml
.#
bindings_header = "bindings.h"
esp-idf
bindings and put into their own module inside the esp-idf-sys
crate.esp-idf
bindings (which are available in the crate root).#
esp-idf
bindings if theesp-idf
headers that were already processed for the esp-idf
bindings are#
bindings_module = "name" ```
and is equivalent to
toml
[package.metadata.esp-idf-sys]
extra_components = [
{ component_dirs = [ "dir1", "dir2" ], bindings_header = "bindings.h", bindings_module = "name" }
]
The esp-idf-sys build script will set rustc cfgs available for its sources.
⚠️ If an upstream crate also wants to have access to the cfgs it must: - have
esp-idf-sys
as a dependency, and - propagate the cfgs in its build script with
rust embuild::build::CfgArgs::output_propagated("ESP_IDF").expect("no esp-idf-sys cfgs");
using the embuild crate.
The list of available cfgs:
- esp_idf_comp_{component}_enabled
for each component
- esp_idf_version="{major}.{minor}"
- esp_idf_version_full="{major}.{minor}.{patch}"
- esp_idf_version_major="{major}"
- esp_idf_version_minor="{minor}"
- esp_idf_version_patch="{patch}"
- esp_idf_{sdkconfig_option}
Each sdkconfig
setting
where {sdkconfig_option}
corresponds to the option set in the sdkconfig lowercased
and without the CONFIG_
prefix. Only options set to y
will get a cfg.
{mcu}
Corresponds to the mcu for which the esp-idf is compiled for.
If you are interested in how it all works under the hood, check the build.rs build script of this crate.