summaryrefslogtreecommitdiff
path: root/components/rust/core
diff options
context:
space:
mode:
authoryan hu <[email protected]>2026-08-07 18:05:09 +0800
committerRbb666 <[email protected]>2026-08-21 11:17:57 +0800
commit30af7388a4077354f6083082fee040595978bbac (patch)
treedfa0440a884847ff7d803bb3113dd3f9f916f74b /components/rust/core
parent339bffb702b911b55b0e6d54fa5ad9116295f048 (diff)
[rust][tools] Fix Rust build example configuration handling
Improve the Rust build integration across core, applications, components, and module examples. Fix build failure propagation, target and feature handling, linker flags, example configuration semantics, and add STM32 CI attach coverage.
Diffstat (limited to 'components/rust/core')
-rw-r--r--components/rust/core/Cargo.toml11
-rw-r--r--components/rust/core/SConscript88
-rw-r--r--components/rust/core/src/api/mod.rs2
-rw-r--r--components/rust/core/src/api/queue.rs11
-rw-r--r--components/rust/core/src/bindings/librt.rs3
-rw-r--r--components/rust/core/src/bindings/mod.rs3
-rw-r--r--components/rust/core/src/fs.rs2
-rw-r--r--components/rust/core/src/lib.rs3
8 files changed, 95 insertions, 28 deletions
diff --git a/components/rust/core/Cargo.toml b/components/rust/core/Cargo.toml
index 4a4a0687df..482b307b23 100644
--- a/components/rust/core/Cargo.toml
+++ b/components/rust/core/Cargo.toml
@@ -10,6 +10,17 @@ crate-type = ["rlib", "staticlib"]
[features]
default = []
smp = []
+fs = []
+libdl = []
+
+[package.metadata.rt-thread.features.smp]
+all = ["RT_USING_SMP"]
+
+[package.metadata.rt-thread.features.fs]
+all = ["RT_USING_DFS", "DFS_USING_POSIX"]
+
+[package.metadata.rt-thread.features.libdl]
+all = ["RT_USING_MODULE"]
[profile.dev]
panic = "abort"
diff --git a/components/rust/core/SConscript b/components/rust/core/SConscript
index 880f6bce92..dd42fbebbf 100644
--- a/components/rust/core/SConscript
+++ b/components/rust/core/SConscript
@@ -1,5 +1,7 @@
import os
+import sys
from building import *
+from SCons.Subst import quote_spaces
cwd = GetCurrentDir()
@@ -7,10 +9,12 @@ sys.path.append(os.path.join(cwd, '../tools'))
from build_support import (
detect_rust_target,
make_rustflags,
+ make_cargo_build_std_args,
collect_features,
verify_rust_toolchain,
ensure_rust_target_installed,
cargo_build_staticlib,
+ get_staticlib_link_name,
clean_rust_build,
)
def _has(sym: str) -> bool:
@@ -20,10 +24,28 @@ def _has(sym: str) -> bool:
return bool(GetDepend(sym))
-# Source files – MSH command glue
-src = ['rust_cmd.c']
+group = []
+if not _has('RT_RUST_CORE') and not GetOption('clean'):
+ Return('group')
+
+
+def get_staticlib_link_name_from_artifact(lib_path):
+ """Derive the link name from the actual staticlib artifact file name."""
+ artifact_name = os.path.basename(os.fspath(lib_path))
+ if artifact_name.startswith("lib") and artifact_name.endswith(".a"):
+ return artifact_name[3:-2]
+ return None
+
+
+# Source files – MSH command glue.
+# rust_cmd.c references rust_init(), which is only provided by the Rust core
+# static library. It must only enter the build when that library is actually
+# produced; otherwise the C link stage fails with 'undefined reference to
+# rust_init' instead of failing/skipping cleanly at the Rust build step.
LIBS = []
LIBPATH = []
+LINKFLAGS = ""
+include_rust_cmd = False
if GetOption('clean'):
# Register Rust artifacts for cleaning
@@ -33,39 +55,65 @@ if GetOption('clean'):
Clean('.', rust_build_dir)
else:
print('No rust build artifacts to clean')
+ # Keep rust_cmd.c in the group during clean so its object is cleaned too.
+ include_rust_cmd = True
else:
if verify_rust_toolchain():
import rtconfig
+ rust_build_dir = clean_rust_build(Dir('#').abspath)
target = detect_rust_target(_has, rtconfig)
if not target:
print('Error: Unable to detect Rust target; please check configuration')
+ sys.exit(1)
else:
print(f'Detected Rust target: {target}')
# Optional hint if target missing
- ensure_rust_target_installed(target)
-
- # Build mode and features
- debug = bool(_has('RUST_DEBUG_BUILD'))
- features = collect_features(_has)
+ if not ensure_rust_target_installed(target):
+ print('Error: Rust target is not installed; Rust library build failed')
+ sys.exit(1)
+ else:
+ # Build mode and features
+ debug = bool(_has('RUST_DEBUG_BUILD'))
+ features = collect_features(_has)
- rustflags = make_rustflags(rtconfig, target)
- rust_lib = cargo_build_staticlib(
- rust_dir=cwd, target=target, features=features, debug=debug, rustflags=rustflags
- )
+ rustflags = make_rustflags(rtconfig, target)
+ cargo_extra_args = make_cargo_build_std_args(rtconfig, target)
+ rust_lib = cargo_build_staticlib(
+ rust_dir=cwd, target=target, features=features, debug=debug, rustflags=rustflags, build_root=rust_build_dir, cargo_extra_args=cargo_extra_args
+ )
- if rust_lib:
- LIBS = ['rt_rust']
- LIBPATH = [os.path.dirname(rust_lib)]
- print('Rust library linked successfully')
- else:
- print('Warning: Failed to build Rust library')
+ if rust_lib:
+ # Derive the link name from the actual artifact so it always
+ # matches the file that was built. Only fall back to
+ # re-parsing Cargo.toml when the artifact name does not
+ # follow the lib<name>.a convention.
+ link_lib_name = get_staticlib_link_name_from_artifact(rust_lib)
+ if not link_lib_name:
+ link_lib_name = get_staticlib_link_name(cwd)
+ LIBS = [link_lib_name]
+ LIBPATH = [os.path.dirname(rust_lib)]
+ if rtconfig.PLATFORM == 'armclang':
+ if not (os.path.isfile(rust_lib) and os.path.getsize(rust_lib) > 0):
+ print(f'Error: ArmClang Rust core link requires a non-empty archive, but got: {rust_lib}')
+ sys.exit(1)
+ LINKFLAGS = " " + quote_spaces(os.fspath(rust_lib))
+ LIBS = []
+ LIBPATH = []
+ include_rust_cmd = True
+ print('Rust library linked successfully')
+ else:
+ print('Error: Failed to build Rust library')
+ sys.exit(1)
else:
- print('Warning: Rust toolchain not found')
+ print('Error: Rust toolchain not found')
print('Please install Rust from https://rustup.rs')
+ sys.exit(1)
-# Define component group for SCons
-group = DefineGroup('rust', src, depend=['RT_USING_RUST'], LIBS=LIBS, LIBPATH=LIBPATH)
+# Only define the component group (with rust_cmd.c) when the Rust core static
+# library was actually produced, so its rust_init() reference always resolves.
+if include_rust_cmd:
+ group = DefineGroup('rust', ['rust_cmd.c'], depend=['RT_USING_RUST', 'RT_RUST_CORE'], LIBS=LIBS, LIBPATH=LIBPATH, LINKFLAGS=LINKFLAGS)
Return('group')
diff --git a/components/rust/core/src/api/mod.rs b/components/rust/core/src/api/mod.rs
index 8fc2ba2301..cf3d0bbc0c 100644
--- a/components/rust/core/src/api/mod.rs
+++ b/components/rust/core/src/api/mod.rs
@@ -14,6 +14,7 @@ pub mod thread;
pub mod mutex;
pub mod sem;
pub mod queue;
+#[cfg(feature = "libdl")]
pub mod libloading;
@@ -24,4 +25,5 @@ pub use thread::*;
pub use mutex::*;
pub use sem::*;
pub use queue::*;
+#[cfg(feature = "libdl")]
pub use libloading::*;
diff --git a/components/rust/core/src/api/queue.rs b/components/rust/core/src/api/queue.rs
index 96665e47f2..8a77374b90 100644
--- a/components/rust/core/src/api/queue.rs
+++ b/components/rust/core/src/api/queue.rs
@@ -20,7 +20,7 @@ pub type APIRawQueue = rt_mq_t;
pub(crate) fn queue_create(name: &str, len: u64, message_size: u64) -> Option<APIRawQueue> {
let s = CString::new(name).unwrap();
let raw;
- unsafe { raw = rt_mq_create(s.as_ptr(), message_size, len, 0) }
+ unsafe { raw = rt_mq_create(s.as_ptr(), message_size as rt_size_t, len as rt_size_t, 0) }
if raw == ptr::null_mut() {
None
} else {
@@ -35,7 +35,7 @@ pub(crate) fn queue_send_wait(
msg_size: u64,
tick: i32,
) -> RttCResult {
- unsafe { rt_mq_send_wait(handle, msg, msg_size, tick).into() }
+ unsafe { rt_mq_send_wait(handle, msg, msg_size as rt_size_t, tick).into() }
}
#[inline]
@@ -45,7 +45,12 @@ pub(crate) fn queue_receive_wait(
msg_size: u64,
tick: i32,
) -> RttCResult {
- unsafe { rt_mq_recv(handle, msg, msg_size, tick).into() }
+ let ret = unsafe { rt_mq_recv(handle, msg, msg_size as rt_size_t, tick) };
+ if ret >= 0 {
+ RttCResult::Ok
+ } else {
+ ret.into()
+ }
}
#[inline]
diff --git a/components/rust/core/src/bindings/librt.rs b/components/rust/core/src/bindings/librt.rs
index 3f16c014fd..a39ed07c22 100644
--- a/components/rust/core/src/bindings/librt.rs
+++ b/components/rust/core/src/bindings/librt.rs
@@ -26,6 +26,7 @@ pub type rt_int32_t = c_int;
pub type rt_uint8_t = c_uchar;
pub type rt_tick_t = rt_uint32_t;
pub type rt_size_t = rt_ubase_t;
+pub type rt_ssize_t = rt_base_t;
pub type rt_thread_t = *mut c_void;
pub type rt_sem_t = *mut c_void;
@@ -94,7 +95,7 @@ unsafe extern "C" {
pub fn rt_mq_create(name: *const c_char, msg_size: rt_size_t, max_msgs: rt_size_t, flag: rt_uint8_t) -> rt_mq_t;
pub fn rt_mq_send(mq: rt_mq_t, buffer: *const c_void, size: rt_size_t) -> rt_err_t;
pub fn rt_mq_send_wait(mq: rt_mq_t, buffer: *const c_void, size: rt_size_t, timeout: rt_int32_t) -> rt_err_t;
- pub fn rt_mq_recv(mq: rt_mq_t, buffer: *mut c_void, size: rt_size_t, timeout: rt_int32_t) -> rt_base_t;
+ pub fn rt_mq_recv(mq: rt_mq_t, buffer: *mut c_void, size: rt_size_t, timeout: rt_int32_t) -> rt_ssize_t;
pub fn rt_mq_delete(mq: rt_mq_t) -> rt_err_t;
pub fn rt_mq_detach(mq: rt_mq_t) -> rt_err_t;
}
diff --git a/components/rust/core/src/bindings/mod.rs b/components/rust/core/src/bindings/mod.rs
index ae2610e9c8..cad651a1dd 100644
--- a/components/rust/core/src/bindings/mod.rs
+++ b/components/rust/core/src/bindings/mod.rs
@@ -46,8 +46,7 @@ pub use librt::{
/* Memory management functions */
pub use librt::{
- rt_malloc, rt_free, rt_realloc, rt_calloc, rt_malloc_align, rt_free_align,
- rt_safe_malloc, rt_safe_free
+ rt_malloc, rt_free, rt_realloc, rt_calloc, rt_malloc_align, rt_free_align
};
/* Device management functions */
diff --git a/components/rust/core/src/fs.rs b/components/rust/core/src/fs.rs
index 6ad02037ab..9a8d1afa8d 100644
--- a/components/rust/core/src/fs.rs
+++ b/components/rust/core/src/fs.rs
@@ -98,7 +98,7 @@ impl File {
pub fn seek(&self, offset: i64) -> RTResult<i64> {
let n = unsafe { libc::lseek(self.fd, offset as libc::off_t, libc::SEEK_SET) };
- if n < 0 { Err(FileSeekErr) } else { Ok(n) }
+ if n < 0 { Err(FileSeekErr) } else { Ok(n.into()) }
}
pub fn flush(&self) -> RTResult<()> {
diff --git a/components/rust/core/src/lib.rs b/components/rust/core/src/lib.rs
index 01e4b34102..0b94f81427 100644
--- a/components/rust/core/src/lib.rs
+++ b/components/rust/core/src/lib.rs
@@ -17,7 +17,6 @@ and device interfaces. Designed for embedded devices running RT-Thread.
*/
#![no_std]
-#![feature(alloc_error_handler)]
#![feature(linkage)]
#![allow(dead_code)]
@@ -33,6 +32,7 @@ pub mod init;
pub mod allocator;
pub mod mutex;
pub mod out;
+#[cfg(feature = "fs")]
pub mod fs;
pub mod panic;
pub mod param;
@@ -40,6 +40,7 @@ pub mod queue;
pub mod sem;
pub mod thread;
pub mod time;
+#[cfg(feature = "libdl")]
pub mod libloader;
mod prelude;