Linux下靜態庫(.a)和動態庫(.so) 的生成與使用

NO IMAGE

“  

              很多崩潰其實都發生在安靜裡,你坐在那裡一動不動,內心世界卻已經坍塌粉碎,一地狼藉。

                                                                                                                                                                                              ”

 

 

關於庫~

作為開發者應該不陌生~

經常會生成或使用一些庫,包括.a和.s以及.dll~

 

先來介紹下常見的幾種庫吧:

  • .o 是目標物件檔案,相當於windows中的.obj檔案。可由一個或多個.c /.cpp來生成
  • .a 為靜態庫,可以是一個或多個.o合在一起,用於靜態連線;多個.o檔案可以連結生成一個.exe的可執行檔案。靜態庫在程式編譯時會被連線到目的碼中,相當於將你使用庫裡的函式載入到程式裡,在編譯的時候直接編譯進去,這樣,在編譯之後執行程式時將不再需要該靜態庫。編譯之後程式檔案大,但載入快,隔離性也好。所以它的優點就顯而易見了,即編譯後的執行程式不需要外部的函式庫支援,因為所有使用的函式都已經被編譯進去了。當然這也會成為它的缺點,因為如果靜態函式庫改變了,那麼你的程式必須重新編譯。
  • .so 為動態庫(共享庫),類似windows平臺的.dll檔案。動態庫在程式編譯時並不會被連線到目的碼中,而是在編譯時僅引用,體積小,在程式執行到相關函式時才呼叫函式庫裡的相應函式,才被載入,因此在程式執行時還需要動態庫存在。多個應用程式可以使用同一個動態庫,啟動多個應用程式的時候,只需要將動態庫載入到記憶體一次即可。
  • .la 為libtool生成的共享庫,其實是個配置文件。可以用$file *.la檢視*.la檔案,或用vi來檢視。

簡而言之:

靜態庫在程式編譯時會被連線到目的碼中,程式執行時將不再需要該靜態庫

動態庫在程式編譯時並不會被連線到目的碼中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在

 

下面來說一說如何得到並使用這幾種檔案~

一:生成.o檔案

gcc -c test1.c test2.c

g  -c test1.cpp test2.cpp   

生成test1.o和test2.o,並不連結物件,所以不是可執行檔案。不用-o引數。

二:生成.a並使用

ar -r libtest.a test1.o test2.o    或者   ar rcs libtest.a test1.o test2.o

使用時:

載入a庫,即用gcc命令生成目標檔案時指明靜態庫名,gcc將會從靜態庫中將公用函式連線到目標檔案中。注意,gcc會在靜態庫名前加上字首lib,然後追加副檔名.a得到的靜態庫檔名來查詢靜態庫檔案。
 

g -o main main.cpp -L. -ltest   或者  g   -o main main.c libtest.a

-L.  代表當前路徑

 

三:生成.so並使用

g test1.cpp test2.cpp -fPIC -shared -o libtest.so

也可以根據.o檔案來生成

g  -shared -fPIC -o libtest.so test1.o test2.o

使用時:

g -o main main.cpp -L. -ltest

注意:在動態庫的使用時,由於其特殊性,編譯器會到指定的目錄去尋找動態庫,所以你需要告訴編譯器你庫存放的路徑,否則編譯會報找不到庫的錯誤,原因在於系統預設載入的動態連結庫路徑裡沒有找到你的動態庫,有三種解決方法:

1.在執行g -o main main.cpp -L. -ltest 前,執行 export LD_LIBRARY_PATH=$(pwd)

   或者: ❶g -o main main.cpp -L. -ltest -lstdc

                ❷LD_LIBRARY_PATH=. ./main

2.將你.so所在的目錄寫到/etc/ld.so.conf檔案裡,然後執行sudo ldconfig。

3.將你的.so放在/etc/ld.so.conf裡的路徑位置裡。

 

ending~

2018年7月28日17:05:20~

come on!