Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 靜態庫與動態庫深度解析:命名、連結、路徑、符號查看與製作全流程

編輯:Linux 教學

庫檔案命名慣例

  • 靜態庫:libxxx.a(archive)
  • 動態庫:libxxx.so(shared object)
  • 版本管理:libxxx.so.1.0 → 建立符號連結 libxxx.so.1 → libxxx.so,連結器尋找 .so 後綴,執行期載入器依 SONAME(如 libxxx.so.1)定位具體版本。

連結機制差異

特性靜態庫動態庫
連結時期將符號完整複製至執行檔在執行檔留下標記,執行時動態載入
體積執行檔較大執行檔較小,共享庫體
部署無外部依賴需確保運行環境有對應 .so
預設行為需顯式指定GCC 預設優先動態連結

實戰:同目錄同時存在靜/動態庫時的連結控制

# 預設動態連結
gcc testlib.o -lhello -o testlib

# 強制靜態連結 hello,動態連結 bye
gcc testlib.o -o testlib -Wl,-Bstatic -lhello -Wl,-Bdynamic -lbye
  • -Wl,-Bstatic 傳遞給連結器 ld,後續 -l 走靜態;-Wl,-Bdynamic 恢復動態。
  • 若系統僅有靜態庫,無需額外參數。

動態庫路徑搜尋順序與配置

  1. 編譯時期 -L 指定目錄(僅影響連結器)。
  2. 執行期依序搜尋:
    • 編譯時嵌入的 RPATH/RUNPATH
    • 環境變數 LD_LIBRARY_PATH
    • /etc/ld.so.conf 內目錄(需執行 ldconfig 刷新快取)
    • 預設 /lib、/usr/lib
# 臨時指定
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib

# 永久生效
echo "/home/ting/lib" >> /etc/ld.so.conf
ldconfig

查看庫符號:nm & ldd

# nm 輸出符號類型:T=定義在本庫、U=未定義(需外部)、W=弱符號
nm libhello.so | grep printf
# 輸出: U printf  → printf 來自外部庫

# ldd 查看動態依賴
ldd libhello.so
# libc.so.6 => /lib/libc.so.6
# /lib/ld-linux.so.2 => /lib/ld-linux.so.2

從原始碼製作庫完整流程

# hello.c
#include 
void sayhello() { printf("hello,world"); }

1. 編譯目標檔

gcc -c hello.c -o hello.o  # 可加 -g 保留除錯資訊

2. 產生靜態庫

ar cqs libhello.a hello.o
  • c 建立、q 快速追加、s 建立索引。

3. 產生動態庫

gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o
ln -sf libhello.so.1.0 libhello.so.1
ln -sf libhello.so.1 libhello.so
  • -shared 生成共享庫而非執行檔。
  • -Wl,-soname,libhello.so.1 設定 SONAME 嵌入執行檔,實現版本相容。
  • 慣例命名:libxxx.so.主版本.次版本,SONAME 只保留主版本。
Copyright © Windows教程網 All Rights Reserved