在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支援的所有目標名稱。
為了要讓Rust程式不去動態連結glibc,我們必須要使用其它的C library,而跨平台的「musl libc」就是個不錯的選擇。使用以下指令,可以印出Rust支援的所有能夠使用musl的目標名稱。
以在個人電腦或伺服器上常用的64位元的Linux作業系統為例,就選擇x86_64-unknown-linux-musl
來編譯Rust程式吧!
首先使用以下指令,來加入x86_64-unknown-linux-musl
目標。
接著在使用cargo
指令來編譯程式專案的時候,只要加上--target x86_64-unknown-linux-musl
參數就好了!例如:
比較一下x86_64-unknown-linux-gnu
和x86_64-unknown-linux-musl
的編譯結果。使用ldd
指令檢查執行檔動態連結的函式庫時可以發現,透過x86_64-unknown-linux-musl
目標編譯出來的程式並不是一個動態連結的可執行檔!
當然像這樣以完全靜態的方式編譯出來的執行檔,檔案大小會比有用動態連結的執行檔的大小還要大一些。不過musl也不是那麼的好,畢竟glibc是主要的函式庫,程式通常不會針對musl libc做測試,因此難保改用musl編譯之後不會出現問題。