Warning The Viam Micro-RDK is currently in beta.
This document provides advanced development configuration notes to aid in the development of Micro-RDK modules and projects, or for working on the Micro-RDK itself.
-
If you are interested in just installing and using the Micro-RDK, please see the Viam Installation Documentation.
-
These instructions and notes assume a working Micro-RDK development environment. Please see the Development Setup Documentation before proceeding.
The micro-rdk monorepo is only part of the development story: when
developing for or with Micro-RDK, there will be other directories in
play (e.g. projects generated from the template, etc.), and
coordinating the state of these many directories and repositories can
prove troublesome. A carefully placed .cargo/config.toml
file can
inject settings for the entire tree of trees, including the micro-rdk
monorepo, projects, and modules. Simply create a .cargo
directory as
a peer of your micro-rdk monorepo and any project directories, and
then create a config.toml
file within it. Settings applied in that
file will now apply globally to all crates inside the micro-rdk as
well as to peer project directories. Here is an example layout:
.
├── .cargo
│ └── config.toml
├── micro-rdk
│ ├── ...
│ ├── examples
│ ├── micro-rdk
│ ├── micro-rdk-ffi
│ ├── micro-rdk-installer
│ ├── micro-rdk-macros
│ ├── micro-rdk-server
│ └── templates
└── projects
├── module-under-development
├── another-module
└── module-consuming-project
Several of the remaining development tips in this document make use of this functionality.
Use sccache to cache the result
of rust compiles for an overall faster experience as you move back and
forth between branches. Install it with cargo install sccache
and
then you can opt into it by setting the RUSTC_WRAPPER
environment
variable to point to sccache
, e.g. RUSTC_WRAPPER=/path/to/sccache cargo build ...
. But it can be easy to forget to configure
that. Instead, you can add the following to a .cargo/config.toml
(either in $HOME/.cargo/config.toml
to apply it everywhere, or in a
tree-level .cargo/config.toml
per above):
[build]
rustc-wrapper = "/path/to/sccache"
[profile.dev.package."*"]
incremental = false
Note that this disables incremental compilation for dev builds because
sccache
is incompatible with incremental compilation.
If you are building Micro-RDK
for ESP32 on a macOS machine and you
receive an error like the following:
xtensa-esp32-elf-gcc: error: unrecognized command line option '--target=xtensa-esp32-espidf'
Then work around this
issue by setting CRATE_CC_NO_DEFAULTS=1
in your environment
(e.g. make build-esp32-bin CRATE_CC_NO_DEFAULTS=1
or
CRATE_CC_NO_DEFAULTS=1 cargo +esp build ...
. Or, you can use the
tree-level Cargo configuration (e.g. .cargo/config.toml
as above)
to just take care of this for you:
[env]
CRATE_CC_NO_DEFAULTS = { value = "1" }
It might be better to scope that to only apply for +esp
builds: if
you know the syntax for that, please submit a PR to this
repository. It is possible that a resolution of this upstream cargo
issue
may be a prerequisite.
The Python packaging made available with Homebrew is not intended for end-user consumption. Attempts to install packages outside of a virtual environment of some sort will result in messages like the following:
$ python3 -m pip install foo
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try brew install
xyz, where xyz is the package you are trying to
install.
If you wish to install a non-brew-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip.
If you wish to install a non-brew packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
Unfortunately, the ESP-IDF ecosystem explicitly depends on being able
to install python packages for its own ends, specifically, the
virtualenv
package.
This conflict is unfortunate, and there are only two somewhat unsavory paths forward:
-
Use a different Python installation which is not externally managed. There are many ways to obtain a version of Python independent from the one in Homebrew which will not prevent ESP-IDF from installing the packages it wants to install (e.g. with
asdf
). -
Forcibly pre-install the
virtualenv
package by runningpython3 -m pip install --user --break-system-packages virtualenv
. This will permit the ESP-IDF build scripts to skip the attempt to installvirtualenv
because it is already installed. However, per the scary name of the flag, it risks breaking system packages.
Again, if you are working with Micro-RDK, you probably have both the
Micro-RDK
monorepo and various project directories associated with
it. Those projects quite often have their own Cargo.toml
files that
have dependencies on micro-rdk by way of github:
[dependencies]
...
micro-rdk = {version = "0.2.2", git = "https://github.com/viamrobotics/micro-rdk.git", features = ["esp32", "binstart","provisioning"], rev = "a1863c9" }
micro-rdk-modular-driver-example = { version = "0.2.2", git = "https://github.com/viamrobotics/micro-rdk", rev = "a1863c9" }
But just as often, what you actually want to do is to have these
projects use your _local micro-rdk state, and you end up hand
editing the Cargo.toml
file to point to a path instead:
[dependencies]
...
micro-rdk = { path = "../micro-rdk/micro-rdk, features = ["esp32", "binstart","provisioning"] }
micro-rdk-modular-driver-example = { path = "../micro-rdk/examples/modular-drivers" }
It is a nuisance to maintain these edits: avoiding checking them in,
keeping them in stashes, replicating them across many Cargo.toml
files, etc. Instead, use the tree-level .cargo/config.toml
to point
to your local tree using patch:
[patch.'https://github.com/viamrobotics/micro-rdk.git']
micro-rdk = { path = "./micro-rdk/micro-rdk" }
micro-rdk-ffi = { path = "./micro-rdk/micro-rdk-ffi" }
micro-rdk-macros = { path = "./micro-rdk/micro-rdk-macros" }
micro-rdk-modular-driver-example = { path = "./micro-rdk/examples/modular-drivers" }
Note that you need to declare each library crate that a dependency
might want to link against individually. Also be careful with pathing,
as it appears that the paths are interpreted relative to the siting of
the .cargo
directory, not the .cargo/config.toml
file (i.e. you do
not need a leading ../
to pop up a directory level. Now all projects
under the affected tree will always use the local Micro-RDK state
without needing local Cargo.toml
edits.
The documented build procedures for Micro-RDK and Micro-RDK adjacent
projects leverage the embuild
package
to automate the installation of the ESP-IDF framework. The default
settings are usually what you want, but there are times when it may
make sense to customize them.
Please review the esp-idf-sys
build options documentation for details on what things are available to customize.
Some values are defaulted in the Micro-RDK top-level Cargo.toml
, but
these values may be overridden with environment variables on the
command line or as an argument to make
. Another path to
customization is to add settings to the [env]
section of a
tree-level .cargo/config.toml
file.
Values of particular interest include:
esp_idf_tools_install_dir
/$ESP_IDF_TOOLS_INSTALL_DIR
, to customize the location where ESP-IDF trees will be installed, if you do not like the default of installing them under thetarget
directory. Note in particular thefromenv
value, which should be used if you have a dedicated ESP-IDF installation already installed and activated that you wish to use.esp_idf_version
/$ESP_IDF_VERSION
, to override the version of ESP-IDF that will be used to build your project or the Micro-RDK.mcu
/$MCU
, to select a different target for the build, rather than the defaultesp32
MCU target.
If you prefer to always use a manually configured ESP-IDF environment
rather than relying on embuild
s automated ESP-IDF installation, you
can do this permanently for all rust development by adding the
following to your treel-level .cargo/config.toml
:
[env]
ESP_IDF_TOOLS_INSTALL_DIR = { value = "fromenv" }
Once this setting is in play, there may be configuration scripts that need to be run to tell the build system where to find the standalone ESP-IDF installation.
Both the Micro-RDK and projects generated from the project template
honor environment variables to statically configure WiFi credentials
via MICRO_RDK_WIFI_SSID
and MICRO_RDK_WIFI_PASSWORD
. These values
are examined at build time, so if you wish to change them you will need to
rebuild and reflash your device for them to have effect.
Similarly, the micro-rdk-server
project and projects generated from
the project template will expect to find robot identity and credential
information in a file called viam.json
. This file is, like the WiFi
credentials, used at build time, so if you add or remove it or change
the contents, you will need to rebuild and reflash in order for the
changes to have effect.
Viam provides a Docker image with a pre-configured Micro-RDK
development environment, and tooling to automate use of that image,
called canon
. The primary use case for the canon
-based workflow is
CI and release builds of the Micro-RDK. However, it is also possible
to use these images for development, if the other ways are proving
difficult.
-
Install
canon
, per the installation instructions -
Run rust development tasks inside the container by launching them as a
bash
shell command:
$ canon bash -lc "make build-esp32-bin"
- Run flashing and monitoring commands outside cannon, so they have access to things like local USB ports:
$ make flash-esp32-bin