了解 Rust 库的依赖关系

Understanding dependencies of Rust libraries

我正在为教育目的编写一个用于 ARM 的嵌入式 Rust 程序。 由于它是一个裸机系统,我只使用核心库。该库的手册页声称 corelib 不依赖于任何东西,而是 memcpymemcmpmemset 以及展开函数(请参阅 https://doc.rust-lang.org/core/index.html)。 但是,特别是如果我使用 atomic types, I continue to get linker errors because of missing symbols, such as __sync_val_compare_and_swap_4 or __sync_lock_test_and_set_4 that indicates a missing compiler-rt 库。我明白,compiler-rt 应该在 corelib 之上。这看起来像一个循环依赖,不应该是什么。此外,我了解到 compiler-rt 又依赖于 OS.

  1. 我的哪一部分理解不正确?
  2. 怎样才能得到一个真正独立的corelib,或者它的哪些部分是真正独立的?我知道我可以重新实现缺少的功能,但它们似乎很多。另外,我知道 compiler-builtins crate,但它仍然给我留下未解析的符号。

与此同时,我找到了解决方案。我分享它,希望它对其他人有用。

正如 kennytm 正确提到的,这些符号不属于 compiler_rt。此外,符号只是偶然与 libgcc 的函数相同,c.f。 here。如果 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" 我可以解决链接器错误。