Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8f32c4e
Fix Rust build example configuration handling
yanhu7150-tech Jul 7, 2026
f89e400
Add Rust build CI attach config
yanhu7150-tech Jul 9, 2026
a05282c
Fix Rust attach build failures
yanhu7150-tech Jul 9, 2026
5d38245
Fix Rust build failure propagation
yanhu7150-tech Jul 10, 2026
fb9252b
Fix Rust link flags for GCC and ArmClang
yanhu7150-tech Jul 10, 2026
75310a8
Fix Rust component anchor configuration
yanhu7150-tech Jul 10, 2026
fc87fc7
Fix ArmClang Rust core archive linking
yanhu7150-tech Jul 10, 2026
269212f
Fail closed on component feature parsing
yanhu7150-tech Jul 10, 2026
53a4e0c
Gate Rust optional APIs by configuration
yanhu7150-tech Jul 13, 2026
49869b5
Refine Rust fs feature condition
yanhu7150-tech Jul 13, 2026
076f21c
Make Rust core feature mapping declarative
yanhu7150-tech Jul 14, 2026
1d59a52
Merge origin/master into bugfix-rust-build-target-artifact
yanhu7150-tech Jul 16, 2026
6f86c79
Fix Rust core cleanup when disabled
yanhu7150-tech Jul 18, 2026
537b128
Merge remote-tracking branch 'origin/master' into bugfix-rust-build-t…
yanhu7150-tech Jul 22, 2026
33479c1
Fix top-level Rust cleanup when disabled
yanhu7150-tech Jul 22, 2026
cf128c8
Fix Rust example cleanup and remove M85 mapping
yanhu7150-tech Jul 23, 2026
425b779
Add Rust application CI and narrow module scope
yanhu7150-tech Jul 23, 2026
7a097ec
Fix Rust queue receive result handling
yanhu7150-tech Jul 28, 2026
795f63f
[rust][examples] Fix module example build configuration
yanhu7150-tech Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,25 @@ component.cherryusb_cdc:
- CONFIG_RT_CHERRYUSB_DEVICE_DWC2_ST=y
- CONFIG_RT_CHERRYUSB_DEVICE_CDC_ACM=y
- CONFIG_RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM=y
# ------ rust CI ------
Comment thread
yanhu7150-tech marked this conversation as resolved.
rust:
Comment thread
yanhu7150-tech marked this conversation as resolved.
<<: *scons
pre_build: |
python3 -m pip install --user toml
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly --profile minimal
sudo ln -sf "$HOME/.cargo/bin/cargo" /usr/local/bin/cargo
sudo ln -sf "$HOME/.cargo/bin/rustc" /usr/local/bin/rustc
sudo ln -sf "$HOME/.cargo/bin/rustup" /usr/local/bin/rustup
rustup target add thumbv7em-none-eabihf
rustc --version
cargo --version
kconfig:
- CONFIG_RT_USING_RUST=y
- CONFIG_RT_RUST_CORE=y
- CONFIG_RT_USING_RUST_EXAMPLES=y
- CONFIG_RT_RUST_BUILD_APPLICATIONS=y
- CONFIG_RT_RUST_BUILD_COMPONENTS=y
- CONFIG_RUST_LOG_COMPONENT=y

devices.soft_i2c:
<<: *scons
Expand Down
2 changes: 1 addition & 1 deletion components/rust/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def _has(sym: str) -> bool:
except Exception:
return bool(GetDepend(sym))

if not _has('RT_USING_RUST'):
if not _has('RT_USING_RUST') and not GetOption('clean'):
Return('objs')

cwd = GetCurrentDir()
Expand Down
11 changes: 11 additions & 0 deletions components/rust/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Comment thread
yanhu7150-tech marked this conversation as resolved.

[profile.dev]
panic = "abort"
Expand Down
86 changes: 66 additions & 20 deletions components/rust/core/SConscript
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import os
import sys
from building import *
from SCons.Subst import quote_spaces

cwd = GetCurrentDir()

