我正在使用一个在嵌入式设备上使用Rust的项目,我正在尝试在Rust中编写可以从C调用的函数。我在没有标准库的情况下编译项目,或多或少遵循本教程: Embedded Rust Right Now!
我的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代码。
有人知道这些错误的含义以及链接器无法解决这些问题的原因吗?谢谢!
答案 0 :(得分:4)
问题是你的rustc
(可能是你的cc
)构建的LLVM引用了编译器 builtins 或有时 intrinsics ,这是小型辅助程序,编译器假定它们已针对目标平台进行了优化。
通常它们都带有编译器,所以你会在网上看到很多commentary来说"为什么不与{{1 }}&#34 ;.这似乎对裸机项目没有帮助,事实上它不起作用,因为LLVM调用的内置程序与gcc略有不同。
您可以为这些例程提供实现,真正的裸机操作系统应该花费大约五分钟来考虑它。你可以用程序集或Rust编写它们:
libgcc.a
在您完成梦想之后,您开始为目标编译llvm's compiler-rt
(相当于libgcc.a)并将其链接起来。
在// 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;
}
和rustc
增加对installing extra targets for cross-compilation的支持之前,您必须下载Rust源并尝试构建交叉编译器和库(包括multirust
)自己。
目前compiler-rt
不是受支持的目标,因为一系列原因构建起来很粗糙,包括arm-none-eabi
无法链接可执行文件,Rust的jemalloc坚持认为。我的解决方法是从arm-none-eabi-gcc
收集源文件,并单独构建和链接它们。