我有一个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 {} }
与一起cargo 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
出现问题是因为链接时目标文件的顺序很重要。
如果将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 $@
这个食谱在我这边成功链接了。我的基本epsilon/apps/main.cpp
仪器:
#include "global_preferences.h"
#include "apps_container_storage.h"
extern "C" int hello_world(int a, int b);
void ion_main(int argc, char * argv[]) {
hello_world(1,2);
...
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句