Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

一般に動的ライブラリを扱う場合には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ディレクトリが作られるようになるので、これらをまとめて配布すれば実行が可能になります。

qoncept
リアルタイム画像認識を専門にした会社です。近年はスポーツにおける認識技術の応用に力を入れています。
https://qoncept.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away