esp-rs / esp-idf-template

A "Hello, world!" template of a Rust binary crate for the ESP-IDF framework.
380 stars 45 forks source link

Using cargo workspaces #67

Closed tadejg closed 1 year ago

tadejg commented 1 year ago

How can I use this template with cargo workspaces? I'd like to separate parts of my firmware into libs which can be tested.

ivmarkov commented 1 year ago

No way. The purpose of this template is to create the minimal possible binary crate to get you started with esp, not to help you in doing proper code separation.

tadejg commented 1 year ago

I've played around with my project a bit more and managed to get it building with cargo workspaces. For anyone else trying to use cargo workspaces, here are my findings.

NOTE: I'm very new to rust, so there might be better or more correct ways of doing this. This is just what worked for me.

  1. Initialize a new project using this template (esp-idf-template) to serve as a reference
  2. Copy .cargo/ from the reference project to the root of your cargo workspace.
  3. Create a binary crate in your workspace to serve as the entrypoint (cargo new entrypoint)
  4. Tell the build system which crate should be used as the entrypoint by adding the following line under [env] section in .cargo/config.toml
    ESP_IDF_SYS_ROOT_CRATE = { value = "entrypoint" }

    The full [env] section should look something like this:

    ...rest of config.toml...
    [env]
    # Note: these variables are not used when using pio builder
    # Enables the esp-idf-sys "native" build feature (`cargo build --features native`) to build against ESP-IDF stable (v4.4)
    ESP_IDF_VERSION = { value = "branch:release/v4.4" }
    # Enables the esp-idf-sys "native" build feature (`cargo build --features native`) to build against ESP-IDF master (mainline)
    #ESP_IDF_VERSION = { value = "master" }
    ESP_IDF_SYS_ROOT_CRATE = { value = "entrypoint" }
  5. Copy rust-toolchain.toml from the reference project into the root of your workspace
  6. Copy sdkconfig.defaults from the reference project into the root of your workspace
  7. Copy build.rs from the reference project into your entrypoint crate
  8. Copy src/main.rs from the reference project into your entrypoint crate (your entrypoint must contain the esp_idf_sys::link_patches() call, otherwise linking will fail)
  9. Copy [features], [dependencies], and [build-dependencies] sections from the reference Cargo.toml into your entrypoint crate's Cargo.toml At this point your entrypoint/Cargo.toml should look something like this:
    
    [package]
    name = "entrypoint"
    version = "0.1.0"
    authors = ["user"]
    edition = "2021"

[features] pio = ["esp-idf-sys/pio"]

[dependencies] esp-idf-sys = { version = "0.31.11", features = ["binstart"] }

[build-dependencies] embuild = "0.30.4" anyhow = "1"

10. Create your workspace `Cargo.toml` with the following content (`resolver` option and `[profile.*]` sections taken from the reference `Cargo.toml`):

[workspace] resolver = "2" members = [ "entrypoint", ]

[profile.release] opt-level = "s"

[profile.dev] debug = true # Symbols are nice and they don't increase the size on Flash opt-level = "z"


You should end up with a file structure like this:

workspace/ ├─ .cargo/ │ ├─ config.toml ├─ entrypoint/ │ ├─ src/ │ │ ├─ main.rs │ ├─ Cargo.toml │ ├─ build.rs ├─ rust-toolchain.toml ├─ sdkconfig.defaults ├─ Cargo.toml



At this point you should be able to run build the workspace using `cargo build`
ivmarkov commented 1 year ago

In retrospective, I should have pointed you at my RUWM project, which has a similar workspace organization. Maybe still useful as a reference.