理解 Rust 库的依赖关系

4

我正在为ARM编写一个嵌入式Rust程序,用于教育目的。

由于这是一个裸机系统,所以我只使用核心库。该库的手册页面声称corelib除了memcpy, memcmp, 和 memset以及取消操作函数(见https://doc.rust-lang.org/core/index.html)之外不依赖任何东西。

然而,特别是当我使用原子类型时,由于缺少符号(例如__sync_val_compare_and_swap_4__sync_lock_test_and_set_4),我仍然会遇到链接器错误,指示缺少compiler-rt库。我理解,compiler-rt应该在corelib之上。这看起来像一个循环依赖,这是不应该的。此外,我了解到,compiler-rt反过来又依赖于操作系统。

  1. 我的理解中哪部分是不正确的?
  2. 如何获得真正独立的corelib,或者它的哪些部分是真正独立的? 我知道我可以重新实现缺失的函数,但它们似乎很多。此外,我知道compiler-builtins crate,但它仍然留下了未解决的符号。

__sync_val_compare_and_swap_4不被compiler-rt提供。连接到libgcc_s是否可行?(参考https://dev59.com/8mDVa4cB1Zd3GeqPeYyI#9329139) - kennytm
@kennytm:还没有,我不确定目标平台是否有它,但我会尝试一下。然而,llvm需要libgcc_s似乎有点奇怪。 - Matthias
这个相关问题使用的是GCC 4,我不知道LLVM的等效物是什么 :) - kennytm
1个回答

3
与此同时,我已经找到了一个解决方案。我分享它的目的是希望能对其他人有所帮助。
正如kennytm所正确提到的,这些符号并不属于compiler_rt。此外,这些符号仅仅巧合地与libgcc的函数相同,详见这里。如果CPU不支持像cmpxchg这样的原子命令,那么llvm会发出调用。
我的处理器是ARMv6,并且支持原子命令。然而,我没能告诉Rust/llvm:目标描述的JSON文件看起来就像这样:
{  "llvm-target": "arm-none-eabihf",  
   "target-endian": "little",
   "target-pointer-width": "32", 
   "os": "none",
   "env": "eabihf", 
   "vendor": "unknown",
   "arch": "arm", 
   "linker": "arm-none-eabi-gcc",
   "linker-flavor": "gnu",
   "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
   "executables": true,
   "relocation-model": "static",
   "no-compiler-rt": true
}

这样一来,我的CPU也可以是不支持原子命令的ARMv5。通过添加一个字段"cpu": "arm1176jzf-s",我可以解决链接器错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接