RUST 交叉編譯 arm64 的浮點函數問題
最近在把一個項目遷移到支持 arm64(aarch64) 時,遇到了個 rust 編譯器的問題,由於 rust 有部分函數沒實現,會出現找不到符號的情況,如
...
vfprintf.c:(.text.fmt_fp+0x178): undefined reference to `__addtf3'
vfprintf.c:(.text.fmt_fp+0x20c): undefined reference to `__multf3'
vfprintf.c:(.text.fmt_fp+0x240): undefined reference to `__subtf3'
vfprintf.c:(.text.fmt_fp+0x250): undefined reference to `__addtf3'
vfprintf.c:(.text.fmt_fp+0x278): undefined reference to `__addtf3'
vfprintf.c:(.text.fmt_fp+0x284): undefined reference to `__subtf3'
vfprintf.c:(.text.fmt_fp+0x33c): undefined reference to `__subtf3'
vfprintf.c:(.text.fmt_fp+0x344): undefined reference to `__multf3'
vfprintf.c:(.text.fmt_fp+0x4e8): undefined reference to `__multf3'
vfprintf.c:(.text.fmt_fp+0x548): undefined reference to `__subtf3'
vfprintf.c:(.text.fmt_fp+0x550): undefined reference to `__multf3'
vfprintf.c:(.text.fmt_fp+0x828): undefined reference to `__addtf3'
...
這個問題是比較普遍的問題,原因在於 rust 的實現中並沒有 f128
相關的內容 (tf3 表示 triple float),基本上做 aarch64 時都會遇到。
github 上的 issue 見 https://github.com/rust-lang/rust/issues/46651 。問題來自於 rust 的實現,但是還是要處理掉的,方法是靜態鏈接 c 庫實現。
具體操作如下:
1. 把交叉編譯器的 libgcc.a 的所在目錄添加到 rust 鏈接時搜索目錄
2. 加入鏈接參數 -lgcc
可以在命令行上加,但是每次都要打命令行不方便,加到項目下的 .cargo/config
中,以下是使用了 musl 工具鏈的配置,見 https://www.cnblogs.com/fengyc/p/12861259.html
[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-ld"
ar = "aarch64-linux-musl-ar"
rustflags = ["-C", "target-feature=+crt-static", "-L", "/opt/aarch64-linux-musl-cross/lib/gcc/aarch64-linux-musl/9.2.1", "-C", "link-arg=-lgcc"]
strip = {path="aarch64-linux-musl-strip"}
objcopy = {path = "aarch64-linux-musl-objcopy"}
-L
后的參數即為 libgcc.a
所在的目錄,可通過 find <交叉編譯工具鏈所在目錄> -name libgcc.a
找到。
如果各個路徑都正確,加上之后再次 cargo build
問題都會消失。
如果使用了其它的工具鏈,也基本是這個原理,只要目錄和附加的鏈接參數正確,鏈接器能正確找到了函數符號,就能解決這個問題。