将 Rust 与 C 链接:对“__aeabi”函数的未定义引用

Linking Rust with C: undefined reference to '__aeabi' functions

我正在做一个在嵌入式设备上使用 Rust 的项目,我试图用 Rust 编写可以从 C 调用的函数。我在没有标准库的情况下编译项目,或多或少遵循这个教程:Embedded Rust Right Now!

我的 Rust 代码可以很好地编译成 .o 文件,但我在尝试使用 arm-none-eabi-ld link C 和 Rust 对象文件时遇到了麻烦。我收到几个与这些类似的错误:

rustfunc.o: In function `func':
rustfunc.0.rs:(.text.hash+0x18): undefined reference to `__aeabi_memclr8'
...
/rust/src/libcore/slice.rs:1446: undefined reference to `__aeabi_memcpy'
/rust/src/libcore/fmt/num.rs:196: undefined reference to `__aeabi_memclr4'

最让我困惑的是,即使我只是 link 将目标文件放在一起,错误也引用了我的 Rust 代码和来自 libcore 的代码。

是否有人知道这些错误的含义以及为什么 linker 无法解决这些问题?谢谢!

问题是 LLVM,您的 rustc(可能还有您的 cc)所基于的,引用了编译器 builtins 或有时 intrinsics,这是编译器假定已针对目标平台优化的小帮助例程。

通常它们与编译器一起提供,所以您会在网上看到很多 commentary 说 "why don't you link with libgcc.a"。这对裸机项目似乎没有帮助,实际上也行不通,因为 LLVM 调用的内置函数与 gcc 略有不同。

您可以为这些例程提供实现,真正的裸机 OS 可能应该花大约五分钟来考虑它。您可以用汇编或 Rust 编写它们:

// Use this at your peril
#[no_mangle]
pub unsafe extern fn __aeabi_memclr4(s: *mut u8, n: usize) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *s.offset(i as isize) = 0u8;
        i += 1;
    }
    return s;
} 

完成梦想后,您开始为目标编译 llvm's compiler-rt(相当于 libgcc.a),然后 link 那个。

直到 rustcmultirust 增加对 installing extra targets for cross-compilation 的支持,您必须下载 Rust 源并尝试构建交叉编译器和库(包括 compiler-rt) 你自己。

目前 arm-none-eabi 不是受支持的目标,由于一系列原因,构建很粗糙,包括 arm-none-eabi-gcc 不会 link 可执行文件,而 Rust 的 jemalloc 坚持这样做.我的解决方法是从 compiler-rt 获取源文件并单独构建和 link 它们。