2017-09-08 78 views
0

使用通過'node-gyp'傳遞的鏈接器命令行選項我指定我希望程序鏈接的庫路徑和庫名稱。但生成的可執行文件不會引用我指定的文件,它在/usr/lib中引用了不同的名稱。爲什麼鏈接器更改共享庫名稱?

我使用binding.gyp中的庫部分引用本地lib目錄。

 'libraries': [ 
     '-lao-oboe', 
     '-L<(module_root_dir)/lib/', 
     '-Wl,-rpath-link,<(module_root_dir)/lib/', 
     '-Wl,-rpath,<(module_root_dir)/lib/' 
     ], 

node-gyp似乎是正確地傳遞選項,因爲鏈接器,如果我改變-L路徑,一個不包含libao-oboe.so返回/usr/bin/ld: cannot find -la-oboe。如果我更改所請求的庫的名稱與lib中的名稱不同,鏈接器也會返回錯誤。

問題是本地庫在運行時不會被加載。 ldd顯示node-gyp輸出文件未引用指定的文件 - 它正在引用一個名稱完全不同的庫 - /usr/lib/liboboe-1.0.so.1。見ldd輸出的第二行:

linux-vdso.so.1 => (0x00007ffee20f5000) 
liboboe-1.0.so.1 => /usr/lib/liboboe-1.0.so.1 (0x00007fa476377000) 
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa475ff5000) 
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa475c2b000) 
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa475a27000) 
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa47580a000) 
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa475501000) 
/lib64/ld-linux-x86-64.so.2 (0x00007fa476922000) 
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa4752eb000) 

本地庫目錄包含:

lrwxrwxrwx 1 bruce bruce  15 Sep 8 02:50 libao-oboe.so -> libao-oboe.so.1` 
-rw-r--r-- 2 bruce bruce 1640848 Aug 31 15:01 libao-oboe.so.1 

它是本地庫文件,libao-oboe.so.1是一樣的系統庫文件中被引用的情況下可執行文件(如ldd所示):/usr/lib/liboboe-1.0.so.1

鏈接器是否以某種方式注意到本地文件是相同的(通過哈希或某個簽名)並從標準位置替換庫文件?

爲什麼node-gyp的輸出文件引用了一個從未被請求的庫文件作爲構建過程的一部分?

+0

.so文件中的'soname'字段最終替換了-l選項中指定的文件名。我不明白到底發生了什麼,但是如果我使文件名與soname匹配,那麼就沒有問題了。 – bmacnaughton

回答

1

根據wikipedia - soname.so文件中的SONAME字段是「基本兼容版本」。從我在上述問題中發現的行爲可以清楚地看出,ld將SONAME插入到鏈接到共享庫的文件中 - 而不是在ld命令中指定的文件名。

重命名.so文件不會更改SONAME,因此鏈接到重命名文件的可執行文件將嘗試加載由SONAME字段命名的庫,而不是文件名。

我的解決方案是不重命名該文件。