linux生成.so庫如何指定添加其他的.so庫


開發環境:

  CentoOs(Linux )

 

起因:

  最近在項目開發過程中需要生成.so文件來給其他的程序調用,而我的這部分程序又需要調用其他的.so,這對於一個剛剛入職的程序猿來說着實有些令人着急,大致的項目需要如圖,其中libStd.so是項目的標准庫,和我的.so在同一父目錄下,libmkl_xxx.so是mkl庫,在系統目錄下。

當時由於是第一次生成.so(年少無知),照着網上的代碼直接就編譯了,然后其他同事在使用時出現undefined symbol <something>.

錯誤代碼:

  

g++ -c -g -fPIC Dir1/*.cpp Dir2/*.cpp -I/opt/intel/mkl/include

g++ -shared -o libMyLib.so *.o

 概念:

  函數庫可以分成動態庫(dynamic)和靜態庫(static),靜態庫相當於把你的所有文件都打了包,以后要跟其他程序集成的話就得把整個包給集成進去,這往往導致最終程序會變得很大,而且也不易升級、維護,動態庫相當於一個開放的包,大家都可以用,只要你鏈接到它,你也可以用,我鏈接到之后我也可以用,是公共、獨立的。兩者更進一步的區別參考鏈接【1】在不同系統上這兩者命名稍微有些不同:

(后綴) Windows Linux
靜態庫 .lib .a
動態庫 .dll .so

 

  .so文件是shared object文件,即共享對象,也就是說其在加載后是可以被多個進程所共享,至於如何實現可以參考鏈接【2】。

  -fPIC: Position Independent Code,參見鏈接【2】

  -shared:表示產生的是共享對象

  由於在鏈接產生共享對象的時候需要檢查語法和語義,所以在鏈接階段需要指定鏈接的庫名-l和庫所在位置-L【1】(這也是我出現上面的錯誤的原因)

解決方案:

  

g++ -c -g -fPIC Dir1/*.cpp Dir2/*.cpp -I/opt/intel/mkl/include

g++ -shared -o libMyLib.so *.o -lStd -L../PATH_A/TO/Bin -lmkl_xxx -L/PATH_B/TO_MKL_XXX

 后續:

  為了查看自己生成的庫鏈接對不對,可以使用

ldd MyLib

  這條指令用於查看依賴項,即你的庫有沒有鏈接成功

  可以看到上面的libBarbeque.so沒有找到,這是為什么的?我明明在鏈接階段指定了對應的.so才對?先別急,這是因為你雖然剛剛指定庫,但是系統在查找時默認只會在當前路徑或者系統指定的LD_LIBRARY_PATH目錄下查找,所以你只需要把依賴的.so放到當前目錄下,或者用配置環境變量的方式使系統知道你需要在哪里找,可以參考鏈接【3】(記得是修改LD_LIBRARY_PATH不是默認的PATH!)

  最后注意,在實際運行的時候也需要指定對應的庫和路徑,在LD_LIBRARY_PATH中添加.so所在文件夾,這樣可以確保程序順利調用

【1】http://blog.csdn.net/nieyinyin/article/details/6890557:linux中的.so和.a文件

【2】http://www.cnblogs.com/cswuyg/p/3830703.html:linux共享對象之編譯參數fPIC

    簡要提綱(僅供自己觀看,有理解不對的請諒解!)

     1.如果不采用PIC,相當於給每個進程開專線,這樣物理內存利用率不高;PIC在我認為就是建立了一個中轉站,大家先來中轉站,再轉到對應的模塊;

【3】http://www.cnblogs.com/hust-chenming/p/4943268.html:linux查看和修改PATH環境變量的方法


免責聲明!

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



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