C++靜態庫和動態庫

靜態庫與動態庫

首先簡單介紹一下gcc 指令

ubuntu 下安裝gcc g++ 方法c++

sudo apt install gcc g++ubuntu

gcc 的簡單使用

創建hello.c 源文件
gcc hello.c => 生成a.out
gcc hello.c -o hello => 生成hello
./a.out | ./hello 運行bash

編譯步驟

  1. 預處理 生成.i 文件
  2. 編譯 生成.s 文件
  3. 生成目標文件 .o
  4. 連接各個.o 文件生成可執行文件

gcc經常使用參數選項

gcc編譯選項 選項的意義
-E 預處理指定的源文件,不進行編譯
-S 編譯指定的源文件,不進行彙編
-c 編譯、彙編指定的源文件,不進行連接
-o 指定生成文件名字
-I directory 指定 include 包含文件的搜索目錄
-g 編譯時,生成調試信息,該程序能夠被調試器調試
-D 在程序編譯的時候,指定一個宏 如打開DEBUG -D DEBUG
-w 不生成任何警告信息
-Wall 生成全部警告信息
-O [123] n的取值範圍:0~3。編譯器的優化選項的4個級別,-O0表示沒有優化,-O1爲缺省值,-O3優化級別最高
-l 在程序編譯的時候,指定使用的庫
-L 指定編譯的時候,搜索的庫的路徑。
-fPIC/fpic 生成與位置無關的代碼
-shared 生成共享目標文件。一般用在創建共享庫時
-std 指定編譯標準 如-std=c++1z或-std=gnu++17或-std=c++17

靜態庫

  • Linux 靜態庫
    • libxxx.a
      • lib 前綴
      • xxx 庫的名字
      • .a 後綴
  • Windows 靜態庫
    • libxxx.lib

靜態庫的製做

  1. 生成 .o 文件

    gcc xxx.c xxx.c xxx.c -capp

  2. 使用ar 打包
    1. ar rcs
    2. -r 替換
    3. -c 建立
    4. -s 索引

    ar rcs libxxx.a xxx.o xxx.o xxx.o函數

靜態庫的使用

引入頭文件與須要的靜態庫libxxx.a (頭文件中聲明瞭靜態庫的接口,libxxx.a爲接口的實現)
gcc main.c -o app -I ./include/ -L 靜態庫路徑 -l 靜態庫名字測試

  • -L 靜態庫路徑
  • -l 靜態庫名字 爲libxxx.a 中的xxx

動態庫/共享庫

  • Linux 動態庫
    • libxxx.so
      • lib 前綴
      • xxx 庫的名字
      • .so 後綴
  • Windows 動態庫
    • libxxx.dll

動態庫製做

  1. 生成 .o 文件 (與位置無關)

    gcc -c xxx.c xxx.c xxx.c -c -fpic
    -fpic/-fPIC 使用相對地址記錄代碼位置優化

  2. gcc -shared xxx.o xxx.o xxx.o -o libcxxx.so

動態庫使用

引入頭文件與須要的動態庫libxxx.so 頭文件中聲明瞭靜態庫的接口,libxxx.a爲接口的實現)
$ gcc main.c -o app -I ./include/ -L 動態庫路徑 -l 動態庫名字調試

工做原理

  • 靜態庫在程序編譯時會連接到目標代碼中,程序運行時再也不須要靜態庫,體積較大。每次編譯都須要載入靜態代碼,內存開銷大。
  • 動態庫在程序運行時才被載入,程序運行時須要動態庫存在,體積較小。系統只需載入一次動態庫,不一樣程序能夠獲得內存中相同的動態副本,內存開銷小。

解決動態庫找不到的問題:

第一種: 將動態庫的絕對路徑添加到 LD_LIBRARY_PATH 中

  1. 測試時候使用的, 終端關閉, 設置失效:
    在當前終端中執行: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/庫的路徑
  2. 長久設置, 將export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/庫的路徑 寫到配置文件中
  • 用戶: ~/.bashrc

添加: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/庫的路徑索引

  • 系統: /etc/profile

添加: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/庫的路徑接口

  • 添加完成執行命令, 使修改生效:

. ~/.bashrc
. /etc/profile
source /etc/profile
. 至關於 source

第二種: 在 /etc/ld.so.cache 添加動態庫路徑

  1. 打開文件: /etc/ld.so.conf
  2. 將.so文件路徑的目錄添加到/etc/ld.so.conf, 更新: sudo ldconfig
  3. /etc/ld.so.conf的做用:記錄了程序加載運行期間查找動態連接庫時的路徑。

靜態庫與動態庫的區別

靜態庫特色總結:

靜態庫對函數庫的連接是放在編譯時期完成的。
程序在運行時與函數庫再無瓜葛,移植方便。
浪費空間和資源,全部相關的目標文件與牽涉到的函數庫被連接合成一個可執行文件

動態態庫特色總結:

動態庫把對一些庫函數的連接載入推遲到程序運行的時期。 能夠實現進程之間的資源共享。 程序升級變得簡單。(只修改須要升級部分,靜態庫則須要整個從新編譯)

相關文章
相關標籤/搜索