5

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

我的 Rust 代码可以很好地编译为 .o 文件,但是在尝试使用 arm-none-eabi-ld 将 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'

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

有谁知道这些错误的含义以及为什么链接器无法解决这些问题?谢谢!

4

1 回答 1

6

问题是 LLVM,它是你的rustc(可能是你的cc)构建的,它引用了编译器builtins或有时是intrinsics,它们是编译器假定已针对目标平台优化的小型辅助例程。

通常它们与编译器一起提供,因此您会在 'Net 上看到很多评论说“为什么不链接libgcc.a”。这对于裸机项目似乎没有帮助,实际上也不起作用,因为 LLVM 调用的内置函数与 gcc 略有不同。

您可以为这些例程提供实现,一个真正的裸机操作系统可能应该花大约五分钟的时间来考虑它。你可以用汇编或 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;
} 

完成梦想后,您开始为您的目标编译llvmcompiler-rt(相当于 libgcc.a)并链接它。

直到rustcmultirust增加他们对安装额外目标以进行交叉编译的支持,您必须下载 Rust 源代码并尝试自己构建交叉编译器和库(包括compiler-rt)。

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

于 2015-12-15T11:38:07.190 回答