From 96ea4e64a90647db44e909028be41e41c0dac787 Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Sun, 21 Dec 2025 00:01:27 +0000 Subject: [PATCH 1/5] support building openthread in full-thread-device mode --- openthread-sys/Cargo.toml | 2 ++ openthread-sys/build.rs | 19 ++++++++++++++++++- openthread-sys/gen/builder.rs | 7 +++++-- openthread/Cargo.toml | 1 + openthread/src/lib.rs | 7 +++++++ openthread/src/platform.rs | 6 ++++++ xtask/src/main.rs | 6 ++++++ 7 files changed, 45 insertions(+), 3 deletions(-) diff --git a/openthread-sys/Cargo.toml b/openthread-sys/Cargo.toml index 7a2837a..6b189c7 100644 --- a/openthread-sys/Cargo.toml +++ b/openthread-sys/Cargo.toml @@ -19,6 +19,8 @@ force-generate-bindings = [] # If this feature is not enabled, the build will assume and use the "official" RiscV GCC toolchain: # https://github.com/riscv-collab/riscv-gnu-toolchain force-esp-riscv-toolchain = [] +# Build the OpenThread library in Full Thread Device (FTD) mode +full-thread-device = [] [build-dependencies] anyhow = "1" diff --git a/openthread-sys/build.rs b/openthread-sys/build.rs index b3697c0..8c911a9 100644 --- a/openthread-sys/build.rs +++ b/openthread-sys/build.rs @@ -18,6 +18,7 @@ fn main() -> Result<()> { let target = env::var("TARGET").unwrap(); let force_esp_riscv_toolchain = env::var("CARGO_FEATURE_FORCE_ESP_RISCV_TOOLCHAIN").is_ok(); + let full_thread_device = cfg!(feature = "full-thread-device"); let pregen_bindings = env::var("CARGO_FEATURE_FORCE_GENERATE_BINDINGS").is_err(); let pregen_bindings_rs_file = crate_root_path @@ -44,6 +45,7 @@ fn main() -> Result<()> { None, None, force_esp_riscv_toolchain, + full_thread_device, ); let libs_dir = builder.compile(&out, None)?; @@ -72,7 +74,22 @@ fn main() -> Result<()> { file_name.trim_end_matches(".lib") }; - println!("cargo:rustc-link-lib=static={lib_name}"); + let should_link = match ( + lib_name.contains("-ftd"), + lib_name.contains("-mtd"), + full_thread_device, + ) { + (true, false, true) => true, + (true, false, false) => false, + (false, true, false) => true, + (false, true, true) => false, + (false, false, _) => true, + (true, true, _) => panic!(), + }; + + if should_link { + println!("cargo:rustc-link-lib=static={lib_name}"); + } } } } diff --git a/openthread-sys/gen/builder.rs b/openthread-sys/gen/builder.rs index a233fe3..36bf8a9 100644 --- a/openthread-sys/gen/builder.rs +++ b/openthread-sys/gen/builder.rs @@ -13,6 +13,7 @@ pub struct OpenThreadBuilder { clang_path: Option, clang_sysroot_path: Option, clang_target: Option, + full_thread_device: bool, } impl OpenThreadBuilder { @@ -37,6 +38,7 @@ impl OpenThreadBuilder { clang_sysroot_path: Option, clang_target: Option, force_esp_riscv_toolchain: bool, + full_thread_device: bool, ) -> Self { Self { cmake_configurer: CMakeConfigurer::new( @@ -50,6 +52,7 @@ impl OpenThreadBuilder { clang_path, clang_sysroot_path, clang_target, + full_thread_device, } } @@ -177,8 +180,8 @@ impl OpenThreadBuilder { config .define("OT_LOG_LEVEL", "NOTE") - .define("OT_FTD", "OFF") - .define("OT_MTD", "ON") + .define("OT_FTD", if self.full_thread_device { "ON" } else { "OFF" }) + .define("OT_MTD", if self.full_thread_device { "OFF" } else { "ON" }) .define("OT_RCP", "OFF") .define("OT_TCP", "OFF") .define("OT_APP_CLI", "OFF") diff --git a/openthread/Cargo.toml b/openthread/Cargo.toml index 6fb699b..43f1840 100644 --- a/openthread/Cargo.toml +++ b/openthread/Cargo.toml @@ -23,6 +23,7 @@ defmt = ["dep:defmt", "heapless/defmt-03", "embassy-time/defmt"] force-generate-bindings = ["openthread-sys/force-generate-bindings"] force-esp-riscv-toolchain = ["openthread-sys/force-esp-riscv-toolchain"] isupper = [] # Provide internal implementation of the `isupper` C fn +full-thread-device = ["openthread-sys/full-thread-device"] [dependencies] openthread-sys = { path = "../openthread-sys" } diff --git a/openthread/src/lib.rs b/openthread/src/lib.rs index 47e471f..608028a 100644 --- a/openthread/src/lib.rs +++ b/openthread/src/lib.rs @@ -1553,6 +1553,13 @@ impl<'a> OtContext<'a> { Ok(()) } + #[cfg(feature = "full-thread-device")] + fn plat_radio_enable_src_match(&mut self, enable: bool) { + trace!("Plat radio enable src match callback, enable: {}", enable); + // Referencing ESP-IDF implementation, here: https://github.com/espressif/esp-idf/blob/1e87d43f1ae1e582771cc0df2f7dffb60a0186fc/components/openthread/src/port/esp_openthread_radio.c#L361 + // This should call into set_pending_mode, but this is not currenty exposed by the esp-radio crate + } + fn plat_settings_init(&mut self, sensitive_keys: &[u16]) { info!( "Plat settings init callback, sensitive keys: {:?}", diff --git a/openthread/src/platform.rs b/openthread/src/platform.rs index 7a38fb8..d650a78 100644 --- a/openthread/src/platform.rs +++ b/openthread/src/platform.rs @@ -170,6 +170,12 @@ extern "C" fn otPlatRadioReceive(instance: *mut otInstance, channel: u8) -> otEr .into_ot_code() } +#[no_mangle] +#[cfg(feature = "full-thread-device")] +extern "C" fn otPlatRadioEnableSrcMatch(instance: *mut otInstance, enable: bool) { + OtContext::callback(instance).plat_radio_enable_src_match(enable); +} + #[no_mangle] extern "C" fn otPlatSettingsInit( instance: *mut otInstance, diff --git a/xtask/src/main.rs b/xtask/src/main.rs index f21876f..85f71be 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -30,6 +30,10 @@ enum Commands { #[arg(short = 'e', long)] force_esp_riscv_toolchain: bool, + /// If specified, builds OpenThread as a Full Thread Device (FTD), otherwise builds as a Minimal Thread Device (MTD) + #[arg(long)] + full_thread_device: bool, + /// Target triple for which to generate bindings and `.a` libraries target: String, }, @@ -52,6 +56,7 @@ fn main() -> Result<()> { if let Some(Commands::Gen { target, force_esp_riscv_toolchain, + full_thread_device, }) = args.command { let builder = builder::OpenThreadBuilder::new( @@ -63,6 +68,7 @@ fn main() -> Result<()> { None, None, force_esp_riscv_toolchain, + full_thread_device, ); let out = TempDir::new("openthread-sys-libs")?; From b3e4b8628f3b72d63d45650495170e3cc6b87fec Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Sun, 21 Dec 2025 00:19:43 +0000 Subject: [PATCH 2/5] make mtd/ftd linker decision clearer --- README.md | 2 +- openthread-sys/build.rs | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ab78b02..d16c08f 100644 --- a/README.md +++ b/README.md @@ -48,13 +48,13 @@ Examples of GCC toolchains that are known to work fine: ## Features - MTD (Minimal Thread Device) functionality +- Optional FTD (Full Thread Device) functionality - Optional integration with [`embassy-net`]() and [`edge-nal`]() - Out of the box support for the IEEE 802.15.4 radio in [Espressif](openthread/src/esp.rs) and [Nordic Semiconductor](openthread/src/nrf.rs) chips ## Next - Sleepy end-device -- FTD (Full Thread Device) functionality ## Non-Goals diff --git a/openthread-sys/build.rs b/openthread-sys/build.rs index 8c911a9..afc39c0 100644 --- a/openthread-sys/build.rs +++ b/openthread-sys/build.rs @@ -74,18 +74,12 @@ fn main() -> Result<()> { file_name.trim_end_matches(".lib") }; - let should_link = match ( - lib_name.contains("-ftd"), - lib_name.contains("-mtd"), - full_thread_device, - ) { - (true, false, true) => true, - (true, false, false) => false, - (false, true, false) => true, - (false, true, true) => false, - (false, false, _) => true, - (true, true, _) => panic!(), - }; + let is_ftd_specific = lib_name.contains("-ftd"); + let is_mtd_specific = lib_name.contains("-mtd"); + let is_general = !is_ftd_specific && !is_mtd_specific; + let should_link = is_general + || (is_ftd_specific && full_thread_device) + || (is_mtd_specific && !full_thread_device); if should_link { println!("cargo:rustc-link-lib=static={lib_name}"); From d5835f73302ff127ab7aa59990a1409e12d3c907 Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Mon, 5 Jan 2026 21:48:06 +0000 Subject: [PATCH 3/5] change approach to allow dynamic rebuilding based on state of config flags --- openthread-sys/build.rs | 48 +++-- openthread-sys/gen/builder.rs | 32 +-- openthread-sys/gen/openthread_config.rs | 197 ++++++++++++++++++ openthread-sys/gen/pregen_paths.rs | 34 +++ .../13518017024750854729/config.txt | 19 ++ .../riscv32imac-unknown-none-elf/bindings.rs} | 0 .../libs}/libeverest.a | Bin .../libs}/libmbedcrypto.a | Bin .../libs}/libmbedtls.a | Bin .../libs}/libmbedx509.a | Bin .../libs}/libopenthread-cli-mtd.a | Bin .../libs}/libopenthread-hdlc.a | Bin .../libs}/libopenthread-mtd.a | Bin .../libs}/libopenthread-ncp-mtd.a | Bin .../libopenthread-platform-utils-static.a | Bin .../libs}/libopenthread-platform.a | Bin .../libs}/libopenthread-radio-spinel.a | Bin .../libs}/libopenthread-spinel-ncp.a | Bin .../libs}/libopenthread-spinel-rcp.a | Bin .../libs}/libp256m.a | Bin .../libs}/libsupport.a | Bin .../libs}/libtcplp-mtd.a | Bin .../riscv32imc-unknown-none-elf/bindings.rs} | 0 .../thumbv6m-none-eabi/bindings.rs} | 0 .../thumbv6m-none-eabi/libs}/libeverest.a | Bin .../thumbv6m-none-eabi/libs}/libmbedcrypto.a | Bin .../thumbv6m-none-eabi/libs}/libmbedtls.a | Bin .../thumbv6m-none-eabi/libs}/libmbedx509.a | Bin .../libs}/libopenthread-cli-mtd.a | Bin .../libs}/libopenthread-hdlc.a | Bin .../libs}/libopenthread-mtd.a | Bin .../libs}/libopenthread-ncp-mtd.a | Bin .../libopenthread-platform-utils-static.a | Bin .../libs}/libopenthread-platform.a | Bin .../libs}/libopenthread-radio-spinel.a | Bin .../libs}/libopenthread-spinel-ncp.a | Bin .../libs}/libopenthread-spinel-rcp.a | Bin .../thumbv6m-none-eabi/libs}/libp256m.a | Bin .../thumbv6m-none-eabi/libs}/libsupport.a | Bin .../thumbv6m-none-eabi/libs}/libtcplp-mtd.a | Bin .../thumbv7em-none-eabi/bindings.rs} | 0 .../thumbv7em-none-eabi/libs}/libeverest.a | Bin .../thumbv7em-none-eabi/libs}/libmbedcrypto.a | Bin .../thumbv7em-none-eabi/libs}/libmbedtls.a | Bin .../thumbv7em-none-eabi/libs}/libmbedx509.a | Bin .../libs}/libopenthread-cli-mtd.a | Bin .../libs}/libopenthread-hdlc.a | Bin .../libs}/libopenthread-mtd.a | Bin .../libs}/libopenthread-ncp-mtd.a | Bin .../libopenthread-platform-utils-static.a | Bin .../libs}/libopenthread-platform.a | Bin .../libs}/libopenthread-radio-spinel.a | Bin .../libs}/libopenthread-spinel-ncp.a | Bin .../libs}/libopenthread-spinel-rcp.a | Bin .../thumbv7em-none-eabi/libs}/libp256m.a | Bin .../thumbv7em-none-eabi/libs}/libsupport.a | Bin .../thumbv7em-none-eabi/libs}/libtcplp-mtd.a | Bin openthread-sys/pre-generated/README.md | 19 ++ xtask/src/main.rs | 44 ++-- 59 files changed, 328 insertions(+), 65 deletions(-) create mode 100644 openthread-sys/gen/openthread_config.rs create mode 100644 openthread-sys/gen/pregen_paths.rs create mode 100644 openthread-sys/pre-generated/13518017024750854729/config.txt rename openthread-sys/{src/include/riscv32imac-unknown-none-elf.rs => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/bindings.rs} (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libeverest.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libmbedcrypto.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libmbedtls.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libmbedx509.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-cli-mtd.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-hdlc.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-mtd.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-ncp-mtd.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-platform-utils-static.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-platform.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-radio-spinel.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-spinel-ncp.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libopenthread-spinel-rcp.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libp256m.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libsupport.a (100%) rename openthread-sys/{libs/riscv32imac-unknown-none-elf => pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs}/libtcplp-mtd.a (100%) rename openthread-sys/{src/include/riscv32imc-unknown-none-elf.rs => pre-generated/13518017024750854729/riscv32imc-unknown-none-elf/bindings.rs} (100%) rename openthread-sys/{src/include/thumbv6m-none-eabi.rs => pre-generated/13518017024750854729/thumbv6m-none-eabi/bindings.rs} (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libeverest.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libmbedcrypto.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libmbedtls.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libmbedx509.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-cli-mtd.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-hdlc.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-mtd.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-ncp-mtd.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-platform-utils-static.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-platform.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-radio-spinel.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-spinel-ncp.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libopenthread-spinel-rcp.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libp256m.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libsupport.a (100%) rename openthread-sys/{libs/thumbv6m-none-eabi => pre-generated/13518017024750854729/thumbv6m-none-eabi/libs}/libtcplp-mtd.a (100%) rename openthread-sys/{src/include/thumbv7em-none-eabi.rs => pre-generated/13518017024750854729/thumbv7em-none-eabi/bindings.rs} (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libeverest.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libmbedcrypto.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libmbedtls.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libmbedx509.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-cli-mtd.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-hdlc.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-mtd.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-ncp-mtd.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-platform-utils-static.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-platform.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-radio-spinel.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-spinel-ncp.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libopenthread-spinel-rcp.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libp256m.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libsupport.a (100%) rename openthread-sys/{libs/thumbv7em-none-eabi => pre-generated/13518017024750854729/thumbv7em-none-eabi/libs}/libtcplp-mtd.a (100%) create mode 100644 openthread-sys/pre-generated/README.md diff --git a/openthread-sys/build.rs b/openthread-sys/build.rs index afc39c0..d4a064f 100644 --- a/openthread-sys/build.rs +++ b/openthread-sys/build.rs @@ -1,15 +1,23 @@ +#![deny(unexpected_cfgs)] + use std::{env, path::PathBuf}; use anyhow::Result; +use crate::builder::OpenThreadConfig; +use crate::paths::PreGenerationPaths; + #[path = "gen/builder.rs"] mod builder; +#[path = "gen/pregen_paths.rs"] +mod paths; fn main() -> Result<()> { let crate_root_path = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); builder::OpenThreadBuilder::track(&crate_root_path.join("gen")); builder::OpenThreadBuilder::track(&crate_root_path.join("openthread")); + builder::OpenThreadBuilder::track(&crate_root_path.join("CMakeLists.txt")); // If `custom` is enabled, we need to re-build the bindings on-the-fly even if there are // pre-generated bindings for the target triple @@ -17,19 +25,18 @@ fn main() -> Result<()> { let host = env::var("HOST").unwrap(); let target = env::var("TARGET").unwrap(); - let force_esp_riscv_toolchain = env::var("CARGO_FEATURE_FORCE_ESP_RISCV_TOOLCHAIN").is_ok(); - let full_thread_device = cfg!(feature = "full-thread-device"); + let force_esp_riscv_toolchain = cfg!(feature = "force-esp-riscv-toolchain"); + + let mut openthread_config = OpenThreadConfig::default(); + set_config_from_features(&mut openthread_config); + + let force_generate_bindings = cfg!(feature = "force-generate-bindings"); + let paths = PreGenerationPaths::derive(&crate_root_path, &target, &openthread_config); - let pregen_bindings = env::var("CARGO_FEATURE_FORCE_GENERATE_BINDINGS").is_err(); - let pregen_bindings_rs_file = crate_root_path - .join("src") - .join("include") - .join(format!("{target}.rs")); - let pregen_libs_dir = crate_root_path.join("libs").join(&target); + let use_pregen_bindings = !force_generate_bindings && paths.bindings_rs_file.exists(); - let dirs = if pregen_bindings && pregen_bindings_rs_file.exists() { - // Use the pre-generated bindings - Some((pregen_bindings_rs_file, pregen_libs_dir)) + let dirs = if use_pregen_bindings { + Some((paths.bindings_rs_file, paths.libs_dir)) } else if target.ends_with("-espidf") { // Nothing to do for ESP-IDF, `esp-idf-sys` will do everything for us None @@ -45,7 +52,7 @@ fn main() -> Result<()> { None, None, force_esp_riscv_toolchain, - full_thread_device, + openthread_config, ); let libs_dir = builder.compile(&out, None)?; @@ -74,19 +81,16 @@ fn main() -> Result<()> { file_name.trim_end_matches(".lib") }; - let is_ftd_specific = lib_name.contains("-ftd"); - let is_mtd_specific = lib_name.contains("-mtd"); - let is_general = !is_ftd_specific && !is_mtd_specific; - let should_link = is_general - || (is_ftd_specific && full_thread_device) - || (is_mtd_specific && !full_thread_device); - - if should_link { - println!("cargo:rustc-link-lib=static={lib_name}"); - } + println!("cargo:rustc-link-lib=static={lib_name}"); } } } Ok(()) } + +fn set_config_from_features(config: &mut OpenThreadConfig) { + if cfg!(feature = "full-thread-device") { + config.ftd(true); + } +} diff --git a/openthread-sys/gen/builder.rs b/openthread-sys/gen/builder.rs index 36bf8a9..dd45178 100644 --- a/openthread-sys/gen/builder.rs +++ b/openthread-sys/gen/builder.rs @@ -6,6 +6,10 @@ use std::{ use anyhow::{anyhow, Result}; use bindgen::Builder; use cmake::Config; +pub use openthread_config::*; + +#[path = "./openthread_config.rs"] +mod openthread_config; pub struct OpenThreadBuilder { crate_root_path: PathBuf, @@ -13,7 +17,7 @@ pub struct OpenThreadBuilder { clang_path: Option, clang_sysroot_path: Option, clang_target: Option, - full_thread_device: bool, + openthread_config: OpenThreadConfig, } impl OpenThreadBuilder { @@ -38,7 +42,7 @@ impl OpenThreadBuilder { clang_sysroot_path: Option, clang_target: Option, force_esp_riscv_toolchain: bool, - full_thread_device: bool, + openthread_config: OpenThreadConfig, ) -> Self { Self { cmake_configurer: CMakeConfigurer::new( @@ -52,7 +56,7 @@ impl OpenThreadBuilder { clang_path, clang_sysroot_path, clang_target, - full_thread_device, + openthread_config, } } @@ -178,25 +182,11 @@ impl OpenThreadBuilder { let mut config = self.cmake_configurer.configure(Some(lib_dir)); + for (key, value) in self.openthread_config.iter() { + config.define(key, value); + } + config - .define("OT_LOG_LEVEL", "NOTE") - .define("OT_FTD", if self.full_thread_device { "ON" } else { "OFF" }) - .define("OT_MTD", if self.full_thread_device { "OFF" } else { "ON" }) - .define("OT_RCP", "OFF") - .define("OT_TCP", "OFF") - .define("OT_APP_CLI", "OFF") - .define("OT_APP_NCP", "OFF") - .define("OT_APP_RCP", "OFF") - .define("OT_BORDER_ROUTER", "OFF") - .define("OT_BORDER_ROUTING", "OFF") - .define("OT_SRP_CLIENT", "ON") - .define("OT_SLAAC", "ON") - .define("OT_ECDSA", "ON") - .define("OT_PING_SENDER", "ON") - // Do not change from here below - .define("OT_LOG_OUTPUT", "PLATFORM_DEFINED") - .define("OT_PLATFORM", "external") - .define("OT_SETTINGS_RAM", "OFF") //.define("OT_COMPILE_WARNING_AS_ERROR", "ON "$@" "${OT_SRCDIR}"") // ... or else the build would fail with `arm-none-eabi-gcc` during the linking phase // with "undefined symbol `__exit`" error diff --git a/openthread-sys/gen/openthread_config.rs b/openthread-sys/gen/openthread_config.rs new file mode 100644 index 0000000..0404bc5 --- /dev/null +++ b/openthread-sys/gen/openthread_config.rs @@ -0,0 +1,197 @@ +use std::{ + collections::{btree_map::Iter, BTreeMap}, + fmt::Display, + hash::{DefaultHasher, Hash, Hasher}, +}; + +#[derive(Clone)] +pub struct OpenThreadConfig { + config_values: BTreeMap<&'static str, &'static str>, +} + +impl OpenThreadConfig { + pub fn app_cli(&mut self, enable: bool) { + self.set_boolean("OT_APP_CLI", enable); + } + + pub fn app_ncp(&mut self, enable: bool) { + self.set_boolean("OT_APP_NCP", enable); + } + + pub fn app_rcp(&mut self, enable: bool) { + self.set_boolean("OT_APP_RCP", enable); + } + + pub fn border_router(&mut self, enable: bool) { + self.set_boolean("OT_BORDER_ROUTER", enable); + } + + pub fn border_routing(&mut self, enable: bool) { + self.set_boolean("OT_BORDER_ROUTING", enable); + } + + pub fn ecdsa(&mut self, enable: bool) { + self.set_boolean("OT_ECDSA", enable); + } + + pub fn ftd(&mut self, enable_ftd: bool) { + self.set_boolean("OT_MTD", !enable_ftd); + self.set_boolean("OT_FTD", enable_ftd); + } + + pub fn log_level(&mut self, log_level: OpenThreadLogLevel) { + use OpenThreadLogLevel::*; + + self.set_string( + "OT_LOG_LEVEL", + match log_level { + None => "NONE", + Crit => "CRIT", + Warn => "WARN", + Note => "NOTE", + Info => "INFO", + Debg => "DEBG", + }, + ); + } + + fn log_output(&mut self, log_output: OpenThreadLogOutput) { + use OpenThreadLogOutput::*; + + self.set_string( + "OT_LOG_OUTPUT", + match log_output { + App => "APP", + DebugUart => "DEBUG_UART", + None => "NONE", + PlatformDefined => "PLATFORM_DEFINED", + }, + ); + } + + pub fn ping_sender(&mut self, enable: bool) { + self.set_boolean("OT_PING_SENDER", enable); + } + + fn platform(&mut self, platform: OpenThreadPlatform) { + use OpenThreadPlatform::*; + + self.set_string( + "OT_PLATFORM", + match platform { + External => "external", + }, + ); + } + + pub fn rcp(&mut self, enable: bool) { + self.set_boolean("OT_RCP", enable); + } + + fn settings_ram(&mut self, enable: bool) { + self.set_boolean("OT_SETTINGS_RAM", enable); + } + + pub fn slaac(&mut self, enable: bool) { + self.set_boolean("OT_SLAAC", enable); + } + + pub fn srp_client(&mut self, enable: bool) { + self.set_boolean("OT_SRP_CLIENT", enable); + } + + pub fn tcp(&mut self, enable: bool) { + self.set_boolean("OT_TCP", enable); + } + + fn set_boolean(&mut self, key: &'static str, value: bool) { + self.set_string(key, if value { "ON" } else { "OFF" }); + } + + fn set_string(&mut self, key: &'static str, value: &'static str) { + self.config_values.entry(key).insert_entry(value); + } + + pub fn iter(&self) -> Iter<'_, &str, &str> { + self.config_values.iter() + } + + pub fn config_hash(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.hash(&mut hasher); + hasher.finish() + } +} + +impl Default for OpenThreadConfig { + fn default() -> Self { + let mut config = Self { + config_values: BTreeMap::new(), + }; + + config.log_level(OpenThreadLogLevel::Note); + config.ftd(false); + config.rcp(false); + config.tcp(false); + config.app_cli(false); + config.app_ncp(false); + config.app_rcp(false); + config.border_router(false); + config.border_routing(false); + config.srp_client(true); + config.slaac(true); + config.ecdsa(true); + config.ping_sender(true); + config.log_output(OpenThreadLogOutput::PlatformDefined); + config.platform(OpenThreadPlatform::External); + config.settings_ram(false); + + config + } +} + +impl Hash for OpenThreadConfig { + fn hash(&self, state: &mut H) { + for (key, value) in self.iter() { + format!("{key}={value}").hash(state); + } + } +} + +impl Display for OpenThreadConfig { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for (key, value) in self.iter() { + f.write_str(key)?; + f.write_str(" = ")?; + f.write_str(value)?; + f.write_str("\n")?; + } + + Ok(()) + } +} + +#[derive(Hash)] +#[allow(dead_code)] +pub enum OpenThreadLogLevel { + None, + Crit, + Warn, + Note, + Info, + Debg, +} + +#[derive(Hash)] +#[allow(dead_code)] +pub enum OpenThreadLogOutput { + App, + DebugUart, + None, + PlatformDefined, +} + +#[derive(Hash)] +pub enum OpenThreadPlatform { + External, +} diff --git a/openthread-sys/gen/pregen_paths.rs b/openthread-sys/gen/pregen_paths.rs new file mode 100644 index 0000000..85f05d2 --- /dev/null +++ b/openthread-sys/gen/pregen_paths.rs @@ -0,0 +1,34 @@ +use std::path::PathBuf; + +use crate::builder::OpenThreadConfig; + +pub struct PreGenerationPaths { + pub bindings_rs_file: PathBuf, + pub libs_dir: PathBuf, + pub config_summary_file: PathBuf, +} + +impl PreGenerationPaths { + pub fn derive( + crate_root_path: &PathBuf, + target: &str, + openthread_config: &OpenThreadConfig, + ) -> PreGenerationPaths { + let config_hash = openthread_config.config_hash(); + let config_based_path = crate_root_path + .join("pre-generated") + .join(format!("{config_hash}")); + + let config_summary_file = config_based_path.join("config.txt"); + + let target_based_path = config_based_path.join(target); + let bindings_rs_file = target_based_path.join("bindings.rs"); + let libs_dir = target_based_path.join("libs"); + + PreGenerationPaths { + bindings_rs_file, + libs_dir, + config_summary_file, + } + } +} diff --git a/openthread-sys/pre-generated/13518017024750854729/config.txt b/openthread-sys/pre-generated/13518017024750854729/config.txt new file mode 100644 index 0000000..a2fe73c --- /dev/null +++ b/openthread-sys/pre-generated/13518017024750854729/config.txt @@ -0,0 +1,19 @@ +This file is autogenerated and describes the config with which these bindings and libraries were pre-generated. + +OT_APP_CLI = OFF +OT_APP_NCP = OFF +OT_APP_RCP = OFF +OT_BORDER_ROUTER = OFF +OT_BORDER_ROUTING = OFF +OT_ECDSA = ON +OT_FTD = OFF +OT_LOG_LEVEL = NOTE +OT_LOG_OUTPUT = PLATFORM_DEFINED +OT_MTD = ON +OT_PING_SENDER = ON +OT_PLATFORM = external +OT_RCP = OFF +OT_SETTINGS_RAM = OFF +OT_SLAAC = ON +OT_SRP_CLIENT = ON +OT_TCP = OFF diff --git a/openthread-sys/src/include/riscv32imac-unknown-none-elf.rs b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/bindings.rs similarity index 100% rename from openthread-sys/src/include/riscv32imac-unknown-none-elf.rs rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/bindings.rs diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libeverest.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libeverest.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libeverest.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libeverest.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libmbedcrypto.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libmbedcrypto.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libmbedcrypto.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libmbedcrypto.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libmbedtls.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libmbedtls.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libmbedtls.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libmbedtls.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libmbedx509.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libmbedx509.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libmbedx509.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libmbedx509.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-cli-mtd.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-cli-mtd.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-cli-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-cli-mtd.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-hdlc.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-hdlc.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-hdlc.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-hdlc.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-mtd.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-mtd.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-mtd.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-ncp-mtd.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-ncp-mtd.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-ncp-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-ncp-mtd.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-platform-utils-static.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-platform-utils-static.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-platform-utils-static.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-platform-utils-static.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-platform.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-platform.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-platform.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-platform.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-radio-spinel.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-radio-spinel.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-radio-spinel.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-radio-spinel.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-spinel-ncp.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-spinel-ncp.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-spinel-ncp.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-spinel-ncp.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-spinel-rcp.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-spinel-rcp.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libopenthread-spinel-rcp.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libopenthread-spinel-rcp.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libp256m.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libp256m.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libp256m.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libp256m.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libsupport.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libsupport.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libsupport.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libsupport.a diff --git a/openthread-sys/libs/riscv32imac-unknown-none-elf/libtcplp-mtd.a b/openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libtcplp-mtd.a similarity index 100% rename from openthread-sys/libs/riscv32imac-unknown-none-elf/libtcplp-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/riscv32imac-unknown-none-elf/libs/libtcplp-mtd.a diff --git a/openthread-sys/src/include/riscv32imc-unknown-none-elf.rs b/openthread-sys/pre-generated/13518017024750854729/riscv32imc-unknown-none-elf/bindings.rs similarity index 100% rename from openthread-sys/src/include/riscv32imc-unknown-none-elf.rs rename to openthread-sys/pre-generated/13518017024750854729/riscv32imc-unknown-none-elf/bindings.rs diff --git a/openthread-sys/src/include/thumbv6m-none-eabi.rs b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/bindings.rs similarity index 100% rename from openthread-sys/src/include/thumbv6m-none-eabi.rs rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/bindings.rs diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libeverest.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libeverest.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libeverest.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libeverest.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libmbedcrypto.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libmbedcrypto.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libmbedcrypto.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libmbedcrypto.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libmbedtls.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libmbedtls.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libmbedtls.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libmbedtls.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libmbedx509.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libmbedx509.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libmbedx509.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libmbedx509.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-cli-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-cli-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-cli-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-cli-mtd.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-hdlc.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-hdlc.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-hdlc.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-hdlc.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-mtd.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-ncp-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-ncp-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-ncp-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-ncp-mtd.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-platform-utils-static.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-platform-utils-static.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-platform-utils-static.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-platform-utils-static.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-platform.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-platform.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-platform.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-platform.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-radio-spinel.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-radio-spinel.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-radio-spinel.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-radio-spinel.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-spinel-ncp.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-spinel-ncp.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-spinel-ncp.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-spinel-ncp.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libopenthread-spinel-rcp.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-spinel-rcp.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libopenthread-spinel-rcp.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libopenthread-spinel-rcp.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libp256m.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libp256m.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libp256m.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libp256m.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libsupport.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libsupport.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libsupport.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libsupport.a diff --git a/openthread-sys/libs/thumbv6m-none-eabi/libtcplp-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libtcplp-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv6m-none-eabi/libtcplp-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv6m-none-eabi/libs/libtcplp-mtd.a diff --git a/openthread-sys/src/include/thumbv7em-none-eabi.rs b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/bindings.rs similarity index 100% rename from openthread-sys/src/include/thumbv7em-none-eabi.rs rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/bindings.rs diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libeverest.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libeverest.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libeverest.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libeverest.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libmbedcrypto.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libmbedcrypto.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libmbedcrypto.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libmbedcrypto.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libmbedtls.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libmbedtls.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libmbedtls.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libmbedtls.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libmbedx509.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libmbedx509.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libmbedx509.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libmbedx509.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-cli-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-cli-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-cli-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-cli-mtd.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-hdlc.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-hdlc.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-hdlc.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-hdlc.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-mtd.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-ncp-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-ncp-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-ncp-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-ncp-mtd.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-platform-utils-static.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-platform-utils-static.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-platform-utils-static.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-platform-utils-static.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-platform.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-platform.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-platform.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-platform.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-radio-spinel.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-radio-spinel.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-radio-spinel.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-radio-spinel.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-spinel-ncp.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-spinel-ncp.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-spinel-ncp.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-spinel-ncp.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libopenthread-spinel-rcp.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-spinel-rcp.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libopenthread-spinel-rcp.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libopenthread-spinel-rcp.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libp256m.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libp256m.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libp256m.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libp256m.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libsupport.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libsupport.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libsupport.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libsupport.a diff --git a/openthread-sys/libs/thumbv7em-none-eabi/libtcplp-mtd.a b/openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libtcplp-mtd.a similarity index 100% rename from openthread-sys/libs/thumbv7em-none-eabi/libtcplp-mtd.a rename to openthread-sys/pre-generated/13518017024750854729/thumbv7em-none-eabi/libs/libtcplp-mtd.a diff --git a/openthread-sys/pre-generated/README.md b/openthread-sys/pre-generated/README.md new file mode 100644 index 0000000..d78ebb4 --- /dev/null +++ b/openthread-sys/pre-generated/README.md @@ -0,0 +1,19 @@ +## Folder structure: +``` +pre-generated/ + {config_hash}/ + {target}/ + config.txt + bindings.rs + libs/ + *.a +``` + +## config_hash +The config hash is derived from the configuration values passed into the build of OpenThread, which in turn is derived from feature flags in this openthread-sys crate. + +## target +This is the target of the build, ie. `riscv32-imac-unknown-none-elf` + +## config.txt +Contains the flags that were passed into CMake during the pre-generation diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 85f71be..3f51e73 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,5 +1,5 @@ -use std::env; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use std::{env, fs}; use anyhow::Result; @@ -9,8 +9,12 @@ use log::LevelFilter; use tempdir::TempDir; +use paths::PreGenerationPaths; + #[path = "../../openthread-sys/gen/builder.rs"] mod builder; +#[path = "../../openthread-sys/gen/pregen_paths.rs"] +mod paths; // Arguments #[derive(Parser, Debug)] @@ -30,10 +34,6 @@ enum Commands { #[arg(short = 'e', long)] force_esp_riscv_toolchain: bool, - /// If specified, builds OpenThread as a Full Thread Device (FTD), otherwise builds as a Minimal Thread Device (MTD) - #[arg(long)] - full_thread_device: bool, - /// Target triple for which to generate bindings and `.a` libraries target: String, }, @@ -56,9 +56,11 @@ fn main() -> Result<()> { if let Some(Commands::Gen { target, force_esp_riscv_toolchain, - full_thread_device, }) = args.command { + let openthread_config = builder::OpenThreadConfig::default(); + let paths = PreGenerationPaths::derive(&sys_crate_root_path, &target, &openthread_config); + let builder = builder::OpenThreadBuilder::new( sys_crate_root_path.clone(), Some(target.clone()), @@ -68,28 +70,26 @@ fn main() -> Result<()> { None, None, force_esp_riscv_toolchain, - full_thread_device, + openthread_config.clone(), ); let out = TempDir::new("openthread-sys-libs")?; - - builder.compile( - out.path(), - Some(&sys_crate_root_path.join("libs").join(&target)), - )?; + builder.compile(out.path(), Some(&paths.libs_dir))?; let out = TempDir::new("openthread-sys-bindings")?; + builder.generate_bindings(out.path(), Some(&paths.bindings_rs_file))?; - builder.generate_bindings( - out.path(), - Some( - &sys_crate_root_path - .join("src") - .join("include") - .join(format!("{target}.rs")), - ), - )?; + write_config_summary(&paths.config_summary_file, &openthread_config)?; } Ok(()) } + +fn write_config_summary(path: &Path, openthread_config: &builder::OpenThreadConfig) -> Result<()> { + log::info!("Writing out OpenThread build config to {path:?}"); + + let header = "This file is autogenerated and describes the config with which these bindings and libraries were pre-generated."; + fs::write(path, format!("{header}\n\n{openthread_config}"))?; + + Ok(()) +} From 068218fffea2a07adbee68487fc4d37bfee48ae7 Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Tue, 6 Jan 2026 00:10:38 +0000 Subject: [PATCH 4/5] switch CI workflow to stable Rust --- .github/workflows/rust_ci.yml | 2 +- examples/esp/rust-toolchain.toml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/rust_ci.yml b/.github/workflows/rust_ci.yml index 3bcf561..05487b8 100644 --- a/.github/workflows/rust_ci.yml +++ b/.github/workflows/rust_ci.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: env: - rust_toolchain: nightly + rust_toolchain: stable GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: diff --git a/examples/esp/rust-toolchain.toml b/examples/esp/rust-toolchain.toml index 2ad5ec3..80666ec 100644 --- a/examples/esp/rust-toolchain.toml +++ b/examples/esp/rust-toolchain.toml @@ -1,5 +1,3 @@ [toolchain] -channel = "nightly" components = ["rust-src"] targets = ["riscv32imac-unknown-none-elf"] - From be4089159d43a771f36f6fb6a79e97ab5f8f65ef Mon Sep 17 00:00:00 2001 From: Matthew Smith Date: Wed, 7 Jan 2026 13:28:04 +0000 Subject: [PATCH 5/5] enhance the readme with tips on acquiring the gnu riscv toolchain --- README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d16c08f..08b9409 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Two IEEE 802.15.4 radios are supported out of the box: ## Build -For certain MCUs / Rust targets, the OpenThread libraries are pre-compiled for convenience. +For certain MCUs / Rust targets, the OpenThread libraries are pre-compiled with a commonly used set of defaults for convenience. The defaults allow running a minimal thread device (MTD) that registers services using SRP. Current list (might be extended upon request): - `riscv32imac-unknown-none-elf` (ESP32C6 and ESP32H2) - `thumbv7em-none-eabi` (NRF52) @@ -30,7 +30,7 @@ Small caveat: since `openthread` does a few calls into the C standard library (p ### Build for other targets / custom build -For targets where pre-compiled libs are not available (including for the Host itself), a standard `build.rs` build is also supported. +For targets where pre-compiled libs are not available (including for the Host itself), or for when additional OpenThread features beyond the defaults are desired, a standard `build.rs` build is also supported. For the on-the-fly OpenThread CMake build to work, you'll need to install and set in your `$PATH`: - The GCC toolchain correspponding to your Rust target, with **working** `foo-bar-gcc -print-sysroot` command - Recent Clang (for Espressif `xtensa`, [it must be the Espressif fork](https://crates.io/crates/espup), but for all other chips, the stock Clang would work) @@ -41,10 +41,23 @@ As per above, since `openthread` does a few calls into the C standard library (p Examples of GCC toolchains that are known to work fine: - For ARM (Cortex M CPUs and others) - the [ARM GNU toolchain](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain); - Note that the Ubuntu `arm-none-eabi-gcc` system package does **NOT** work, as it does not print a sysroot, i.e. `arm-none-eabi-gcc -print-sysroot` returns an empty response, and furthermore, the `newlib` headers are installed in a separate location from the arch headers; -- For RISCV - the [Espressif RISCV toolchain](https://github.com/espressif/crosstool-NG/releases). The ["official" RISCV GNU toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) should also work; +- For RISCV - the [Espressif RISCV toolchain](https://github.com/espressif/crosstool-NG/releases). The ["official" RISCV GNU toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) should also work (see below for guidance on building this); - For xtensa (Espressif ESP32 and ESP32SXX MCUs) - the [Espressif xtensa toolchain](https://github.com/espressif/crosstool-NG/releases); - For the Host machine (non-embedded) - your pre-installed toolchain would work just fine. +### Compiling the RISCV GNU Toolchain +As above, the requirements are for the toolchain to have `newlib`, so `--disable-linux` must be specified. For the `riscv32imac-unknown-none-elf` target (ESP32-C6 and ESP32-H2), the following options will produce a usable build: +``` +./configure --prefix=/opt/riscv --with-arch=rv32imac --with-abi=ilp32 --disable-linux +make +``` + +Don't forget to include the resulting binaries in your path: +``` +export PATH=$PATH:/opt/riscv/bin +``` + + ## Features - MTD (Minimal Thread Device) functionality