高階C C 編譯技術之讀書筆記(四)之定位庫檔案

2022-04-22 13:51:08 字數 3440 閱讀 1430

最近有幸閱讀了《高階c/c++編譯技術》深受啟發,該書深入淺出地講解了構建過程(編譯、鏈結)中的各種細節,從多個角度展示了程式與庫檔案或**的整合方法,提出了面向**復用和系統整合的軟體架構設計方法,以及系統開發過程中疑難問題的解決方案。

以下將回頭記錄下其中的關鍵要點,以便後面查閱。

(1)靜態庫:lib+. + a

(2)動態庫:lib+

(3)動態庫的版本資訊

dynamic libaray version information = ..

m:主版本號

m:次版本號

p:補丁(很小的**改動)版本號

(4)動態庫的soname

soname = lib++.so+m

動態庫的soname通常由聯結器嵌入二進位制檔案的專有elf欄位中,通常用特定的聯結器選項,將表示庫soname的字串傳遞給鏈結器

g++ -shared object files>-wl, -soname,libfoo.so.1 -o libfoo.so.1.0.0
(2)凡是間接呼叫鏈結器時,我們需要在鏈結器引數前追加「wl,」

在linux中用-l和-l選項來指定構建過程中庫檔案路徑

(1)將完整的庫檔案路徑分成兩個部分:目錄路徑和庫檔名

(2)將目錄路徑新增到-l聯結器選項後面,並傳遞給鏈結器

(3)將庫檔名新增到-l引數後面,並傳遞給聯結器

g++ main.o -l../sharedlib -lwokingdemo -o demo
在使用g++命令列一次性完整編譯鏈結兩個過程時,應在在鏈結器前新增-wl,

g++ -wall -fpic main.cpp -wl, -l../sharedlib -wl, -lworkingdeno -o demo
對於經驗不足的linux軟體工程師經常會遇到找到不動態庫的情況而不知所措,主要是對以下內容不夠了解。

動態庫執行時搜尋演算法由一組規則約束,按照優先順序從高到低列出

(1)預載入庫

a:通過設定ld_preload環境變數

export ld_preload=/home/fate/shareddir/libtest.so:$ld_preload
b:通過修改、etc/ld.so.preload檔案

指定預載入庫並不符合標準的設計規範。相反,該方案僅用於特殊情況,比如設計壓力測試、診斷已經對原始**的緊急補丁等
(2)rpath

rpath和runpath都可供我們使用,但是runpath在執行時搜尋優先順序列表中賦予了更高的優先順序,只有在runpath缺失的情況下,rpath才是linux裝載器剩餘的搜尋路徑資訊中具有最高優先順序的。

但如果elf二進位制檔案的runpath(dt_runpath)字段是非空的,那麼rpath會被忽略

g++ -wl, -r/home/fate/shared/ -ltestlibrary
或者,也可以用ld_run_path環境變數來設定rpath

export ld_run_path=/home/fate/shared:$ld_run_path
(3)ld_libaray_path

從庫搜尋概念發展初期開始,開發人員就希望可以使用一種臨時應急的有效機制來驗證它們的設計,通過特定的環境變數(ld_library_path)就能解決我們遇到的問題,當沒有rpath時,該路徑就是路徑搜尋資訊中優先順序最高的

export ld_library_path=/home/fate/shared/:$ld_library_path

注意:該機制只應用於實驗目的,軟體產品的產品版本不應該依賴於這種機制
(4)runpath

設定runpath的方法和設定rpath的方法非常相似,為了傳遞-r或-rpath鏈結器選項,需要使用額外的--enable-new-dtags鏈結選項

g++ -wl,-r/home/fate/shared/ -wl, --enable-new-dtags -ltestlibrary
(5)ldconfig快取

一種標準的**部署過程是基於執行linux的ldconfig工具,ldconfig會將指定的目錄路徑插入動態庫搜尋列表中,該列表維護在檔案/etc/ld.so.conf中。同樣地,系統會掃瞄新加入的目錄路徑,其結果是將發現的庫檔名新增到庫檔名列表中,該錶維護在/etc/ld.so.cache檔案中

/lib和/usr/lib是linux作業系統儲存動態庫的兩個預設路徑

總的來說,優先順序方案可以歸納為以下兩種版本:

(1)如果指定了runpath(即ld_runpath欄位非空)

a. ld_library_path

b. runpath(ld_runpath)

c. ld.so.cache

d. 預設路徑

(2)如果沒有指定runpath

a. 被載入庫的rpath,然後是二進位制檔案的rpath,直到可執行檔案或者動態庫將這些庫全部載入完畢為止

b. ld_librayr_path

c. ld.so.cache

d. 預設路徑

linux_so.h

#pragma once#ifdef __cplusplus

extern"c

"#endif

linux_so.c

#include "

linux_so.h

"#include

using

namespace

std;

void

fun()

main.c

#include "

stdio.h

"#include

"linux_so.h

"int

main()

編譯、鏈結

g++ -wall -g -o0 -fpic -shared linux_so.c -o liblinux_so.so
g++ -wall -g -o0 -fpic main.c -wl,-l./ -wl,-llinux_so -o out

export ld_library_path=/home/fate/sharedir/dlltest/:$ld_librayr_path

輸出

高階C C 編譯技術之讀書筆記(一)之編譯 鏈結

最近有幸閱讀了 高階c c 編譯技術 深受啟發,該書深入淺出地講解了構建過程 編譯 鏈結 中的各種細節,從多個角度展示了程式與庫檔案或 的整合方法,提出了面向 復用和系統整合的軟體架構設計方法,以及系統開發過程中疑難問題的解決方案。以下將回頭記錄下其中的關鍵要點,以便後面查閱。1 節 供cpu執行的...

高階C C 編譯技術之讀書筆記(二)之庫的概念

最近有幸閱讀了 高階c c 編譯技術 深受啟發,該書深入淺出地講解了構建過程 編譯 鏈結 中的各種細節,從多個角度展示了程式與庫檔案或 的整合方法,提出了面向 復用和系統整合的軟體架構設計方法,以及系統開發過程中疑難問題的解決方案。以下將回頭記錄下其中的關鍵要點,以便後面查閱。首先,需要理解載入域與...

《數學之美》讀書筆記(四)

關於分詞 統計語言模型方法進行分詞 最好的一種分詞方法應該保證分完詞後這個句子出現的概率最大 如果窮舉所有可能的分詞方法並計算每種可能性下句子的概率,計算量相當大。可以看成動態規劃問題dynamic programming,並利用維特比viterbi解碼演算法快速找到最佳分詞。孫茂松教授的貢獻 解決...