在前面介紹了靜態庫的構建,這里談一下動態庫的構建,同樣以案例的方式描述,希望案例可起到模板的作用。
首先新建一個測試文件,test.c
#include
int main()
{
printf("hello world\\n");
return 0;
}
它是可以編譯成功的
將可執行文件a.out刪除
添加文件,如靜態庫中所示(這里省略掉了)
編譯運行,同樣可以輸出
$ 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文件,用動態庫的方式實現。
: ~/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
`
很可惜,最后在鏈接動態庫編譯的時候,失敗了,提示不能找到文件
error while loading shared libraries: libfunc.so: cannot open shared object file: No such file or directory
在編譯程序時,使用動態鏈接庫和靜態庫是一致的,使用”-l庫名”的方式,在生成可執行文件的時候會鏈接庫文件。
-L指定動態鏈接庫的路徑,-ldtiger鏈接庫函數tiger。-ltiger是動態庫的調用規則。Linux系統下的動態庫命名方式是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
錯誤是因為程序運行時沒有找到動態鏈接庫造成的。程序編譯時鏈接動態庫和運行時使用動態鏈接庫的概念是不同的,在運行時,程序鏈接的動態鏈接庫需要在系統目錄下才行。為此,需要設置臨時環境變量
:~/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**:**.表示動態庫所在位置為當前目錄,將當前目錄添加到環境變量中,當終端關閉,這個臨時變量就會消失。
上面的運行結果顯示,可以正確輸出結果,也就是說,動態庫是可以成功鏈接的。下面將上述案例稍微變復雜一點,如果是多個層級目錄,又怎么處理,理解路徑是非常重要的。
:~/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的形式來使用動態庫,編輯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
然后編譯執行,同樣可以輸出正確結果
動態庫的過程比靜態庫稍微復雜,但是在寫Makefile的時候,步驟基本相似,倒著寫gcc編譯過程即可。
審核編輯:劉清
-
Linux系統
+關注
關注
4文章
591瀏覽量
27356 -
Makefile
+關注
關注
1文章
125瀏覽量
19162 -
gcc編譯器
+關注
關注
0文章
78瀏覽量
3363
發布評論請先 登錄
相關推薦
評論