gcc/g++動態鏈接庫和靜態庫的鏈接順序


轉自:http://withc8212.blog.163.com/blog/static/11656983820109263562854/

so文件:動態庫
a文件: 靜態庫
exe文件:可執行程序(linux下以文件屬性來標示是否是可執行文件,與后綴名無關)

經過自己寫的一些測試程序,大致了解了下gcc中鏈接順序問題,總結出以下幾點:
1,動態庫中可以包含另一個靜態庫,通過參數 -lxxx 把靜態庫libxxx.a加入so文件中,這樣so文件中
   就包含了libxxx.a的所有實現。當然,如果不包含libxxx.a也沒有問題,這樣生成的so會小一點。
   如果不包含libxxx.a,最終使用這個so的可執行文件,在其生成時必須加入 -lxxx。
2, 2個so文件可以包含同一個靜態庫libxxx.a,最終生成exe文件時,不會產生沖突。更廣泛的說,生成
   exe文件時候,可以鏈接多個so文件和a文件,如果其中的a文件有多份實現,最終只會有一份生效,其他
   都會被忽略。不用擔心沖突。
3,當生成exe時候,當a文件有多份實現時,最左邊指定的a文件才生效。

具體例子來說:
     libstatic.a :   一個靜態庫文件
     libdynamic1.so:需要使用libstatic.a中的函數,但是沒有包含libstatic.a
     libdynamic2.so:需要使用libstatic.a中的函數,包含libstatic.a
     libdynamic3.so:需要使用libstatic.a中的函數,也包含libstatic.a
     test.exe:最終的生成的可執行文件(linux對后綴沒有要求,為了說明文件,姑且用exe后綴來表示可執行文件)
     
     gcc -o test.exe -ldynamic1 :錯誤,libdynamic1.so中沒有包含libstatic.a,找不到libstatic.a的實現。
     
     gcc -o test.exe -ldynamic1 -lstatic:正確,so中沒有,但是指定了libstatic.a,可以編譯過
     
     gcc -o test.exe -ldynamic2 :正確,libdynamic2.so中有libstatic.a的實現。
     
     gcc -o test.exe -ldynamic1 -ldynamic2:正確,libdynamic1.so中沒有libstatic.a,但是libdynamic2.so中有。
     
     gcc -o test.exe -ldynamic2 -ldynamic3:正確,雖然libdynamic2.so和libdynamic3.so都含有靜態庫,但是不會沖突,
                                           最終只會有一份存在,並且是libdynamic2.so中的靜態庫有效。
                                           
     gcc -o test.exe -ldynamic2 -ldynamic3 -lstatic:同樣正確,最終只會有一份存在,並且是libdynamic2.so中的靜態庫有效。
     
     gcc中庫的鏈接順序是從右往左進行,所以要把最基礎實現的庫放在最后,這樣左邊的lib就可以調用右邊的lib中的代碼。同時,當一個函數的實現代碼在多個lib都存在時,最左邊的lib代碼最后link,所以也將最終保存下來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM