我試圖在沒有root的Solaris服務器上編譯samtools。 Samtools依賴於zlib。此機器上的系統zlib未編譯時支持大文件,因此針對此版本編譯samtools具有預期的效果:samtools僅處理小文件。我需要它能夠處理大文件。幸運的是,有一個由admin在/usr/local/apps/zlib-1.2.5/編譯的zlib版本,支持大文件。我可以通過向CFLAGS添加-R /usr/local/apps/zlib-1.2.5/lib
來對此進行編譯,但這似乎不起作用。症狀如下:運行時鏈接程序忽略solaris上可執行文件中的RPATH
當我嘗試運行samtools,它與此錯誤崩潰:
ld.so.1: samtools: fatal: relocation error: file samtools: symbol gzopen64: referenced symbol not found
如果我添加/usr/local/apps/zlib-1.2.5/
到LD_LIBRARY_PATH,然後samtools工作正常。
與LDD分析samtools和readelf產生如下:
$ 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。
那麼如何在不使用LD_LIBRARY_PATH的情況下強制samtools在運行時在/usr/local/apps/zlib-1.2.5/lib
中搜索?
編輯:文檔here似乎表明-R
選項是做正確的事。但它不起作用。
嘎!你是對的!但是我的init文件都沒有設置它,所以我不知道它是如何設置的。不過,取消它會使事情發揮作用。看起來像一個錯誤配置的服務器。我將在我的shell初始化文件中解除它並通過電子郵件發送給系統管理員。 – 2010-11-19 22:09:35
現在我已經平靜了一點,我想補充一句:「謝謝。」 – 2010-11-19 22:40:31
沒問題;樂意效勞。 – bosmacs 2010-11-20 15:14:56