學習總結:靜態連接和動態連接

連接可分爲靜態連接和動態連接

靜態連接:對函數庫的連接是放在編譯時期完成的是靜態連接

生成靜態連接庫的步驟:

(1)先將源文件編譯成 .o 文件:

(源文件可從上一篇查看)函數

g++ -c printA.cpp
g++ -c printB.cpp

生成的文件爲 printA.o printB.o ,-c 的編譯選項,表示只執行到編譯,輸出目標文件。code

  • 不管是靜態庫文件仍是動態庫文件,都是由 .o 文件建立的

(2)由 .o 文件建立靜態庫(.a 文件),執行命令:

ar cr libmyprint.a printA.o printB.o

生成的靜態庫文件就是libmyprint.a,命名規範是以lib 開頭(前綴),緊接着是靜態庫名,以.a爲後綴名內存

ar 命令的 c 選項:建立一個庫。開發

ar 命令的 r 選項:在庫中插入模塊(替換);若是若干模塊中有一個模塊在庫中不存在,ar會顯示一個錯誤信息,而且不替換其餘同名模塊。編譯器

(3)在程序中使用靜態庫,連接生成可執行文件:

g++ -o main main.cpp -L. -lmyprint

動態連接:程序運行到要調用待連接的庫函數時,才連接載入,拷貝至內存,內存已有不重複載入。

生成動態連接庫的步驟:

(1)先將源文件編譯成位置獨立的.o文件

g++ -fPIC -o printA.o -c printA.cpp
g++ -fPIC -o printB.o -c printB.cpp

(2)由 .o 文件建立動態庫(.so 文件),執行命令:

g++ -shared -o libmyprint.so printA.o printB.o

(1) ,(2)也能夠一步到位:編譯

g++ -fPIC -shared -o libmyprint.so printA.cpp printB.cpp

(3)將動態庫文件拷貝至動態庫搜索路徑目錄下

動態庫的搜索路徑的前後順序是:class

  • 編譯目標代碼時指定的動態庫搜索路徑
  • 環境變量 LD_LIBRARY_PATH 指定的動態庫搜索路徑
  • 配置文件 /etc/ld.so.conf 中指定的動態庫搜索路徑;即只需在該文件中追加一行庫所在的完整路徑如「root/test/conf/lib」便可,而後ldconfig使修改生效
  • 默認的動態搜索路徑 /lib
  • 默認的動態庫搜索路徑 /usr/lib

爲此解決步驟爲:test

將動態庫文件 拷貝至目錄 /usr/lib 中後臺

cp libmyprint.so /usr/lib/

修改環境變量 LD_LIBRARY_PATH,並使修改生效變量

export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH
sudo ldconfig

(4)在程序中(隱式)使用動態庫,連接生成可執行文件

g++ -o main main.cpp -L. -lmyprint

代碼和靜態庫生成可執行文件同樣

選項備註:

-fPIC :表示編譯爲位置獨立的代碼

-Lpath:表示從path 目錄中搜索庫文件,若從當前路徑 . 查找,選項爲 -L. (有一點)

-Iname:name爲動態庫的真正名字,編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面+lib,後面加.so肯定庫的名稱,即實際動態庫文件名爲 libname.so

參考:《後臺開發核心與應用實踐》

相關文章
相關標籤/搜索