🐡

Rustでクロスビルドするときのリンカにclangを使う

2023/08/08に公開

Rustではrustupコマンドでビルドするターゲットを簡単に追加することができますが、そこにはリンカは含まれていないので、別途用意する必要があります。
しかし、clangがインストールしてあれば、clang-target オプションをつけることでllvmがサポートしている各ターゲットのリンクをすることができます。

riscv64向けのクロスビルドをセットアップする例

rustupriscv64がつくターゲットを探します。

$ rustup target list |grep riscv64
riscv64gc-unknown-linux-gnu
riscv64gc-unknown-none-elf
riscv64imac-unknown-none-elf

ターゲットの追加。

$ rustup target add riscv64gc-unknown-linux-gnu

ビルドしてみると

$ cargo build --target riscv64gc-unknown-linux-gnu
   Compiling hello v0.1.0 (/home/koba/work/rust/hello)
error: linking with `cc` failed: exit status: 1
  |

...

ccコマンドでエラーになっています。デフォルトではリンカにはccが使用されていることがわかります。

以下のようにコンフィグファイルに追加します。

.cargo/config.toml
[target.riscv64gc-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-args=-target riscv64-unknown-linux-gnu"]

このファイルをどこに置くかはこちらのページを見てください。

再度試すと

$ cargo build --target riscv64gc-unknown-linux-gnu
   Compiling hello v0.1.0 (/home/koba/work/rust/hello)
    Finished dev [unoptimized + debuginfo] target(s) in 0.24s

今度はビルドできました。

できた実行ファイルは以下の通り。

$ file target/riscv64gc-unknown-linux-gnu/debug/hello
target/riscv64gc-unknown-linux-gnu/debug/hello: ELF 64-bit LSB pie executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 4.15.0, with debug_info, not stripped

余談

リンクする時のコマンドを表示するにはコンフィグファイルを以下のようにします。

.cargo/config.toml
[target.riscv64gc-unknown-linux-gnu]
linker = "clang"
#rustflags = ["-C", "link-args=-target riscv64-unknown-linux-gnu"]
rustflags = ["-C", "link-args=-target riscv64-unknown-linux-gnu", "--print", "link-args"]
$ cargo build --target riscv64gc-unknown-linux-gnu
   Compiling hello v0.1.0 (/home/koba/work/rust/hello)
LC_ALL="C" PATH="/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/aarch64-unknown-linux-gnu/bin:/opt/go/bin:/opt/zig-linux-aarch64-0.11.0:/home/koba/bin:/home/koba/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" VSLANG="1033" "clang" "/tmp/rustc8a7R5e/symbols.o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88.15g0eqzl2rrftgsf.rcgu.o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88.1jvqh1ky25lp0r26.rcgu.o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88.1l8xzgkyxyilsjjw.rcgu.o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88.2y79tyoudgsriolg.rcgu.o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88.3xrx24iyd78q5i4t.rcgu.o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88.4c78rqzuvi61l9vl.rcgu.o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88.120equ4cmxzxa6k0.rcgu.o" "-Wl,--as-needed" "-L" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps" "-L" "/home/koba/work/rust/hello/target/debug/deps" "-L" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libstd-f14170ec88add058.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libpanic_unwind-f7c74f5d43927d99.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libobject-eedc5164b562a274.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libmemchr-125f2f0121460ce9.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libaddr2line-92892d1da853f534.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libgimli-75e47a8c56db0187.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/librustc_demangle-7840d34c328d8e09.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libstd_detect-e700286be1b08062.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libhashbrown-caae8743e900cf72.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/librustc_std_workspace_alloc-fca90050d2ae9f79.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libminiz_oxide-1cf667f67b3e3bb1.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libadler-8258e975f0bee1f0.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libunwind-fa9c38884ee4a972.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libcfg_if-7969105acb127d0e.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/liblibc-f3eb382cb263b5d5.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/liballoc-21408a73b2354e4a.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/librustc_std_workspace_core-406210fecf4e9a91.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libcore-2a8cb54ea4890402.rlib" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib/libcompiler_builtins-144a83d72b408c06.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/home/koba/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/riscv64gc-unknown-linux-gnu/lib" "-o" "/home/koba/work/rust/hello/target/riscv64gc-unknown-linux-gnu/debug/deps/hello-a2405796a984dc88" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "-target" "riscv64-unknown-linux-gnu"
    Finished dev [unoptimized + debuginfo] target(s) in 0.25s

長い一行になっているので、横スクロールして見てください。

Discussion