Linux編譯連結之庫
簡要記錄linux下編譯靜態庫和動態庫的方法,
1.靜態庫(*.a)
編譯:cc -Wall -c ctest1.c ctest2.c
建立靜態庫:ar -cvq libctest.a ctest.o ctest2.o
顯示靜態庫中的檔案列表(建立符號表):ar -t libctest.a
連結使用:
cc -o executable_name prog.c libctest.a
cc -o executable_name prog.c -L/path/tolibrary_directory -lctest
列出靜態庫中包含的目標檔案
nm /usr/lib/libopencv_ts.a
2.動態庫(*.so)
下述命令模組,建立共享動態庫libctest.so.1.0,同時進行符號連結;
gcc -Wall -fPIC -c *.c
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
mv libctest.so.1.0 /opt/lib
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so
Wall: 顯示警告資訊;
-fPIC: 即position independent code,編譯時相對位置查詢
-shared: 生成動態庫的選項
-Wl,option: 傳遞引數,此處"-soname libctest.so.1",即命名;
-o: 目標名稱
如果為了省事兒,可以採用下述命令生成.so
gcc *.c -fPIC -shared -o libctest.so.1
在呼叫動態庫時,可以採取下述模式
gcc -Wall -I/path/to/include_files -L/path/to/libraries prog.c -lctest -o prog
//like this
gcc -Wall -L/ot/lib prog.c -lctest -o prog
查詢執行檔案的依賴庫: ldd prog
2.1 配置動態庫路徑 Libary Path
為了可執行檔案在執行時能夠找到動態庫,需要配置路徑(下述方法至少採取一個)
2.1.1.修改/etc/ld.so.conf執行ldconfig
在/etc/ld.so.conf檔案下加入動態庫所在的目錄,然後以root執行ldconfig
ps:
ldconfig 命令的用途,主要是在預設搜尋目錄(/lib和/usr/lib)以及動態庫配置檔案/etc/ld.so.conf內所列的目錄下,搜尋出可共享的動態連結庫(格式如前介紹,lib*.so*),進而創建出動態裝入程式(ld.so)所需的連線和快取檔案.快取檔案預設為 /etc/ld.so.cache,此檔案儲存已排好序的動態連結庫名字列表.
2. 向library cache內增加特殊路徑的快取(as root)
ldconfig -n /lib_path
此處lib_path為需求庫所在的目錄;當然也可以使用相對路徑,以方便移動;此種方式有一個缺點,在關機之後library cache將會丟掉所加的內容。
3.修改環境變數LD_LIBRARY_PATH
不同版本的linux/unix中表示庫檔案路徑的變數名稱不統一,此處以linux/solaris為例,另外mac os x: DYLD_LIBRARY_PATH
export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PAT
或者在~/.bashrc末尾加入:
...
if [ -d /opt/lib ];
then
LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH
fi
...
export LD_LIBRARY_PATH
總的說來,編譯器會先在path資料夾下搜尋libxxx.so檔案,如果沒有找到,繼續搜尋libxxx.a(靜態庫)。