From 99a2aa71128f8419291254662beccc69a3289527 Mon Sep 17 00:00:00 2001 From: Shoji Tokunaga Date: Mon, 15 Jun 2026 17:28:54 +0900 Subject: [PATCH] examples/rust: Avoid the infinite loop on sim for hello_rust_cargo On the sim target (Windows/macOS/Linux), hello_rust_cargo_main() ended with an infinite `loop {}` that never returned control to NSH, so the example could not exit and the shell prompt hung. Introduce a Cargo `sim` feature that is enabled only when CONFIG_ARCH_SIM is set, and use it to compile out the trailing infinite loop and return 0 instead. Other embedded targets keep the original looping behavior. Signed-off-by: Shoji Tokunaga --- cmake/nuttx_add_rust.cmake | 10 +++++++++- examples/rust/hello/CMakeLists.txt | 7 ++++++- examples/rust/hello/Cargo.toml | 3 +++ examples/rust/hello/Makefile | 6 +++++- examples/rust/hello/src/lib.rs | 7 ++++++- tools/Rust.mk | 9 ++++++--- 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/cmake/nuttx_add_rust.cmake b/cmake/nuttx_add_rust.cmake index 54b17255bb0..cfc527b9bac 100644 --- a/cmake/nuttx_add_rust.cmake +++ b/cmake/nuttx_add_rust.cmake @@ -130,6 +130,8 @@ endfunction() # hello # CRATE_PATH # ${CMAKE_CURRENT_SOURCE_DIR}/hello +# FEATURES +# sim # ) # ~~~ @@ -142,6 +144,8 @@ function(nuttx_add_rust) ONE_VALUE CRATE_NAME CRATE_PATH + MULTI_VALUE + FEATURES REQUIRED CRATE_NAME CRATE_PATH @@ -159,6 +163,10 @@ function(nuttx_add_rust) set(RUST_PANIC_FLAGS "") endif() + foreach(feature ${FEATURES}) + list(APPEND RUST_FEATURE_FLAGS --features ${feature}) + endforeach() + # Get the Rust target triple nuttx_rust_target_triple(${LLVM_ARCHTYPE} ${LLVM_ABITYPE} ${LLVM_CPUTYPE} RUST_TARGET) @@ -198,7 +206,7 @@ function(nuttx_add_rust) RUSTFLAGS=${RUST_PANIC_FLAGS} cargo build ${RUST_PROFILE_FLAG} -Zbuild-std=std,panic_abort -Zjson-target-spec --manifest-path ${CRATE_PATH}/Cargo.toml --target ${RUST_TARGET} --target-dir - ${RUST_BUILD_DIR} + ${RUST_BUILD_DIR} ${RUST_FEATURE_FLAGS} DEPENDS ${RUST_CRATE_SOURCES} COMMENT "Building Rust crate ${CRATE_NAME}" VERBATIM) diff --git a/examples/rust/hello/CMakeLists.txt b/examples/rust/hello/CMakeLists.txt index 2a83be84e16..b84e0234a77 100644 --- a/examples/rust/hello/CMakeLists.txt +++ b/examples/rust/hello/CMakeLists.txt @@ -21,7 +21,12 @@ if(CONFIG_EXAMPLES_HELLO_RUST_CARGO) # Build the Rust crate using nuttx_add_rust - nuttx_add_rust(CRATE_NAME hello CRATE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + if(CONFIG_ARCH_SIM) + nuttx_add_rust(CRATE_NAME hello CRATE_PATH ${CMAKE_CURRENT_SOURCE_DIR} + FEATURES sim) + else() + nuttx_add_rust(CRATE_NAME hello CRATE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + endif() nuttx_add_application( NAME ${CONFIG_EXAMPLES_HELLO_RUST_CARGO_PROGNAME} STACKSIZE diff --git a/examples/rust/hello/Cargo.toml b/examples/rust/hello/Cargo.toml index 0741516b909..d5872893405 100644 --- a/examples/rust/hello/Cargo.toml +++ b/examples/rust/hello/Cargo.toml @@ -6,6 +6,9 @@ edition = "2021" [lib] crate-type = ["staticlib"] +[features] +sim = [] + [profile.dev] panic = "abort" diff --git a/examples/rust/hello/Makefile b/examples/rust/hello/Makefile index c5af986713a..0e1b534c45a 100644 --- a/examples/rust/hello/Makefile +++ b/examples/rust/hello/Makefile @@ -30,8 +30,12 @@ MODULE = $(CONFIG_EXAMPLES_HELLO_RUST_CARGO) RUST_LIB := $(call RUST_GET_BINDIR,hello,$(APPDIR)/examples/rust) RUST_SRCS := $(call RUST_CARGO_SRCS,hello,$(APPDIR)/examples/rust) +ifeq ($(CONFIG_ARCH_SIM),y) +HELLO_RUST_FEATURES := sim +endif + $(RUST_LIB): $(RUST_SRCS) - $(call RUST_CARGO_BUILD,hello,$(APPDIR)/examples/rust) + $(call RUST_CARGO_BUILD,hello,$(APPDIR)/examples/rust,$(HELLO_RUST_FEATURES)) context:: $(RUST_LIB) diff --git a/examples/rust/hello/src/lib.rs b/examples/rust/hello/src/lib.rs index f50cf5bc5c3..dbe71ca0e16 100644 --- a/examples/rust/hello/src/lib.rs +++ b/examples/rust/hello/src/lib.rs @@ -1,6 +1,7 @@ extern crate serde; extern crate serde_json; +use core::ffi::{c_char, c_int}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] @@ -11,7 +12,7 @@ struct Person { // Function hello_rust_cargo without manglng #[no_mangle] -pub extern "C" fn hello_rust_cargo_main() { +pub extern "C" fn hello_rust_cargo_main(_argc: c_int, _argv: *mut *mut c_char) -> c_int { // Print hello world to stdout let john = Person { @@ -50,7 +51,11 @@ pub extern "C" fn hello_rust_cargo_main() { println!("Hello world from tokio!"); }); + #[cfg(not(feature = "sim"))] loop { // Do nothing } + + #[cfg(feature = "sim")] + 0 } diff --git a/tools/Rust.mk b/tools/Rust.mk index 06b65f7c5ba..722c623802b 100644 --- a/tools/Rust.mk +++ b/tools/Rust.mk @@ -90,11 +90,12 @@ endef # Build Rust project using cargo # -# Usage: $(call RUST_CARGO_BUILD,cratename,prefix) +# Usage: $(call RUST_CARGO_BUILD,cratename,prefix[,features]) # # Inputs: # cratename - Name of the Rust crate (e.g. hello) # prefix - Path prefix to the crate (e.g. path/to/project) +# features - Optional Cargo features to enable # # Output: # None, builds the Rust project @@ -105,7 +106,8 @@ define RUST_CARGO_BUILD RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" \ cargo build --release -Zbuild-std=std,panic_abort -Zjson-target-spec \ --manifest-path $(2)/$(1)/Cargo.toml \ - --target $(call RUST_TARGET_TRIPLE) + --target $(call RUST_TARGET_TRIPLE) \ + $(if $(strip $(3)),--features $(3),) endef else define RUST_CARGO_BUILD @@ -113,7 +115,8 @@ define RUST_CARGO_BUILD NUTTX_INCLUDE_DIR=$(TOPDIR)/include:$(TOPDIR)/include/arch \ cargo build -Zbuild-std=std,panic_abort -Zjson-target-spec \ --manifest-path $(2)/$(1)/Cargo.toml \ - --target $(call RUST_TARGET_TRIPLE) + --target $(call RUST_TARGET_TRIPLE) \ + $(if $(strip $(3)),--features $(3),) endef endif