root を持たない Solaris サーバーでsamtoolsをコンパイルしようとしています。Samtools は zlib に依存しています。このマシンのシステム zlib は大きなファイルをサポートするようにコンパイルされていないため、このバージョンに対して samtools をコンパイルすると、期待どおりの効果が得られます。samtools は小さなファイルのみを処理します。大きなファイルを処理できるようにする必要があります。幸いなことに、管理者によってコンパイルされたバージョンの zlib が /usr/local/apps/zlib-1.2.5/ にあり、大きなファイルをサポートしています。CFLAGS に追加することでこれに対してコンパイルできます-R /usr/local/apps/zlib-1.2.5/lib
が、これは機能しないようです。症状は次のとおりです。
samtools を実行しようとすると、次のエラーでクラッシュします。
ld.so.1: samtools: fatal: relocation error: file samtools: symbol gzopen64: referenced symbol not found
LD_LIBRARY_PATHに追加/usr/local/apps/zlib-1.2.5/
すると、samtools は正常に動作します。
ldd と readelf を使用して samtools を分析すると、次の結果が得られます。
$ ldd -r samtools
libnsl.so.1 => /usr/lib/libnsl.so.1
libsocket.so.1 => /usr/lib/libsocket.so.1
libresolv.so.2 => /usr/lib/libresolv.so.2
libm.so.2 => /usr/lib/libm.so.2
libcurses.so.1 => /usr/lib/libcurses.so.1
libz.so => /usr/lib/libz.so
libc.so.1 => /usr/lib/libc.so.1
libmp.so.2 => /usr/lib/libmp.so.2
libmd.so.1 => /usr/lib/libmd.so.1
libscf.so.1 => /usr/lib/libscf.so.1
libdoor.so.1 => /usr/lib/libdoor.so.1
libuutil.so.1 => /usr/lib/libuutil.so.1
libgen.so.1 => /usr/lib/libgen.so.1
symbol not found: gzopen64 (samtools)
$ ldd -s samtools
...(snip)...
find object=libz.so; required by samtools
search path=/usr/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib (LD_LIBRARY_PATH)
trying path=/usr/lib/libz.so
libz.so => /usr/lib/libz.so
...(snip)...
$ readelf -d samtools | grep RPATH
0x0000000f (RPATH) Library rpath: [/usr/local/apps/zlib-1.2.5/lib:/usr/local/apps/gcc-4.5.1/lib]
これ/usr/local/apps/zlib-1.2.5/lib
は明らかにバイナリの RPATH にあり、実行時に共有ライブラリを検索することになっていると私は理解しています。ただし、ldd -s
このディレクトリは検索されないことを示しています。このパスを LD_LIBRARY_PATH に追加して ldd コマンドを再実行すると、期待どおりの効果が得られます。ディレクトリが検索され、正しいバージョンの libz が検出されます。
/usr/local/apps/zlib-1.2.5/lib
では、 LD_LIBRARY_PATH を使用せずに実行時にsamtools に強制的に検索させるにはどうすればよいでしょうか?
編集:ここのドキュメントは-R
、オプションが正しいことを示しているようです。しかし、うまくいきません。