c - "multiple definition of ` memcmp“链接Rust staticlib与嵌入式C程序时出错

标签 c linker rust embedded ffi

我有一个 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/

相关文章:

c - 使用文本文件,它不起作用

c++ - 非类类型成员getName请求错误 'char'

添加到队列时在 C 和 Malloc 中创建队列

types - 是否可以将闭包分配给 impl Fn() 类型的变量?

rust - 如何在rust中的多个线程上传递具有特征的数据结构?

c - 尝试在 Ubuntu 中实现无名管道程序

eclipse - ld : Symbol(s) not found… but they are there…

c++ - 无法在 VC++ 中从 NASM 调用 c 函数,除了 main,出现链接错误

c++ - 链接时不包含宏定义

rust - 如何离线阅读 Rust 文档?