一、庫的作用
1、提高開發(fā)效率,讓開發(fā)者所有的函數(shù)實現(xiàn)不用從零開始。
2、隱藏源代碼。
????????庫其實就是所有的.o文件用特定的方式進行打包形成一個文件,各個.o文件包含了源代碼中的機器語言指令。
二、動態(tài)庫和靜態(tài)庫的制作和使用
2.1、靜態(tài)庫的制作和使用
先將我們的.c文件或者是.cpp文件形成.o文件,指令為:
gcc/g++ -c 要形成的.o文件名 .c文件
????????假設(shè)在我當(dāng)前目錄下有mystdio.o和mymath.o兩個.o文件,要將這兩個.o文件打包形成靜態(tài)庫,我們要用ar指令
ar -rc libmyc.a(名字,.a后綴表示靜態(tài)庫,真正的庫名要去掉lib,去掉.a)mystdio.o mymath.o?(跟上.o文件名)
?????????上面指令-rc中的r表示replace,c表示create,也就是說你要我形成的這個庫如果原本沒有,我就幫你形成一個新的庫,如果有了那我就把你原來舊的庫替換掉。
????????此時在我當(dāng)前路徑下就有這個庫了。但是,當(dāng)我們?nèi)ゾ幾g的時候,gcc編譯器是不認識我們這個靜態(tài)庫的,gcc默認只能識別lib64目錄下的C標準庫,要讓gcc鏈接我們的庫,需要在指令中指明哪一個庫讓gcc鏈接。
gcc -o myexe(要形成的可執(zhí)行文件名) test.c(所依賴的文件) -lmyc(指明要鏈接myc這個靜態(tài)庫) -L .(-L + 路徑表示myc這個庫在哪個路徑下)
?
2.2、動態(tài)庫的制作和使用
fPIC:產(chǎn)生位置無關(guān)碼,在將.c或者.cpp形成.o文件時,需要加上-fPIC。要形成動態(tài)庫必須加上-fPIC。
?加上-fPIC同樣可以形成.o文件。
形成動態(tài)庫不需要用到其它指令,gcc編譯器就可以形成動態(tài)庫,只不過要加上-shared命令。
gcc -shared -o libmyc.so(名字,真正的庫名要去掉lib和.so) mystdio.o mymath.o(所依賴的.o文件)?
?????????但如果直接使用我們的這個動態(tài)庫,同樣會和我們之前使用靜態(tài)庫一樣發(fā)生鏈接錯誤。那么就同樣要告訴編譯器我們庫的名字和所在的路徑(參考上面靜態(tài)庫路徑的寫法)。
????????但是,在ubuntu系統(tǒng)下你會發(fā)現(xiàn),動態(tài)庫使用靜態(tài)庫的鏈接方法我們的動態(tài)庫系統(tǒng)還是找不到(此處特制ubuntu系統(tǒng),其它系統(tǒng)可能可以正常運行),這時我們就只能將我們的動態(tài)庫拷貝到系統(tǒng)的usr/lib目錄下,因為系統(tǒng)默認尋找?guī)斓臅r候回到/usr/lib目錄下找。??
?此時在運行我們的程序就能正常運行了,但要注意的是,在指令的最后我們必須指明我們要鏈接的庫,因為這個庫是我們自己導(dǎo)到系統(tǒng)中的,需要我們自己指明鏈接。
三、將自己的庫打包交給別人
?????????假設(shè)在我當(dāng)前目錄下有l(wèi)ibmyc.so動態(tài)庫,mymath.h,mystdio.h兩個頭文件,如果我想將這三個文件一起交給別人,就可以把它們打包一起放在一個目錄下,一起壓縮完再交給別人。
?在這里我將指令全部放在makefile中
libmyc.so:mystdio.o mymath.o
gcc -shared -o $@ $^
.o:.c
gcc -shared -c $<
#mystdio.o:mystdio.c
# gcc -c -fPIC $< -o $@
#mymath.o:mymath.c
# gcc -c -fPIC $< -o $@
.PHONY:clean
clean:
rm -f *.o libmyc.so
.PHONY:output
output:
mkdir -p ./user/mylib/
mkdir -p ./user/Headfile/
cp -rf libmyc.so ./user/mylib/
cp -rf mystdio.h mymath.h ./user/Headfile/
tar -czf user.tgz user
四、運行別人給我的庫文件和頭文件?
????????假設(shè)我自己收到了別人的壓縮文件,里面有頭文件和庫文件,我想使用可以將頭文件拷貝到usr/include目錄下,將庫文件拷貝到usr/lib目錄下,最后指定鏈接哪一個庫,就可以使用了。
????????現(xiàn)在假設(shè)user目錄是通過user.tgz解壓得到的,下面是user目錄下的文件:
????????將兩個頭文件拷貝到usr/include目錄下(編譯器默認會到include目錄下去尋找頭文件),將庫文件拷貝到usr/lib目錄下,編譯時指定庫鏈接,就能夠運行了。當(dāng)然了包含main函數(shù)的文件要自己寫啦!
如果今天我不將我的庫文件和頭文件拷貝到系統(tǒng)中,則需要:
gcc -o myexe test.c -I ./user/Headfile/(-I + 路徑指明要去哪里找頭文件) -L ./user/mylib/ -lmyc(-L + 路徑 + 庫名指明要去哪里找哪一個庫)
????????如果是這樣去做我們會發(fā)現(xiàn)編譯是能通過的,但當(dāng)我們要運行我們的可執(zhí)行程序時,會發(fā)現(xiàn)還是找不到庫。因為-L只是告訴gcc編譯器動態(tài)庫在哪里,但沒有告訴系統(tǒng)動態(tài)庫在哪里,所以在要運行時系統(tǒng)會找不到動態(tài)庫。
?那如何解決呢?
方法1:添加環(huán)境變量LD_LIBRARY_PATH的搜索路徑
LD_LIBRARY_PATH變量在你的系統(tǒng)中可能有也可能沒有,如果沒有自行導(dǎo)入就行。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/sxb/240402/user/mylib(冒號后緊跟你的動態(tài)庫所在的路徑)
?????????但是因為命令行export是導(dǎo)入到系統(tǒng)內(nèi)存級別的環(huán)境變量中,下次登錄系統(tǒng)又會從磁盤配置文件中重新讀取環(huán)境變量,所以如果要讓你配置的這個LD_LIBRARY_PATH環(huán)境變量永久生效需要將其配置到.bashprofile文件或者.bashrc文件中。
方法2:通過軟鏈接方式
????????在usr/lib目錄下建立一個與我們的動態(tài)庫同名(記住必須要同名)的軟鏈接文件,這樣修改的是系統(tǒng)文件,是永久存在的。
方法3:修改加載動態(tài)庫的配置文件
????????在系統(tǒng)這個目錄/etc/ld.so.conf.d/下(ld:load加載,so動態(tài)庫,conf配置文件,d目錄),建立.conf后綴的配置文件,文件里面只需要存放動態(tài)庫的路徑即可,系統(tǒng)在尋找動態(tài)庫的時候默認就會幫我們搜索該目錄下的配置文件中所保存的路徑。
????????在該目錄下創(chuàng)建一個我們自己的.conf后綴的文件
????????然后只需要在該文件中保存我們的動態(tài)庫所在的路徑?
?
????????然后需要讓系統(tǒng)知道/etc/ld.so.conf.d/下的文件被修改過了,需要執(zhí)行l(wèi)dconfig指令,這樣我們的可執(zhí)行程序在運行時也能找到動態(tài)庫了。文章來源:http://www.zghlxwxcb.cn/news/detail-854001.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-854001.html
到了這里,關(guān)于【Linux】詳解動靜態(tài)庫的制作和使用&&動靜態(tài)庫在系統(tǒng)中的配置步驟的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!