在Linux作業系統上編譯Rust程式時,預設使用的目標(target)為*-unknown-linux-gnu*(例如x86_64-unknown-linux-gnu、i686-unknown-linux-gnu等),因此編譯出來的執行檔會與「glibc」進行動態連結。如果使用較新的Linux作業系統來編譯Rust程式,該程式很可能就會因為glibc版本也較新的關係,而無法在較舊的Linux作業系統上執行。為了使Rust程式在編譯出來之後就可以被用在任意的Linux作業系統版本,就要讓該Rust程式編譯出來之後不去動態連結glibc,這該怎麼做呢?



Rust在編譯程式的時候,可以設定要編譯的目標平台。使用以下指令,可以印出Rust支援的所有目標名稱。

rustc --print target-list

rust-static-musl

為了要讓Rust程式不去動態連結glibc,我們必須要使用其它的C library,而跨平台的「musl libc」就是個不錯的選擇。使用以下指令,可以印出Rust支援的所有能夠使用musl的目標名稱。

rustc --print target-list | grep musl

rust-static-musl

以在個人電腦或伺服器上常用的64位元的Linux作業系統為例,就選擇x86_64-unknown-linux-musl來編譯Rust程式吧!

首先使用以下指令,來加入x86_64-unknown-linux-musl目標。

rustup target add x86_64-unknown-linux-musl

rust-static-musl

接著在使用cargo指令來編譯程式專案的時候,只要加上--target x86_64-unknown-linux-musl參數就好了!例如:

cargo build --target x86_64-unknown-linux-musl

rust-static-musl

比較一下x86_64-unknown-linux-gnux86_64-unknown-linux-musl的編譯結果。使用ldd指令檢查執行檔動態連結的函式庫時可以發現,透過x86_64-unknown-linux-musl目標編譯出來的程式並不是一個動態連結的可執行檔!

rust-static-musl

rust-static-musl

當然像這樣以完全靜態的方式編譯出來的執行檔,檔案大小會比有用動態連結的執行檔的大小還要大一些。不過musl也不是那麼的好,畢竟glibc是主要的函式庫,程式通常不會針對musl libc做測試,因此難保改用musl編譯之後不會出現問題。