2016年2月6日土曜日

EL CapitanでDYLD_LIBRARY_PATHが無効になった!

Yosemiteで動いていたコマンドラインのプログラムが、El Capitanで共有オブジェクトのリンクエラーで実行できなくなった。El Capitanでは、SIPというセキュリティが導入されたらしく、この影響でDYLD_LIBRARY_PATHが無効になったらしい。

この問題を解決するために、このSIPを無効にすることもできるようだが、このプログラムを使用する全てのMacでこの作業をするのも面倒だし、Macのセキュリティ方針を尊重したい。そこで別の方法を考えることにした。

問題は何かというと、プログラムの実行時にDYLD_LIBRARY_PATHが使えないので、共有ライブラリを探すディレクトリが認識できていないことにある。ならば、DYLD_LIBRARY_PATHを使わずに、検索ディレクトリを指定できれば良い。

つまり、実行ファイルや共有ライブラリなどのオブジェクトファイルに検索パスを書き込んであげれば良い(たぶん)。自分でビルドできるプログラムであれば、gccのビルドオプションを指定することで解決できる。既にビルド済みのオブジェクトファイルで、ビルドする方法を知らない場合は、オブジェクトファイルを書き換えるツールがあるので、それを使って書き換えよう。

自分でビルドできる場合


gccでビルドする際に、次のオプションを追加する。

-Xlinker -rpath -Xlinker <検索ディレクトリ>

gccは内部で、ld(リンカ)を呼んでいる。ldは、実行ファイルや共有ライブラリを生成するコマンドだ。-Xlinkerはgccからld(リンカ)にオプションを渡す場合に使用するgccのオプションだ。つまり、ldには、「-rpath <検索ディレクトリ>」と認識される。
-rpathは、検索ディレクトリを指定するldのオプションである。

既にビルドされたオブジェクトを書き換える


まずは、オブジェクトにどんなrpathが指定されているか確認する必要がある。それには、otoolを使用する。

otool -l <オブジェクトファイル>

結果の中には、次のような記述がある

Load command 26
          cmd LC_RPATH
      cmdsize 64
         path /Users/hoge/Applications/root_v6.04.06/lib (offset 12)

「LC_RPATH」の項目のところの「path」がrpathである。

これを書き換えたい場合は、

install_name_tool -rpath  /Users/hoge/Applications/root_v6.04.06/lib <new path>

とする。

rpathを追加する場合は、

install_name_tool -add_rpath <new path>

とする。