2017-03-18 36 views
0

這裏有一個簡單的例子:爲什麼在構建共享庫後無法重命名共享庫?

lib.c:

#include <stdio.h> 

void hello_world(void) { 
    puts("Hello, world!"); 
} 

program.c:

void hello_world(void); 

int main() { 
    hello_world(); 
    return 0; 
} 

如果我通常編譯庫,並將其鏈接,一切工作正常:

$ cc lib.c -fPIC -shared -o libmylib.dylib 
$ cc program.c -L. -lmylib 
$ ./a.out 
Hello, world! 

但如果我建立之後(但建設程序之前),重命名庫,這是行不通的:

$ cc lib.c -fPIC -shared -o totally_different_name.dylib 
$ mv totally_different_name.dylib libmylib.dylib 
$ cc program.c -L. -lmylib 
$ ./a.out 
dyld: Library not loaded: totally_different_name.dylib 
    Referenced from: /private/tmp/./a.out 
    Reason: image not found 
[1] 13229 abort  ./a.out 

爲什麼會出現這種情況?爲什麼dyld尋找原始的圖書館名稱?

這在Linux上運行正常,但是當我嘗試在macOS上它完全失敗(我不知道它是macOS vs Linux的東西,還是鏗鏘vs gcc的東西,因爲我在macOS和gcc上使用了clang在Linux上)。

如果相關,cc --versionApple LLVM version 8.0.0 (clang-800.0.42.1) x86_64-apple-darwin16.4.0

+0

執行'LD_LIBRARY_PATH =。 。/ a.out'有所作爲? – dhke

+0

@dhke:不,也不適用於'DYLD_LIBRARY_PATH'。 – Cornstalks

+0

'otool -L。/ a.out'應該給你程序聲明的依賴列表。至少這可能有助於縮小問題的範圍。 – dhke

回答

0

感謝Florian Zwoch's comment,我找到了解決這個問題的方法。重命名dylib後運行此命令:

install_name_tool -id libmylib.dylib libmylib.dylib 

該命令將更改dylib的內部標識。命令語法是install_name_tool -id <new-id> <dylib-path>

本來,dylib的ID爲totally_different_name.dylib。重命名該文件不會更改其在內部存儲的ID,並且必須單獨使用install_name_tool進行更新。

+0

我的答案顯示瞭如何解決問題,但我缺乏必要的知識深度來解釋更好的情況以及爲什麼。如果有人發佈了一個更好地解釋dylib如何工作的答案,那麼clang如何構建它們,macOS如何使用它們,以及爲什麼需要額外的步驟,我會很樂意接受這個答案。 – Cornstalks