目錄
必要的知識儲備:
生成靜態庫:
生成動態庫:
解決加載找不到動態庫的四種方法:
第一種:拷貝到系統默認的庫路徑 /usr/lib64/
第二種:在系統默認的庫路徑/usr/lib64/下建立軟鏈接
第三種:將自己的庫所在的路徑,添加到系統的環境變量LD_LIBRARY_PATH中
第四種:/etc/ld.so.conf.d建立自己的動態庫路徑的配置文件,然后重新ldconfig()即可
必要的知識儲備:
- 靜態庫(.a):程序在編譯鏈接的時候把庫的代碼鏈接到可執行文件中。程序運行的時候將不需要靜態庫
- 動態庫(.so):程序在運行的時候才去鏈接動態庫的代碼,多個程序共享使用庫的代碼。
- 一個與動態庫鏈接的可執行文件僅僅包含它用到的函數入口地址的一個表,而不是外部函數所在目標文件的整個機器碼。
- 在可執行文件開始運行以前,外部函數的機器碼由操作系統從磁盤上的該動態庫中復制到內存中,這個過程稱為動態鏈接。
- 動態庫可以在多個程序間共享,所以動態鏈接使得可執行文件更小,節省了磁盤空間。操作系統采用虛擬內存機制允許物理內存中的一份動態庫被要用到該庫的所有進程共用,節省了內存和磁盤空間。
生成靜態庫:
靜態庫(.a):程序在編譯鏈接的時候把庫的代碼鏈接到可執行文件中。所以,在和庫的代碼鏈接之前,得把我們的.c文件進行編譯生成.o文件。
gcc -c .c文件名 -o .o文件名
有了.o文件,我們我們就要生成靜態庫
ar -rc libmymath.a mymath.o(.a代表的是靜態庫,rc表示replace、create,就是靜態庫中有同名的就替換,沒有就創建一個新的)
查看靜態庫中的目錄列表:ar -tv libmymath.a(靜態庫名稱)
t:列出靜態庫中的文件
v:verbose 詳細信息
我們創建一個.c文件,去嘗試使用靜態庫
出現第一個問題:明明我們main.c文件已經包含了頭文件,且頭文件也在當前路徑,但是為什么編譯失敗?
編譯失敗就是找不到庫路徑
因為編譯器尋找.c文件里的頭文件直接到系統指定目錄查找頭文件 ,一般用于包含標準庫頭文件。所以找不到庫路徑
gcc main.c -L. -lmymath
-L 指定庫路徑
-l 指定庫名
測試目標文件生成后,靜態庫刪掉,程序照樣可以運行。
庫搜索指定路徑:
- 從左到右搜索-L指定的目錄。
- 由環境變量指定的目錄(LIBRARY_PATH)
- 由系統指定目錄:/usr/lib? ? ? ?/usr/local/lib
把我們提供的方法給別人用,有兩種方法:
- 把源文件直接給他
- 把源代碼想辦法打包成庫 = 庫 + .h
我們可以用makefile幫助我們更輕松的生成靜態庫
1 lib=libmymath.a2 3 $(lib):mymath.o4 ar -rc $@ $^5 mymath.o:mymath.c6 gcc -c $^7 8 .PHONY:clean9 clean:10 rm -rf *.o *.a lib11 12 .PHONY:output 13 output:14 mkdir -p lib/include15 mkdir -p lib/mymathlib16 cp *.h lib/include17 cp *.a lib/mymathlib18
我們平時用的庫如果都是別人成熟的庫,都采用直接安裝到系統的方式
生成動態庫:
gcc -fPIC -c myprint.c
gcc -shared -o libmyprint.so myprint.o
fPIC:產生位置無關碼(可以不了解,可以淺略閱讀下面關于-fPIC知識)
shared:表示生成共享庫格式
庫名規則:libxxx.so
關于-fPIC知識
在使用gcc編譯生成動態庫時,通常需要使用-fPIC(Position Independent Code)選項來生成位置無關的代碼。這是因為動態庫是在加載時動態鏈接到程序中的,而且可能會加載到內存的任意位置,因此需要生成位置無關的代碼,以確保代碼可以正確運行。
具體來說,`-fPIC`選項的作用包括:
1. 生成可重定位的代碼:位置無關代碼可以被加載到任何地址,不會受到地址空間限制。
2. 允許動態庫在內存中共享代碼段:多個程序可以共享同一個動態庫的代碼段,減少內存占用。
3. 支持更靈活的共享庫加載方式:使得動態鏈接更為靈活,可以在程序運行時根據需要加載動態庫。因此,在生成動態庫時,使用`-fPIC`選項可以確保生成的庫具有位置無關性,適合被動態鏈接到不同程序中使用。
gcc main.c -L. -lmyprint
庫文件名稱和引入庫的名稱
如:lib.c.so->c庫,去掉前綴lib,去掉后綴.so,.a
解決加載找不到動態庫的四種方法:
- 拷貝到系統默認的庫路徑 /user/lib64/
- 在系統默認的庫路徑/user/lib64/下建立軟鏈接
- 將自己的庫所在的路徑,添加到系統的環境變量LD_LIBRARY_PATH中
- /etc/ld.so.conf.d建立自己的動態庫路徑的配置文件,然后重新ldconfig()即可
第一種:拷貝到系統默認的庫路徑 /usr/lib64/
第二種:在系統默認的庫路徑/usr/lib64/下建立軟鏈接
第三種:將自己的庫所在的路徑,添加到系統的環境變量LD_LIBRARY_PATH中
第四種:/etc/ld.so.conf.d建立自己的動態庫路徑的配置文件,然后重新ldconfig()即可
系統維護自己的動態庫,配置文件里放的都是路徑
用makefile生成動靜態庫
dy-lib=libmethod.so 2 static-lib=libmymath.a3 4 .PHONY:all5 all: $(dy-lib) $(static-lib)6 7 8 $(static-lib):mymath.o9 ar -rc $@ $^10 mymath.o:mymath.c11 gcc -c $^12 13 $(dy-lib): myprint.o14 gcc -shared -o $@ $^15 myprint.o:myprint.c16 gcc -fPIC -c $^17 18 19 .PHONY:clean20 clean:21 rm -rf *.o *.a *.so mylib22 23 .PHONY:output24 output:25 mkdir -p mylib/include26 mkdir -p mylib/lib27 cp *.h mylib/include28 cp *.a mylib/lib29 cp *.so mylib/lib