我有一个 Rust 函数,我想从 C project 调用在 STM32F412 MCU 上运行,但我收到一系列“多重定义”链接器错误。
这是我的 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。
链接器错误的完整列表可以是found here . nm
将所有冲突函数显示为全局文本符号 (T),full output here .
C 项目没有普通的标准 C 库,而是使用自定义 libc,这是一种特定于设备的实现,涵盖了标准的一小部分。我可以告诉 Rust 库使用这些函数吗?
通读 Rust 特性列表,有 #![feature(compiler_builtins_lib)]
但这与我想要的完全相反,因为如果你得到“ undefined reference ”链接器错误.
最佳答案
您有一堆重复的符号,它们来自您自定义的“标准库”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);
...
关于c - "multiple definition of ` memcmp“链接Rust staticlib与嵌入式C程序时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50433610/