SharedとStaticの差


下記何の変哲もないHelloWorldです。

nogisawa@a970:~/clang$ cat hello.c 
#include <stdio.h>

void main(){

	printf("Hello\n");

}
nogisawa@a970:~/clang$ gcc hello.c 
nogisawa@a970:~/clang$ ./a.out 
Hello
このa.outを実行する時、どんなライブラリを参照しているか確認するのにlddというコマンドがあります。

nogisawa@a970:~/clang$ ldd ./a.out 
	linux-vdso.so.1 (0x00007ffef63dc000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7e17f25000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f7e18126000)
libcなどいくつかのライブラリを読み込んでる事がわかります。

ここで下記のオプションでコンパイルしてみましょう。

nogisawa@a970:~/clang$ gcc -static ./hello.c 
nogisawa@a970:~/clang$ ./a.out 
Hello
nogisawa@a970:~/clang$ ldd ./a.out 
	動的実行ファイルではありません
すると動的実行ファイルはありませんとなります。実行に必要なライブラリをすべて内包した事になります。

ライブラリを内包したという事は実行ファイルのサイズが増えているはず。という事で早速確認してみます。

(動的)-rwxr-xr-x 1 nogisawa nogisawa 739K  1月  8 23:19 ./a.out
(静的)-rwxr-xr-x 1 nogisawa nogisawa 17K  1月  8 23:20 ./a.out
何と700KB以上の差がありました。

sharedライブラリはメモリに一度展開されると他のプログラムも含めて再利用されるため消費されるメモリを節約し、プログラムのサイズも小さくしてくれるのでメリットが大きいですが、それ故インストールされているライブラリのバージョンが一致しないとプログラムが動かなくなるという互換性の問題が出てきます。

staticでビルドする事でその問題はある程度解決してくれますが、代わりのメモリとファイルサイズを消費するようになります。