ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

静的ライブラリと共有ライブラリ

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を設定しないとうまくいかなかったのを忘れていたので、その手順も追加しました。