概要
得意のパクリ記事です。
Rustで動的ライブラリに依存しないLinuxコマンドを作成する方法を読んで、Nimでも同じ事ができるのか調べてみました。
MUSLのインストール
MUSLのホームページから、musl-1.1.20.tar.gz をダウンロードします。
ダウンロードファイルを展開し、ビルドします。
wget http://www.musl-libc.org/releases/musl-1.1.20.tar.gz
tar xzvf musl-1.1.20.tar.gz
cd musl-1.1.20
./configure
make install
# obj/musl-gccが本体っぽい
ls -la obj/musl-gcc
# インストール先は、/usr/local/musl
tree -L 1 /usr/local/musl [master]
/usr/local/musl
├── bin
├── include
└── lib
NimでMuslを利用するには
githubにそのものズバリのリポジトリがいくつかありました。
こちらはconfig.nimsに、コンパイルオプション等が入っているサンプル
https://github.com/kaushalmodi/hello_musl
こちらはシェルでビルドするサンプル
https://github.com/yuhangwang/musl-nim
試してみる
1つめのサンプルで試してみます。
まずは、先ほどインストールしたmusl-gccへのパスを設定し、サンプルソースをgithubからcloneします。
# PATHは絶対パスで指定する必要あり
export PATH=/usr/local/musl/bin:$PATH
git clone https://github.com/kaushalmodi/hello_musl.git
cd hello_musl
hello_muslフォルダに、Nimファイルを作成します。
echo "hello musl"
まずは、普通にコンパイルし動的ライブラリを確認してみる
$ nim c -o:hello-nomal hello.nim Hint: used config file '/opt/apps/nim/nim-0.19.0/config/nim.cfg' [Conf]
Hint: used config file '/mnt/ramdisk/hello_musl/config.nims' [Conf]
Hint: system [Processing]
Hint: hello [Processing]
CC: hello
Hint: [Link]
Hint: operation successful (27405 lines compiled; 0.194 sec total; 38.844MiB peakmem; Debug Build) [SuccessX]
# 依存SOファイルを表示する
$ ldd hello-nomal
linux-vdso.so.1 => (0x00007ffc98fa6000)
libm.so.6 => /lib64/libm.so.6 (0x00007f68e04b4000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f68e02af000)
libc.so.6 => /lib64/libc.so.6 (0x00007f68dfeed000)
/lib64/ld-linux-x86-64.so.2 (0x00007f68e07db000)
5つの動的ライブラリに依存していることがわかります。
次に、MUSLでビルドし、依存ライブラリを確認してみます。
config.nimsにて、nimコマンドに渡されるコマンドを拡張しています。
このconfig.nimsですが、けっこうすごいことしています。Nimってこんな拡張ができるものなのかと感動しました。
$ nim musl -o:hello hello.nim Hint: used config file '/opt/apps/nim/nim-0.19.0/config/nim.cfg' [Conf]
Hint: used config file '/mnt/ramdisk/hello_musl/config.nims' [Conf]
Running 'nim c -d:musl -d:release --opt:size -o:hello hello.nim' ..
Hint: used config file '/opt/apps/nim/nim-0.19.0/config/nim.cfg' [Conf]
Hint: used config file '/mnt/ramdisk/hello_musl/config.nims' [Conf]
[-d:musl] Building a static binary using musl ..
debug: ../musl-1.1.20/obj/musl-gcc
Hint: system [Processing]
Hint: hello [Processing]
CC: hello
Hint: [Link]
Hint: operation successful (27405 lines compiled; 0.193 sec total; 38.809MiB peakmem; Release Build) [SuccessX]
Running 'strip -s' ..
Created binary: hello
# 依存SOファイルを表示する
$ ldd hello
動的実行ファイルではありません
lddコマンドの結果を見ると、どの動的ライブラリにも依存していないことがわかります。
出来上がったバイナリを他のディストリビューションで試してみる
今回は、Window10のbash on windows上に、先のhelloコマンドをコピーして実行してみたところ、問題なく動作しました。
本来はもっと検証したいところですが。
まとめ
MUSLを利用したNimのビルドを試し、動的ライブラリに依存しないコマンドを作成することができました。
今回は、Linuxでの動作確認となりましたが、Windows10のMINGW環境でMUSLをビルドしてもうまく行かず時間もなかったので、今回はスキップしています。
MacでもMuslのビルドは問題なさそうな気がしますが、時間があるときに試してみる予定です。
なお、hello_muslでは、正規表現およびSSLを使う時の専用のオプションもあります。
詳細はこちらでご確認ください。