シェアードライブラリの作り方・使い方というのは、 OSによってバラバラだったりします。 共通性の高そうな SVR4系 (SunOS5,NEWSOS6,EWS-UX,IRIX) でも微妙に違う。 私なりに調べてみた事項をここにまとめてみました。
$Id: dynald.html,v 1.13 2005/04/28 06:21:48 kabe Exp $
OS | RPATH | 依存ライブラリ | 備考 |
---|---|---|---|
SunOS 4 | (なし) | ldd a.out
| |
SunOS 5 | ldd -s a.out
| ldd a.out
| |
dump -vL a.out
| |||
EWS-UX/V | ldd a.out
| ||
dump -vL a.out
| |||
NEWS-OS 6 | ldd a.out
dump -Dl a.out
| ldd は いもづるも表示する
| |
dump -L a.out
| |||
IRIX 5 | elfdump -Dl a.out
| ||
elfdump -L a.out
| |||
_RLD_PATH=/usr/lib/rld.debug _RLD_ARGS=-v a.out
| ターゲットが実行されてしまう | ||
HP-UX 9 | chatr a.out
| ldd
の方が正確な情報がとれる(ような気がする)
| |
AIX 4 | dump -H a.out
| ||
Darwin (MacOS X) | (RPATHなし) | otool -L a.out
| |
GNU binutils | objdump -p a.out
|
/usr/lib
だけを参照するような
OSが多い。
実行時に環境変数 LD_LIBRARY_PATH で指定されるものと同じ。
シェアードライブラリを早くからサポートした SunOS4 では、 構築時パス (-L で指定するもの) との区別がなかったが、 SVR4系では明確に区別される。 従って、リンクは成功した(a.outはできた)が、いざ実行してみると 「ライブラリが見つからん」といって実行できないような a.outを作ってしまうことがある。
Solaris2% gcc -c -I/usr/local/X11R6/include a.c Solaris2% gcc a.o -L/usr/local/X11R6/lib -lX11 -lsocket -lnsl # コンパイル・リンクは成功 Solaris2% ./a.out ld.so.1: ./a.out: fatal: libX11.so.6.0: can't open file: errno=2 Killed Solaris2%
これを解消するには、実行時に LD_LIBRARY_PATH を設定して 一時的にしのぐか、
Solaris2 % env LD_LIBRARY_PATH=/usr/local/X11R6/lib ./a.out Solaris2 %リンク時に明示的に RPATH を指定してやらないといけない。 こちらでは LD_LIBRARY_PATH は不要。 具体的な方法はOSによって微妙に違うので、下の 実行時検索パス(RPATH)の指定 を参照のこと。
Solaris2% env LD_RUN_PATH=/usr/local/X11R6/lib gcc a.o -L/usr/local/X11R6/lib -lX11 -lsocket -lnsl Solaris2 % ./a.out Solaris2 %
SunOS および NEWS-OS6 の ldd は、動作的には
SunOS% env LD_TRACE_LOADED_OBJECTS=1 a.outと同じ。SunOS5なら、lib*.soのexecute bitを立てれば シェアードライブラリに対しても ldd を実行できる。
単に環境変数を定義しているだけなので、NEWS-OS6用の ldd を IRIX に持っていっても無駄。気が向いたら作りましょう。
「いもづる」というのは、 「AがBに依存しているとき、構築時にAをリンクすればBも勝手にリンクされる (もしくは実行時に探される)」ような機能を指すつもりで書いています。 マニュアルに明示的に書かれていることが少ないので正式名がわからん。
SunOS5 ばかり使っていると忘れがちですが、-R
オプションは
SunOS5 でしか使えません。
OS | ld コマンドライン | いもづる | shlib自体のRPATH | 備考 |
---|---|---|---|---|
SunOS 4 | ld -Lpath1 -Lpath2
| 有効 | 無視 | -L は、リンク時と実行時の両方に使われる。
出力に-L が記録される。
|
SunOS 5 | ld -Rpath1:path2
| 無視 | 無視 | -R を使用すると
LD_RUN_PATH は無視される。
shlib中のRPATHも基本的に無視されるが、Undefined symbol の表示の際に
依存ライブラリの推測に使われる。
|
EWS-UX/V | LD_RUN_PATH=path1:path2 ld ...
| 無視 | 不可 | |
NEWS-OS 6 | ld -rpath path1:path2
| 有効 | 有効 | ./so_locations を自動更新。
-rpath ⊇ shlibのRPATH でないと
bus error?
|
IRIX 5 | ld -rpath path1:path2
| 有効 | 有効 | ./so_locations を自動更新。
出力のRPATH = shlibのRPATH ∩ -rpath
|
HP-UX 9 | ld +bpath1:path2
ld -Lpath1 -Lpath2 +b:
| 不可 | 不可 | +b: では
SunOS4と同様、-L が実行形式に記録される
|
AIX 4 | ld -blibpath:path:/usr/lib:/lib
ld -Lpath1 -Lpath2
| 有効 | 無視 | -L のみのときはSunOS4と同様、
-L が実行形式に記録される。
検索パスは実行形式・ライブラリ毎に独立。
|
QNX 6.1 (GNU ld) | (処置なし) | 無視 | 無視 | RPATHの埋め込みはできるのだが、バグのため 実行時には全く使われない。 LD_LIBRARY_PATHで逃げる。 |
QNX 6.2 (GNU ld) | ld -rpath=path1:path2
LD_RUN_PATH=path1:path2 ld ...
| 有効 | 有効 | shlibのRPATHは実行リンク時には使われる。 構築リンク時は明示的にいもづるに対する -Lか--rpath-link が必要 |
Darwin (MacOS X) | 有効 | 検索パスは環境変数での設定のみ。 (dyld(1)) | ||
(GNU binutils) | ld -rpath=path1:path2
LD_RUN_PATH=path1:path2 ld ...
| 有効 | 無視 | 実際は使われるOSによって細部は違うと思われる |
cc -c $(PICFLAGS)
で
シェアードライブラリに適したオブジェクトを作り、
ld
で *.so にまとめあげる
libS.so
の構築を例にしています。
OS | PICFLAGS | -shared | 備考 |
---|---|---|---|
SunOS 4 | cc -PIC
| ld -assert pure-text -o libS.so.1.0 *.o
| バージョン番号必須 |
SunOS 5 | cc -KPIC
| ld -G -z text -o libS.so *.o
| |
EWS-UX/V | cc [-Kconform_pic]
| ld -G -z text -o libS.so *.o
| |
NEWS-OS 6 | cc -KPIC
| ld -G -o libS.so.1 *.o;
ln libS.so libS.so.1
| リンク時には*.so が使われ、実行時は*.so.1
(shlibのDT_SONAME)が使われる。
-o libS.so とするとデフォルトのDT_SONAME = libS.so.1
|
IRIX 5 | cc -KPIC
| ld -shared -rdata_shared -o libS.so *.o
| |
HP-UX 9 | cc +z
| ld -b -o libS.sl *.o
| 拡張子は*.sl
|
AIX 4 | cc [-bM:SRE]
| ld -btextro -bM:SRE -bE:libS.sym -o libS.a *.o -lc
| arもshlibもファイル名は*.a 。
libS.symは dump -g arファイル を加工して
取り出す。
依存しているライブラリ (-lc ) も明示が必要。
|
QNX 6.x | qcc -shared
| qcc -shared -o libS.so *.o
| 標準では gcc/GNU ld が裏で起動されるが、 違うコンパイラでもqccでオプションの差を吸収する |
Darwin (MacOS X) | cc -dynamic -fPIC
| libtool [-v] -dynamic -o libS.dylib *.o -lc
| ld を直接叩くよりlibtoolがおすすめ。 拡張子は .dylib |
(gcc) | gcc -fPIC
| gcc -shared -o libS.so *.o
| バージョン番号の生成までは自動化されない |
NEWS-OS 6 の頁にもちょこっと書きましたが、
実行時リンカ (ld(1)とかdso(5)とかdld.sl(5)) にバージョン管理機構が
ある場合には、単に*.so
を作るだけではだめで、
*.so.1.0
を実体にして*.so
をシンボリックリンクにしたり、
ld のオプションでバージョン番号 (SO_NAME) を明示的に渡してやったり
しなきゃならんこともあります。
詳しくはマニュアルを見て下さい(いちいち書いとったらきりがない)。
なお、当ページはHTML3 Table Modelを使用しているため、 NetscapeやMSIEでは正常に表示されない可能性があります。