[英]What is added to an executable when linking with a shared library?
如果我想創建一個與靜態庫鏈接的C ++程序,那么最終的可執行文件將包含我程序中的代碼和庫中的代碼(我認為......!)。 但是我不確定當我與共享庫鏈接時會發生什么。
假設我鏈接了一個名為libfoo.so
的庫,在我的CMakeLists.txt
文件中指定了target_link_libraries(${PROJECT_NAME} foo)
。 我假設最終的可執行文件將包含有關此庫的一些信息,但不包含完整的代碼。 這是什么其他信息? 而且,庫是否必須在用戶的系統上完全被稱為libfoo.so
?
鏈接到動態庫時,鏈接器將在程序的動態部分中添加NEEDED
條目。 然后動態加載器將使用它們來定位庫並使用庫來解決任何未定義的動態符號。
請注意,未定義的動態符號與期望找到它們的動態庫之間沒有任何關聯。 有時他們會被發現在另一個圖書館,有趣的事情可能發生。
存儲在NEEDED
條目中的特定名稱取決於庫是否在其動態部分中具有SONAME
條目:
SONAME
,則其內容將被復制到程序的NEEDED
SONAME
,將存儲鏈接器命令中使用的庫的文件名。 您可以使用以下命令檢查庫或程序的動態部分的內容:
$ objdump -p program
這在實踐中如何使用? 那么,大多數(所有?)linux發行版使用以下方案,系統庫(采取libfoo.so
):
/usr/lib/libfoo.so.1.2
或其任何版本。 /usr/lib/libfoo.so.1
和/usr/lib/libfoo.so
庫的符號鏈接。 SONAME
是libfoo.so.1
。 /usr/lib
設置為動態庫路徑。 這樣,當您與-lfoo
鏈接時,它將找到符號鏈接libfoo.so
,但會將SONAME
記錄為libfoo.so.1
。 當程序運行時,它將找到另一個符號鏈接並加載庫。
使用此技巧,以便您可以安裝ABI兼容,改進的libfoo.so.1.3
和ABI不兼容的較新的libfoo.so.2.1
,舊程序將加載舊庫,而新的編譯將使用新庫。
另請注意,環境變量LD_PRELOAD
, LD_LIBRARY_PATH
和其他因素會影響運行時行為。 有關更多詳細信息,請閱讀man ld.so
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.