LoginSignup
18
7

More than 5 years have passed since last update.

Nimで動的ライブラリに依存しないLinuxコマンドを作成する方法

Last updated at Posted at 2018-12-12

概要

得意のパクリ記事です。
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ファイルを作成します。

hello.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を使う時の専用のオプションもあります。
詳細はこちらでご確認ください。

18
7
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
18
7