Expand All @@ -11,6 +13,7 @@ from build_support import (
verify_rust_toolchain,
ensure_rust_target_installed,
cargo_build_staticlib,
get_staticlib_link_name,
clean_rust_build,
)
def _has(sym: str) -> bool:
Expand All @@ -20,10 +23,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
Expand All @@ -33,39 +54,64 @@ 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)
rust_lib = cargo_build_staticlib(
rust_dir=cwd, target=target, features=features, debug=debug, rustflags=rustflags, build_root=rust_build_dir
)

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 = []
Comment thread
yanhu7150-tech marked this conversation as resolved.
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')
2 changes: 2 additions & 0 deletions components/rust/core/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod thread;
pub mod mutex;
pub mod sem;
pub mod queue;
#[cfg(feature = "libdl")]
pub mod libloading;


Expand All @@ -24,4 +25,5 @@ pub use thread::*;
pub use mutex::*;
pub use sem::*;
pub use queue::*;
#[cfg(feature = "libdl")]
pub use libloading::*;
11 changes: 8 additions & 3 deletions components/rust/core/src/api/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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]
Expand All @@ -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]
Expand Down
3 changes: 2 additions & 1 deletion components/rust/core/src/bindings/librt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 1 addition & 2 deletions components/rust/core/src/bindings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion components/rust/core/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()> {
Expand Down
3 changes: 2 additions & 1 deletion components/rust/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]

Expand All @@ -33,13 +32,15 @@ pub mod init;
pub mod allocator;
pub mod mutex;
pub mod out;
#[cfg(feature = "fs")]
pub mod fs;
pub mod panic;
pub mod param;
pub mod queue;
pub mod sem;
pub mod thread;
pub mod time;
#[cfg(feature = "libdl")]
pub mod libloader;

mod prelude;
Expand Down
22 changes: 13 additions & 9 deletions components/rust/examples/application/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cwd = GetCurrentDir()

# Import usrapp build module and build support
sys.path.append(os.path.join(cwd, '../../tools'))
from build_usrapp import build_example_usrapp
from build_usrapp import UserAppBuildError, build_example_usrapp
from build_support import clean_rust_build


Expand All @@ -31,7 +31,7 @@ def load_extended_feature_configs():

group = []

if not _has('RT_RUST_BUILD_APPLICATIONS'):
Comment thread
yanhu7150-tech marked this conversation as resolved.
if not (_has('RT_RUST_BUILD_APPLICATIONS') or _has('RT_RUST_BUILD_ALL_EXAMPLES')) and not GetOption('clean'):
Return('group')

# Load extended feature configurations
Expand All @@ -51,12 +51,16 @@ if GetOption('clean'):
print('No example_usrapp build artifacts to clean')
else:
import rtconfig
LIBS, LIBPATH, LINKFLAGS = build_example_usrapp(
cwd=cwd,
has_func=_has,
rtconfig=rtconfig,
build_root=os.path.join(Dir('#').abspath, "build", "example_usrapp")
)
try:
LIBS, LIBPATH, LINKFLAGS = build_example_usrapp(
cwd=cwd,
has_func=_has,
rtconfig=rtconfig,
build_root=os.path.join(Dir('#').abspath, "build", "example_usrapp")
)
except UserAppBuildError as e:
print(f'Error: {e}')
sys.exit(1)

group = DefineGroup(
'example_usrapp',
Expand All @@ -67,4 +71,4 @@ group = DefineGroup(
LINKFLAGS=LINKFLAGS
)

Return('group')
Return('group')
4 changes: 2 additions & 2 deletions components/rust/examples/application/fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ default = []
enable-log = ["em_component_log/enable-log"]

[dependencies]
rt-rust = { path = "../../../core" }
rt-rust = { path = "../../../core", features = ["fs"] }
rt_macros = { path = "../../../rt_macros" }
em_component_log = { path = "../../component/log"}
em_component_log = { path = "../../component/log"}
4 changes: 2 additions & 2 deletions components/rust/examples/application/loadlib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ name = "em_loadlib"
crate-type = ["staticlib"]

[dependencies]
rt-rust = { path = "../../../core" }
rt_macros = { path = "../../../rt_macros" }
rt-rust = { path = "../../../core", features = ["libdl"] }
rt_macros = { path = "../../../rt_macros" }
Loading
Loading