生成靜態庫
若當前已有以下.o文件: obj1.o obj2.o
則gcc指令如下:
~$ ar -rsv libtest.a obj1.o obj2.o
ranlib指令:來對靜態庫的符號索引表進行更新
~$ ranlib libtest.a
注:linux下生成靜態庫.a文件有一個命名規則,必須 lib 開頭 .a 結尾, 即 libXX.a
使用靜態庫
1.使用路徑,如
~$ g++ test.o ./libtest.a -o test.out
若還依賴其他目錄下的庫,則也用這種絕對路徑方式鏈接,如
~$ g++ test.o ./libtest.a /usr/local/lib/libboost_thread.a -o test.out
注:以上指令./libtest.a 和 /usr/local/lib/libboost_thread.a 都是使用路徑指定要依賴的庫文件,並指定鏈接的文件是.a(靜態庫)
2.使用 -L 設置文件路徑,-l 代表庫名,例文件為 libtest.a 則參數為 -ltest
~$ g++ test.o -L./ -llog -L/usr/local/lib -lboost_thread -o test.out
其中:-L./ 表示當前目錄 -L/usr/local/lib表示 /usr/local/lib 目錄
但是:使用 -L -l 會帶來一個問題,該方式不指定鏈接庫類型,即靜態or動態(.a or .so),且優先鏈接動態庫
這會帶來一個問題:以上條指令為例, /usr/local/lib 下包含了boost的靜態和動態庫文件,當使用 -L/usr/local/lib -lboost_thread 時,鏈接可通過,可生成可執行文件,但是一執行就會出現提示 error while loading shared libraries: libboost_thread.so.1.49.0: cannot open shared object file: no such file or directory
這是因為使用 -L/usr/local/lib -lboost_thread 時,優先鏈接了動態庫,而執行時卻發現 .so 文件不在,相當於windows下的dll機制, -L./ -llog 鏈接正常是因為編譯器在./下沒找到相關的 .so 文件,此時才去加載 .a 文件
解決這個問題的辦法:設法讓可執行文件找到.so文件。也許你會把那個.so 文件拷貝到 可執行文件目錄下,你會發現這是行不通的。linux里有一個環境變量叫 LD_LIBRARY_PATH, 可以理解為windows的 Path 環境變量,可在終端輸入 echo $LD_LIBRARY_PATH 輸出該變量值,我們只要設置該變量值到相應目錄就可以解決找不.so 文件的問題了。
~$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
再執行文件,OK,問題解決。
注: 在終端用 export 指令只是暫時改變 LD_LIBRARY_PATH 的值,重啟之后該值又為空,
靠譜方法為:在~/.bashrc 或者 ~/.bash_profile 中加入該 export 語句,前者在每次登陸和每次打開 shell 都讀取一次,后者只在登陸時讀取一次。習慣是加到 ~/.bashrc 中,在該文件的未尾可采用如下語句來使設置生效:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
修改完后,記得關掉當前終端並重新打開一個新的終端,從而使上面的配置生效。
export 后面的語句不能包含空格
另外: ldd 指令 可以查看可執行文件對哪些動態庫有依賴關系