文章目錄
- 1.靜態庫和動態庫的定義,庫的命名規則
- 2.靜態庫與動態庫的優缺點
- Linux Centos下載C靜態庫命令
- 生成靜態鏈接C程式 -static
- 查看可執行程式依賴的動態庫(ldd)
- 靜態庫與動態庫的特征
- ①動靜態程式運行程序
- ②動靜態庫的優缺點
- 3.打包.o檔案制作動靜態庫
- 打包靜態庫(ar -rc)
- 生成靜態可執行程式(gcc -I+頭檔案路徑-L+庫路徑-l+要鏈接的庫名)
- 安裝自己的靜態庫(將庫拷貝到系統路徑下)
- 4.打包.o檔案制作動態庫(gcc -fPIC gcc -shared)
- 生成動態可執行程式(無法執行)
- 5.解決動態庫生成的可執行程式無法運行
- ①將依賴的庫拷貝到系統路徑下
- ②更改環境變數(LD_LIBRARY_PATH)
- ③更新ldconfig配置
1.靜態庫和動態庫的定義,庫的命名規則
動靜態庫類似與“半個可執行程式”
程式在編譯時會經歷4步
預處理->編譯->匯編->鏈接分別生成三個臨時檔案
.i->.s->.o,其中.o可重定向二進制檔案,對于C語言,我們把除了含有main函式的.c檔案的其他.c檔案在匯編所生成的.o檔案打包,這個包稱為庫(.so/.s)
動靜態庫的本質為一堆.o檔案的集合,不包含main但是包含了大量的方法
靜態庫(.a):程式在編譯鏈接的時候把庫的代碼鏈接到可執行檔案中,程式運行的時候將不再需要靜態庫
動態庫(.so):程式在運行的時候才去鏈接動態庫的代碼,多個程式共享使用庫的代碼,
庫的命名規則:
lib+庫名+后綴(.s/.so等)
eg:libc.so.6的庫名為c,其表示c語言動態庫
2.靜態庫與動態庫的優缺點
Linux Centos下載C靜態庫命令
sudo yum install glibs-static
生成靜態鏈接C程式 -static
注意:要安裝C靜態庫

查看可執行程式依賴的動態庫(ldd)

靜態庫與動態庫的特征
①動靜態程式運行程序

靜態可執行程式
加載:因為可執行程式包含頭檔案所有方法和main函式,所以加載到記憶體比較大,
在記憶體的程式代碼通過頁表對應行程地址空間的正文代碼段
如果其他行程也需要使用C庫,記憶體中沒有加載C庫,C庫在靜態可執行程式中,所以其他行程還要重新加載C庫,浪費了記憶體空間
動態可執行程式
加載:除了代碼加載到記憶體,其所使用的方法也會被加到記憶體,所以加載比較小
記憶體中的代碼映射到行程地址空間的正文代碼段,所使用的方法映射到堆疊和堆區之間的共享區
如果其他行程也需要使用C庫,則只要調整其他行程的映射關系到已經在記憶體加載好的C庫即可,不需要重復加載,節省記憶體空間
注意:
共享區:1.無法被寫入 2.所有使用該庫的行程可以共享
②動靜態庫的優缺點
靜態庫
缺點:1.加載到記憶體時所占空間大 2.多個行程使用同一庫會導致記憶體資源浪費
優點:1.與庫無關,庫已經鏈接在可執行程式中,洗掉庫后仍可運行
動態庫
缺點:1.依賴庫,如果可執行程式生成后,洗掉庫則無法運行這個可執行程式
優點:1.節省記憶體空間資源
3.打包.o檔案制作動靜態庫
打包靜態庫(ar -rc)
ar -rc +靜態庫名稱+依賴的.o檔案

其中r表示replace c表示create,表示當生成靜態庫的.o檔案發生改變時會更新靜態庫
將所有的頭檔案和生成的靜態庫整理到一個檔案中如下圖
生成靜態可執行程式(gcc -I+頭檔案路徑-L+庫路徑-l+要鏈接的庫名)
注意:
庫名為去掉lib和后綴之后剩下的名字
eg:libc.so.6庫名為c

如果直接運行因為這個庫不在系統路徑下,所以會找不到頭檔案和庫

我們要在鏈接時指定頭檔案搜索路徑和所依賴的庫路徑,并且還要指定要鏈接的庫名稱

安裝自己的靜態庫(將庫拷貝到系統路徑下)

注意:
1.此時在生成可執行程式時不需要指明庫路徑和頭檔案路徑,但還是要指明庫名稱,
2.我們在編譯c語言的庫不需要指明庫名稱因為編譯器自己會自動找到庫名稱

4.打包.o檔案制作動態庫(gcc -fPIC gcc -shared)
注意:
在生成.o檔案時要生成位置無關碼,在gcc后加 -fPIC表示生成位置無關碼

在將生成的.o檔案生成動態庫時還要加-shared選項


這個mathlib_Dy就是我們生成的動態庫
生成動態可執行程式(無法執行)
生成動態可執行程式的思路和靜態相同,指明頭檔案,庫路徑和庫名稱

這里發現gcc生成了可執行程式后并不能運行,
原因為:gcc時將頭檔案和庫路徑和庫名稱指定所以生成了可執行程式,但是在運行的程序中,作業系統無法查找到可執行程式所依賴的庫

如上圖:libMy.so為not found
5.解決動態庫生成的可執行程式無法運行
①將依賴的庫拷貝到系統路徑下
這種方法可以讓作業系統在運行的時候找到其依賴的庫
②更改環境變數(LD_LIBRARY_PATH)
LD_LIBRARY_PATH表示程式在運行時動態查找的路徑
環境變數的添加洗掉與命令獲取
export命令

匯出環境變數后,作業系統就可以找到這執行程式所依賴的庫

③更新ldconfig配置
Linux centos中/etc/ld.so.conf.d下保存的是組態檔,這些組態檔中是一些路徑
可以將自己庫的路徑寫到組態檔中再拷貝到/etc/ld.so.conf.d檔案夾中再ldconfig重繪即可

可以發現可執行程式中libMy.so可以找到了
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/325576.html
標籤:其他
上一篇:利用Python+Django快速開發Web畢業設計
下一篇:【Linux】行程基礎知識
