dynamic library の OS Xの補足

  • 45
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

前々回にFreeBSDでの静的ライブラリと動的ライブラリについて書いた。
そのときに、OS Xでもほぼ同じ、と書いたのだが、ここでは違いについて書く。

まず、FreeBSDやLinuxでは動的ライブラリのファイル名は *.so だが、OS Xでは *.dylib である。(試しに*.soにしても動いたので、拡張子はなんでも良いようだが)
そして、ライブラリの依存関係を調べるコマンドは ldd ではなく otool -L を使う。

リンク時のオプションで -L と -l を使うのは同じ。
ldには-rpathオプションはあるが -rpath-linkオプションはない。(リンク時には-Lオプションと標準パスだけで探すらしい)
そして、-rpathオプションの扱いもFreeBSDとは違う。

基本

動的ライブラリの作成

前々回と同じソースで、libfunc2.dylibを生成してみる

% cc -c -fPIC func2.c
% cc -shared -install_name @rpath/libfunc2.dylib -o libfunc2.dylib func2.o

FreeBSDとの違いは、-install_nameオプションでライブラリのinstall nameを指定すること。

動的ライブラリのリンク

% cc -o test2 test2.c -L. -lfunc2 -Wl,-rpath,.

これで何が起きるかと言うと、実行ファイルのリンク時に指定した-rpathオプションのパス(.)が、ライブラリの@rpathと置き換えられる。
このため、実行時には./libfunc2.dylibを見つけて動的リンクしてくれる。

% otool -L test2
test2:
        @rpath/libfunc2.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
% otool -L libfunc2.dylib
libfunc2.dylib:
        @rpath/libfunc2.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
% otool -D libfunc2.dylib
libfunc2.dylib:
@rpath/libfunc2.dylib

otool -Dは、動的ライブラリのid nameを表示するコマンド。

ライブラリが固定のディレクトリにインストールされる場合、わざわざ@rpathを使う必要はないので、以下のように書くことができる。

% cc -c -fPIC func2.c
% cc -shared -install_name ./libfunc2.dylib -o libfunc2.dylib func2.o
% cc -o test2 test2.c -L. -lfunc2

この場合は実行ファイルのリンク時に-rpathオプションは不要になる。(実際には./ではなくインストールディレクトリを指定すること)

たぶん、通常のコマンドラインアプリを作成する分には、ここまでの知識があれば良い。(むしろ、OS Xの場合は-rpathを使わない方が簡単だと思う)

しかし、OS Xの場合は、一般に配布されるアプリケーションは.appと言う形式になる。
.appは、実際にはディレクトリで、中には実行ファイルの他に必要なライブラリや、リソースファイルなどが含まれている。
このようなときに、.appがどこに置かれても動作するためには、ライブラリが/usr/local/libや/opt/local/libにあることが期待できず、.app内の相対パスで指定されなければならない。

man dyldすると、@rpathの他に、@executable_path@loader_pathと言うものが見つかる。それぞれ、実行ファイルのパスや、フレームワークのパスに置き換えられる。
ただ、通常.appを作成するときには、XcodeやQt Creatorなどを使用すると思うので、自分でこの辺の細かい指定をすることはあまりないのではないかと思う。
ライブラリを作成するときに、こんなものもあったかな〜と思い出すくらいで良いのでは。(と言うか、現時点であまり理解していない)

libtool

OS Xも、Xcodeを入れると(?)、/usr/bin/libtoolが入る。
が、このlibtoolがGNUのlibtoolとは違うもののようで、同じ使い方はできない。

OS Xのlibtoolができることは、動的ライブラリを作ることと、静的ライブラリを作ることだけである。
*.lo*.la も作らないので、同じ名前の完全な別物と考えた方が良いだろう。

% cc -c -fPIC test4.c
% libtool -dynamic -o libfunc4.dylib -install_name /usr/local/lib/libfunc4.dylib func4.o
ld: warning: -macosx_version_min not specified, assuming 10.10
% cc -o test4 test4.c -L. -lfunc4

ここで試した内容は、githubの osx ブランチにcommitしてある。
https://github.com/false-git/libstudy/tree/osx