- 論壇徽章:
- 0
|
$gcc -c hello.c -o hello.o
1.連接成靜態(tài)庫
連接成靜態(tài)庫使用ar命令,其實(shí)ar是archive的意思
$ar cqs libhello.a hello.o
2.連接成動(dòng)態(tài)庫
生成動(dòng)態(tài)庫用gcc來完成,由于可能存在多個(gè)版本,因此通常指定版本號(hào):
$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o
另外再建立兩個(gè)符號(hào)連接:
$ln -s libhello.so.1.0 libhello.so.1
$ln -s libhello.so.1 libhello.so
這樣一個(gè)libhello的動(dòng)態(tài)連接庫就生成了。最重要的是傳gcc -shared 參數(shù)使其生成是動(dòng)態(tài)庫而不是普通執(zhí)行程序.
-Wl 表示后面的參數(shù)也就是-soname,libhello.so.1直接傳給連接器ld進(jìn)行處理。實(shí)際上,每一個(gè)庫都有一個(gè)soname,當(dāng)連接器發(fā)現(xiàn)它正 在查找的程序庫中有這樣一個(gè)名稱,連接器便會(huì)將soname嵌入連結(jié)中的二進(jìn)制文件內(nèi),而不是它正在運(yùn)行的實(shí)際文件名,在程序執(zhí)行期間,程序會(huì)查找擁有 soname名字的文件,而不是庫的文件名,換句話說,soname是庫的區(qū)分標(biāo)志。
這樣做的目的主要是允許系統(tǒng)中多個(gè)版本的庫文件共存,習(xí)慣上在命名庫文件的時(shí)候通常與soname相同
libxxxx.so.major.minor
其中,xxxx是庫的名字,major是主版本號(hào),minor 是次版本號(hào)
至于頭文件的使用 只要.c文件和.h文件在同一目錄下就可以直接用#include "your.h" 如果在.c文件的上層目錄 那只要做如下修改#include "../your.h" 就能夠讓你的編譯器找到了!
這個(gè)也不錯(cuò):http://colintrace.blogdriver.com/colintrace/1049722.html
這個(gè)也相當(dāng)詳細(xì):http://blog.csdn.net/lijing3933/archive/2008/01/28/2070381.aspx
一、創(chuàng)建共享庫
1 單獨(dú)編譯SList.cpp,編譯時(shí)需要傳入-fPIC選項(xiàng),告訴編譯器生成位置無關(guān)代碼.
位置無關(guān)代碼可以被加載到地址空間的任意位置而不需要修改.
[root@LEE src]# ls
main.cpp SList.cpp SList.h
[root@LEE src]# g++ -fPIC -g -c SList.cpp
2 當(dāng)鏈接到庫時(shí),為鏈接器傳入-shared選項(xiàng),把目標(biāo)文件SList.o鏈接為共享對(duì)象
libSList.so.1.0.1
每個(gè)共享庫都有一個(gè)特定的搜索名(soname).搜索名約定如下:
lib+庫名+.so+.版本號(hào)
在文件系統(tǒng)中,搜索名是一個(gè)指向?qū)嵜姆?hào)連接.每個(gè)共享庫也有一個(gè)特定的實(shí)名,約定如下:
搜索名+.子版本號(hào)+.發(fā)布號(hào)
你可以使用一個(gè)特殊的編譯器選項(xiàng)-Wl,option,將option傳給ld,用逗號(hào)分隔多個(gè)option,
為了在所有的系統(tǒng)上得到最好結(jié)果,鏈接libSList到標(biāo)準(zhǔn)C++庫上
[root@LEE src]# g++ -g -shared -Wl,-soname,libSList.so.1 -o libSList.so.1.0.1 SList.o -lstdc++
[root@LEE src]# ls
libSList.so.1.0.1 main.cpp SList.cpp SList.h SList.o
libSList.so.1是搜索名,libSList.so.1.0.1是實(shí)名,SList.o是目標(biāo)文件(也可以是多個(gè)目標(biāo)文件的列表)
,-lstdc++是庫需要訪問的庫(也可以是庫的列表-llibrary,關(guān)于此選項(xiàng)參考附錄.)
3 創(chuàng)建一個(gè)從soname鏈接到庫
[root@LEE src]# ln -fs libSList.so.1.0.1 libSList.so.1
[root@LEE src]# ln -fs libSList.so.1 libSList.so
4 使用-L使鏈接器在當(dāng)前目錄中查找?guī)欤⑶沂褂?lSList告訴它要鏈接哪個(gè)庫
[root@LEE src]# g++ -g -c main.cpp -o main.o
[root@LEE src]# g++ -g -o main main.o -L. -lSList
[root@LEE src]# ls
libSList.so libSList.so.1.0.1 main.cpp SList.cpp SList.o
libSList.so.1 main main.o SList.h
5 運(yùn)行命令
[root@LEE src]# LD_LIBRARY_PATH=$(pwd) ./main
4->17->19->10->23->21->11->20
LD_LIBRARY_PATH
提供用來搜索庫的目錄路徑,以冒號(hào)作為間隔.正常情況下它不應(yīng)該被設(shè)置,因?yàn)橄到y(tǒng)文件
/ect/ld.so.conf提供了默認(rèn)的路徑.
二、使用鏈接庫
當(dāng)運(yùn)行一個(gè)程序時(shí),動(dòng)態(tài)裝載器通常在/ect/ld.so.conf.d目錄查找程序所需要的庫.但是,如果
LD_LIBRARY_PATH 環(huán)境變量被設(shè)置,它首先掃描在LD_LIBRARY_PATH 中列出的目錄.對(duì)于上一節(jié)5,如果直接運(yùn)行
命令 ./main,會(huì)出現(xiàn)找不到庫的現(xiàn)象.如:
[root@LEE src]# ./main
./main: error while loading shared libraries: libSList.so.1: cannot open shared object file: No such file or directory
上述問題的解決方案有兩種(我能想到的):
1 如果LD_LIBRARY_PATH 沒設(shè)定:
拷貝libSList.so到目錄 /usr/local/lib (同理也可以拷到/usr/lib下)
[root@LEE src]# cp libSList.so /usr/local/lib
[root@LEE src]# ldconfig /usr/local/lib
[root@LEE src]# ./main
4->17->19->10->23->21->11->20
2 如果LD_LIBRARY_PATH 設(shè)定:
編輯.bash_profile文件
添加LD_LIBRARY_PATH:=$LD_LIBRARY_PATH:/path/to/libSList.so(不包括 libSList.so)
執(zhí)行.bash_profile 文件.
[root@LEE src]# . /root/.bash_profile
[root@LEE src]# ./main
4->17->19->10->23->21->11->20
本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/15201/showart_2058793.html |
|