LoginSignup
45
39

More than 5 years have passed since last update.

macOSのコマンドラインアプリでdylibをよろしく扱う方法

Posted at

一般に動的ライブラリを扱う場合には2つの方針があると思います。

  • ライブラリはシステムにインストールして、アプリはそれを使う
  • ライブラリをアプリ用に用意してまとめて配布する

後者の場合のよろしいやり方について調べたのでまとめました。

構成

コマンドラインアプリと一緒にlibディレクトリを置き、その中にdylibが入っているという構成にします。ファイルをリストすると下記のようになります。

  • app_dir/app
  • app_dir/lib/libfoo.dylib
  • app_dir/lib/libbar.dylib

ライブラリはfooとbarがあって、barはfooに依存しているとします。

ライブラリの本体パスと依存パスの設定

macのdylibはバイナリ内部に自身のパスと依存するライブラリ達のパスが書き込まれています。この自身のパスは下記のようにして得られます。

$ otool -D libfoo.dylib

また、依存するライブラリのパスは下記のようにして得られます。

$ otool -L libfoo.dylib

まず、自身のパスを @rpath 直下の形に書き換えます。

$ install_name_tool -id "@rpath/libfoo.dylib" libfoo.dylib
$ install_name_tool -id "@rpath/libbar.dylib" libbar.dylib

また、依存するライブラリのうち、一緒に配布するものは @rpath 直下を探すように書き換えます。この例ではbarの中にfooへの依存があるのでこれを修正します。コマンドの引数として元々のパスを指定しますが、これは先述の方法で取得した結果を用います。

$ install_name_tool -change "/Users/omochi/temp/libfoo.dylib" "@rpath/libfoo.dylib" libbar.dylib

ここで設定した @rpath は変数で、アプリが起動する時に変数展開されます。

アプリの実行時rpathの設定

アプリの実行時のrpath変数はビルド設定で指定できます。Xcode > ターゲット設定 > Build Settings > Runpath Search Pathesを下記の値に設定します。

@executable_path/lib

@executable_pathは変数で、アプリ実行時のアプリ自体のファイルパスになります。これにlibを付けておくことで、同じディレクトリにあるlibディレクトリの中からライブラリが探索されます。

アプリのビルド時のライブラリの設定

dylibはxcode上で登録しておき、アプリターゲットに対してリンクされるよう設定しておきます。さらに、ビルド時にアプリと一緒にlibディレクトリを作りその中にコピーされるように、Build PhasesでCopy Filesの設定を作ります。DestinationはProducts Directoryにして、Subpathは lib にします。そしてdylib全てを登録します。

アプリの状態

rpathの設定内容はアプリバイナリ自体に書き込まれます。また、アプリの依存ライブラリは、リンクしたライブラリに書かれていた、ライブラリ自身のパスが書き込まれます。これらは下記のコマンドで確認できます。

otool -l app

配布

これで、ビルドした際にProductsの中にアプリとlibディレクトリが作られるようになるので、これらをまとめて配布すれば実行が可能になります。

45
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
39