7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rust でしっかりとダイナミックリンク

Last updated at Posted at 2019-03-30

はじめに

Rustのビルドシステムでは、Rustの世界ではスタティックリンク、OSの標準ライブラリとはダイナミックリンクが基本になっている。これは、Rustの標準ライブラリぐらいはダイナミックリンクにして、バイナリをスリム化するための備忘録である。

環境

  • macOS Sierra 10.12.6 (16G2011)
  • rustc 1.36.0-nightly (e305df184 2019-04-24)
  • Apple LLVM version 9.0.0 (clang-900.0.39.2)

ダイナミックリンクを指定する方法

rustc のコード生成時のオプションとして -C prefer-dynamic を指定すればよい。cargo を使う場合、rustc のフラグを指定する方法には以下の3つがあるようだが、それぞれ、ちょっとしたデメリットがある。

  1. cargo rustc のコマンドラインで指定
    • cargo build ではないサブコマンドを使わないといけない
    • いちいち指定するのが面倒
    • これでビルドしても、cargo run すると、通常の cargo build が走ってしまう
  2. .cargo/configrustflags に記述
    • ビルドするターゲットごとに指定することはできなさそう
    • "Cargo.toml" と同様の TOML フォーマットで記述すればよいのだが、" をエスケープすることができないので、指定にちょっとコツがいる
  3. 環境変数 RUSTFLAGS で指定
    • いちいち指定するのが面倒(だが、これが一番お手軽な気がする)

ちなみに、ダイナミックリンクされているライブラリが何かを知るためには、otool -L バイナリファイル名 とすればよい。

例 1. cargo rustc のコマンドラインで指定

# ビルド
$ cargo rustc -- -C prefer-dynamic

# 起動(Rust標準ライブラリのパスを環境変数で設定)
$ DYLD_LIBRARY_PATH=~/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib ./target/debug/hogehoge
# もしくは
$ DYLD_LIBRARY_PATH=~/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib ./target/debug/hogehoge

# 起動(rustup経由)
$ rustup run stable ./target/debug/hogehoge
# もしくは
$ rustup run nightly ./target/debug/hogehoge

例 2. .cargo/configrustflags に記述

# config 設定
$ mkdir .cargo
$ cat <<EOF >.cargo/config
[build]
rustflags = ["-C", "prefer-dynamic"]
EOF

# ビルド
$ cargo build

# 起動
$ cargo run

例 3. 環境変数 RUSTFLAGS で指定

# 環境変数の設定
$ export RUSTFLAGS="-C prefer-dynamic"

# ビルド
$ cargo build

# 起動
$ cargo run

結果

結果は以下の通り(Swift については、2019/8/14 追記)。

unstripped stripped
Rust (-C opt-level=3) 276,272 bytes 178,856 bytes
Rust (-C opt-level=3 -C prefer-dynamic) 9,048 bytes 8,656 bytes
C (-Oz) 8,432 bytes 8,440 bytes
Swift (-Osize) 8,960 bytes 8,824 bytes

比較のためのプログラムは以下の通り。

hello/src/main.rs
fn main() {
    println!("Hello, world!");
}
hello/c/hello.c
#include <stdio.h>

int main() {
	   printf("Hello, world!\n");
}
hello/swift/hello.swift
print("Hello, world!")

なかなかいい線いっているという感じか。次はスタティックリンクに挑戦

参考

様々な最適化フラグの比較については、下記が参考になる。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?