Jam*_*man 4 c gcc libc rust eabi
我正在一个在嵌入式设备上使用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'
Run Code Online (Sandbox Code Playgroud)
最让我困惑的是,即使我只是将目标文件链接在一起,但这些错误同时引用了我的Rust代码和libcore中的代码。
是否有人知道这些错误是什么意思,以及链接器为何无法解决这些问题?谢谢!
问题在于,您rustc(可能还有您cc)所基于的LLVM 引用了编译器的内建函数,有时还引用了内在函数,即内在函数,它们是小的辅助例程,编译器认为它们已针对目标平台进行了优化。
通常它们是随编译器一起提供的,因此您会在网上看到很多评论,说“为什么不链接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;
}
Run Code Online (Sandbox Code Playgroud)
做完梦之后,就着手为目标编译llvmcompiler-rt(相当于libgcc.a),并将其链接起来。
直到rustc和multirust增加他们的支持对交叉编译安装额外的目标,你必须下载锈源,并尝试建立交叉编译器和库(包括compiler-rt)自己。
目前arm-none-eabi还不是受支持的目标,出于各种原因,构建过程很粗糙,包括那些arm-none-eabi-gcc不会链接可执行文件的原因,Rust的jemalloc坚持认为。我的解决方法是从中获取源文件,compiler-rt并分别构建和链接它们。