在前面介紹了靜態(tài)庫的構(gòu)建,這里談一下動態(tài)庫的構(gòu)建,同樣以案例的方式描述,希望案例可起到模板的作用。
首先新建一個測試文件,test.c
#include
int main()
{
printf("hello world\\n");
return 0;
}
它是可以編譯成功的
將可執(zhí)行文件a.out刪除
添加文件,如靜態(tài)庫中所示(這里省略掉了)
編譯運行,同樣可以輸出
$ gcc test.c func.c
:~/Documents/clan/test2$ tree
.
├── a.out
├── func.c
├── func.h
└── test.c
0 directories, 4 files
:~/Documents/clan/test2$ ./a.out
hello world
30
到此說明,所有文件是正常的,程序是正常的。
下面清除a.out文件,用動態(tài)庫的方式實現(xiàn)。
: ~/Documents/clan/test2$ gcc test.c func.c
:~ /Documents/clan/test2$ tree
.
├── a.out
├── func.c
├── func.h
└── test.c
0 directories, 4 files
: ~/Documents/clan/test2$ ./a.out
hello world
30
:~ /Documents/clan/test2$ rm a.out
:~/Documents/clan/test2$ tree
.
├── func.c
├── func.h
└── test.c
0 directories, 3 files
: ~/Documents/clan/test2$ gcc -fPIC -shared -o libfunc.so func.c
:~ /Documents/clan/test2$ tree
.
├── func.c
├── func.h
├── libfunc.so
└── test.c
0 directories, 4 files
: ~/Documents/clan/test2$ gcc test.c libfunc.so
:~ /Documents/clan/test2$ tree
.
├── a.out
├── func.c
├── func.h
├── libfunc.so
└── test.c
0 directories, 5 files
:~/Documents/clan/test2$ ./a.out
./a.out: error while loading shared libraries: libfunc.so: cannot open shared o
`
很可惜,最后在鏈接動態(tài)庫編譯的時候,失敗了,提示不能找到文件
error while loading shared libraries: libfunc.so: cannot open shared object file: No such file or directory
在編譯程序時,使用動態(tài)鏈接庫和靜態(tài)庫是一致的,使用”-l庫名”的方式,在生成可執(zhí)行文件的時候會鏈接庫文件。
-L指定動態(tài)鏈接庫的路徑,-ldtiger鏈接庫函數(shù)tiger。-ltiger是動態(tài)庫的調(diào)用規(guī)則。Linux系統(tǒng)下的動態(tài)庫命名方式是lib*.so,而在鏈接時表示位-l*,*是自己命名的庫名。
:~/Documents/clan/test2$ rm a.out
:~/Documents/clan/test2$ gcc test.c -L./ -lfunc
:~/Documents/clan/test2$ tree
.
├── a.out
├── func.c
├── func.h
├── libfunc.so
└── test.c
0 directories, 5 files
:~/Documents/clan/test2$ ./a.out
./a.out: error while loading shared libraries: libfunc.so: cannot open shared object file: No such file or directory
錯誤是因為程序運行時沒有找到動態(tài)鏈接庫造成的。程序編譯時鏈接動態(tài)庫和運行時使用動態(tài)鏈接庫的概念是不同的,在運行時,程序鏈接的動態(tài)鏈接庫需要在系統(tǒng)目錄下才行。為此,需要設(shè)置臨時環(huán)境變量
:~/Documents/clan/test2$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
:~/Documents/clan/test2$ gcc test.c -L./ -lfunc
:~/Documents/clan/test2$ ./a.out
hello world
30
其中export LD_LIBRARY_PATH=$LD_LIBRARY_PATH**:**.表示動態(tài)庫所在位置為當前目錄,將當前目錄添加到環(huán)境變量中,當終端關(guān)閉,這個臨時變量就會消失。
上面的運行結(jié)果顯示,可以正確輸出結(jié)果,也就是說,動態(tài)庫是可以成功鏈接的。下面將上述案例稍微變復雜一點,如果是多個層級目錄,又怎么處理,理解路徑是非常重要的。
:~/Documents/clan/test2$ tree
.
├── func
│ ├── func.c
│ └── func.h
└── test.c
1 directory, 3 files
:/Documents/clan/test2$ gcc -fPIC -shared -o func/libfunc.so func/func.c/Documents/clan/test2 export LD_LIBRARY_PATH=LD_LIBRARY_PATH:/func
:
:/Documents/clan/test2$ gcc test.c -L./func -lfunc/Documents/clan/test2$ tree
:
.
├── a.out
├── func
│ ├── func.c
│ ├── func.h
│ └── libfunc.so
└── test.c
1 directory, 5 files
:~/Documents/clan/test2$ ./a.out
hello world
30
下面我們將用Makefile的形式來使用動態(tài)庫,編輯Makefile文件
export LD_LIBRARY_PATH:=$LD_LIBRARY_PATH:/func
test : test.c func/libfunc.so
gcc -o test test.c -L./func -lfunc
func/libfunc.so : func/func.c func/func.h
gcc -fPIC -shared -o func/libfunc.so func/func.c
clean :
rm -f test func/libfunc.so
然后編譯執(zhí)行,同樣可以輸出正確結(jié)果
動態(tài)庫的過程比靜態(tài)庫稍微復雜,但是在寫Makefile的時候,步驟基本相似,倒著寫gcc編譯過程即可。
審核編輯:劉清
-
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
593瀏覽量
27392 -
Makefile
+關(guān)注
關(guān)注
1文章
125瀏覽量
19181 -
gcc編譯器
+關(guān)注
關(guān)注
0文章
78瀏覽量
3378
發(fā)布評論請先 登錄
相關(guān)推薦
評論