linux共享庫學習筆記(創建、加載)

一:含義

共享庫以.so爲後綴(shared object),應用程序執行期間被加載到內存,可同時被多個程序共享使用;


二:分類

real name:真正的庫文件,包含庫文件完整版本號(Major,Minor,Release);

soname:軟鏈接名字,應用程序運行時使用,只包含共享庫的主版本號(主版本號相同,函數接口一致),

                 因此應用程序的.dynamic段只記錄共享庫的soname,只要soname一致這個共享庫就可以使用;

linker name:在編譯鏈接時使用,gcc的-L選項應該指定爲linker name所在目錄;

//linker name
lrwxrwxrwx 1 cdos chronos     16  1月  5 14:35 libtspi.so -> libtspi.so.1.2.0*
//soname
lrwxrwxrwx 1 cdos chronos     16  1月  5 14:35 libtspi.so.1 -> libtspi.so.1.2.0*
//real name
-rwxr-xr-x 1 cdos chronos 417272  1月  5 14:35 libtspi.so.1.2.0*

三:創建共享庫 

1、生成目標文件,-fPIC(position-independent-coding)表示沒有綁定具體地址(運行時才能確定),如需要調試,可添加-g選項;

gcc -c -fPIC -o calc.o -g calc.c

2、生成動態庫文件   

gcc -shared -Wl,-soname,libcalc.so.1 -o libcalc.so.1.0 calc.o

生成soname爲libcalc.so.1(只是指定,並未生成鏈接文件),real name爲libcalc.so.1。

注:(1)前兩步可合併 gcc -shared -fPIC -Wl,-soname,libcalc.so.1 -o libcalc.so.1.0 calc.c
        (2)關於-Wa、-Wp、-Wl含義如下: 

       -Wa,<options>            Pass comma-separated <options> on to the assembler
       -Wp,<options>            Pass comma-separated <options> on to the preprocessor
       -Wl,<options>             Pass comma-separated <options> on to the linker
3、使用ldconfig生成soname文件
ldconfig -n ./

四:加載共享庫
1、編譯鏈接路徑:編譯時鏈接保證編譯通過,該部分不同於靜態鏈接,只是做一些基本的符號鏈接,不需要拷貝函數定義,搜索路徑順序如下;
(1)-L:指定鏈接時動態庫的路徑;
(2)LD_LIBRARY_PATH:指定鏈接路徑;
(3)默認路徑:/lib、/usr/lib、/usr/local/lib(有些系統不包含)

2、運行鏈接路徑:程序運行時加載動態庫的路徑,搜索路徑順序如下:
(1)ELF可執行文件動態段中DT_PATH所指定路徑。(編譯目標代碼時,對gcc加入鏈接參數-Wl,-rpath指定)
(2)LD_LIBRARY_PATH:指定動態庫搜索路徑;
(3)/etc/ld.so.cache中緩存的路徑。可通過修改配置文件/etc/ld.so.conf中指定的搜索路徑來改變;

(4)默認動態庫搜索路徑/lib,/usr/lib;


3、具體共享庫形式

(1)含版本號的共享庫,直接寫:gcc -o main main.c -L. libcalc.so.1 -Wl,-rpath,./
(2)libxxx.so形式的共享庫,寫爲-lxxx:gcc -o main main.c -L.  -lcalc  -Wl,-rpath,./


注:(1)C/C++程序裏經常會調用到外部庫函數,通過LD_LIBRARY_PATH指定共享庫路徑只適合調試階段使用,且有時會與系統庫衝突,此時我們可以使用第一種方法即編譯時加上-Wl,-rpath,該路徑會寫入ELF文件中。比如gcc -o main main.c -L. libcalc.so.1 -Wl,-rpath,./,程序會在加載libcalc.so.1庫時先在當前目錄下搜索;
        (2)通過ldd命令可查看具體使用的哪個路徑下的庫;          
cdos@chronos:~/calc/dynamic$ ldd main
	linux-vdso.so.1 =>  (0x00007ffeba7ee000)
	libcalc.so.1 => ./libcalc.so.1 (0x00007fcaf56f3000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcaf5313000)
	/lib64/ld-linux-x86-64.so.2 (0x000055871d6dd000)

參考:
http://www.jianshu.com/p/aed2ba9be14f
http://www.linuxidc.com/Linux/2016-06/132669.htm

http://blog.csdn.net/v6543210/article/details/44809405








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章