Fer*_*ogh 5 c embedded linker ffi rust
我有一个 Rust 函数,我想从在 STM32F412 MCU 上运行的C 项目调用,但是我收到了一系列“多重定义”链接器错误。
这是我的 lib.rs:
#![crate_type = "staticlib"]
#![feature(lang_items)]
#![no_std]
#![no_builtins]
#[no_mangle]
pub extern "C" fn hello_world(a: i32, b: i32) -> i32 {
a + b
}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
Run Code Online (Sandbox Code Playgroud)
Building withcargo build --release --target=thumbv7em-none-eabihf会生成一个librust.a我作为对象添加到 C Makefile 的对象。
可以在此处找到链接器错误的完整列表。nm将所有冲突函数显示为全局文本符号 (T),此处为完整输出。
C 项目没有普通的标准 C 库,而是使用自定义 libc,这是一个特定于设备的实现,涵盖了标准的一小部分。我可以告诉 Rust 库使用这些函数吗?
通读 Rust 功能列表,#![feature(compiler_builtins_lib)]但是这与我想要的完全相反,因为如果您收到“未定义的引用”链接器错误。
您有一堆重复的符号来自您的自定义“标准库”liba和插入到的生成的内置librust.a符号:
memset, memcpy, memmove, ecc, ecc
Run Code Online (Sandbox Code Playgroud)
出现您的问题是因为链接时目标文件的顺序很重要。
如果您librust.a过早地将要链接的文件的有序序列放入其中,则之前的文件librust.a将解析其中的符号librust.a,而之后的文件librust.a将解析其中的相同符号liba,这会生成重复的符号错误。
为了避免这个问题,请将 Rust 库放在目标文件的末尾进行链接。
在 epsilon Makefile 中将链接命令更改为:
RUST_LIB_DIR = <path_to_librust.a>
.SECONDARY: $(objs)
%.$(EXE):
@echo "LD $@"
$(Q) $(LD) $^ $(LDFLAGS) -L$(RUST_LIB_DIR) -l:librust.a -o $@
Run Code Online (Sandbox Code Playgroud)
这个食谱在我这边链接成功。我的基本epsilon/apps/main.cpp仪器:
memset, memcpy, memmove, ecc, ecc
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1149 次 |
| 最近记录: |