dynamic link libraryを実行ファイルのそばに配置する

Windowsの場合EXEと同じ場所にDLLを置けば、PATHが通って無くてもそのDLLが動的リンクされます。
Macの場合はどうするかのメモ。

DYLD_LIBRARY_PATH や DYLD_FALLBACK_LIBRARY_PATH を指定する余地があるなら不要な話です。


例えばopenCVのdylibをリンクしようとしている場合、otoolでみると以下の様になります。

$ otool -L sample
sample:
	lib/libopencv_core.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
	lib/libopencv_imgcodecs.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

これを

$ install_name_tool \
  -change lib/libopencv_core.3.0.dylib @executable_path/libopencv_core.3.0.dylib \
  -change lib/libopencv_imgcodecs.3.0.dylib @executable_path/libopencv_imgcodecs.3.0.dylib \
  sample

$ otool -L sample
sample:
	@executable_path/libopencv_core.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
	@executable_path/libopencv_imgcodecs.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

とすることで「sample と同じ場所にある libopencv_*.dylib」になります。

・・・しかし上の場合は libopencv_imgcodecs.3.0.dylib が libopencv_core.3.0.dylib に依存しています。

$ otool -L libopencv_imgproc.3.0.dylib 
libopencv_imgproc.dylib:
	lib/libopencv_imgproc.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
	lib/libopencv_core.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)      #<=コレ
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

そこでこれらも再帰的に @executable_path に置き換えます。

$ install_name_tool \
  -change lib/libopencv_imgproc.3.0.dylib @executable_path/libopencv_imgproc.3.0.dylib \
  libopencv_imgproc.3.0.dylib

$ otool -L libopencv_imgproc.3.0.dylib
libopencv_imgproc.3.0.dylib:
	lib/libopencv_imgproc.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
	@executable_path/libopencv_core.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)


再帰的に処理する部分が厄介なので「カレントディレクトリに集めておいてまとめて更新」するスクリプトを書きました。
https://gist.github.com/suzumura-ss/01d6e0f42234d3110ea1