静的ライブラリと共有ライブラリ
BINARY HACKS p30
BINARY HACKSアウトプットモードに入りますが、難しいので、多分かなりの部分読み飛ばすと思います。。
まずは静的ライブラリ。
taka@ubuntu:~$ more add.h int add(int a, int b); taka@ubuntu:~$ more add.c int add(int a, int b) { return a + b; } taka@ubuntu:~$ cc -c -o add.o add.c taka@ubuntu:~$ ls add.o add.o taka@ubuntu:~$ ar ruv libadd.a add.o ar: creating libadd.a a - add.o taka@ubuntu:~$ ls libadd.a libadd.a taka@ubuntu:~$ ar tv libadd.a rw-r--r-- 1000/1000 675 Mar 12 01:41 2008 add.o taka@ubuntu:~$ more calladd.c #include#include "add.h" int main() { printf("add(3, 4) = %d\n", add(3, 4)); } taka@ubuntu:~$ cc -o calladd calladd.c -ladd /usr/bin/ld: cannot find -ladd collect2: ld returned 1 exit status taka@ubuntu:~$ cc -o calladd calladd.c -L. -ladd taka@ubuntu:~$ ./calladd add(3, 4) = 7 taka@ubuntu:~$ mv libadd.a libadd.aa taka@ubuntu:~$ ./calladd add(3, 4) = 7 taka@ubuntu:~$
arコマンドで.oをアーカイブしているところと、-lライブラリ名でリンクしてるところがポイントですかね。
ちなみに、デフォルトでカレントパスのライブラリを読まなかったので、-L.を付けてコンパイルしてます。
最後にやったのは、静的ライブラリなので、ロードモジュールが出来てしまえば、元のライブラリが無くても動くってところです。
arって、tarの先祖みたいなもんですかね?一字違いだし。
続いて、共有ライブラリ。
taka@ubuntu:~$ more mult.h int mult(int a, int b); taka@ubuntu:~$ more mult.c int mult(int a, int b) { return a * b; } taka@ubuntu:~$ cc -fPIC -c -o mult.o mult.c taka@ubuntu:~$ ls mult.o mult.o taka@ubuntu:~$ cc -shared -Wl,-soname,libmult.so.0 -o libmult.so mult.o taka@ubuntu:~$ ls libmult.so libmult.so taka@ubuntu:~$ cc -o callmult callmult.c -lmult /usr/bin/ld: cannot find -lmult collect2: ld returned 1 exit status taka@ubuntu:~$ cc -o callmult callmult.c -L. -lmult taka@ubuntu:~$ ./callmult ./callmult: error while loading shared libraries: libmult.so.0: cannot open shared object file: No such file or directory taka@ubuntu:~$ ln -s libmult.so libmult.so.0 taka@ubuntu:~$ ./callmult ./callmult: error while loading shared libraries: libmult.so.0: cannot open shared object file: No such file or directory taka@ubuntu:~$ echo $LD_LIBRARY_PATH taka@ubuntu:~$ export LD_LIBRARY_PATH=. taka@ubuntu:~$ ./callmult mult(3, 4) = 12 taka@ubuntu:~$
-sonameで指定した名前と、-oで指定したファイル名が違うためにエラーが起きているような気がするのですが、、
共有ライブラリなので、コンパイル時にも、実行時にも無いとエラーになります。
(追記)
プログラマーでない人のための「共有ライブラリ」講座みたら、バージョン管理のために〜.so.0ってしているらしい。シンボリックリンクするのが流儀らしい。
バイナリアン的(UNIX使い的)には常識なのだろうか。。
(3/12 追記)
シンボリックリンクでやる手順に直しました。
ついでに、LD_LIBRARY_PATHを設定しないとうまくいかなかったのを忘れていたので、その手順も追加しました。