AIX (IBM Unix) 的庫機制與 Linux 有顯著差異:.a 既可作靜態庫也可作動態庫封裝,.so 較少見。本文記錄在 AIX 上使用 xlc/cc 編譯器與 ld 連結器進行靜態/動態鏈接的實驗過程與核心概念。
.a (archive) 封裝目標檔;.so (shared object) 共享物件。libc.a 同時包含靜態成員 (crt0.o 等) 與共享成員 (shr.o 等),ld -bnso 控制選擇哪一種。# hello.c
#include <stdio.h>
int main() { printf("Hello, world!\n"); }
xlc -c hello.c -o hello.o
ld -o hello_s -bnso hello.o -lc
# 錯誤: Entry point not found: __start
缺少啟動代碼 crt0.o (提供 __start 入口點)。
ld -o hello_s -bnso hello.o -lc /usr/lib/crt0.o
# 大量 Undefined symbol: __loadx, errno, ... 來自 libc.a[shr.o]
libc.a 內的 shr.o 是共享成員,包含系統呼叫存根,需動態鏈接支持。靜態鏈接時必須解析這些符號。
# 導出 shr.o 依賴
ar -x /usr/lib/libc.a shr.o
ldd shr.o
# shr.o needs: /unix, /usr/lib/libcrypt.a(shr.o), /usr/lib/libc.a(shr.o)
# 匯入系統呼叫導出表
ld -o hello_s -bnso hello.o -lc /usr/lib/crt0.o -bI:/lib/syscalls.exp
# 仍有重複符號警告與未定義符號...
crt0.o、syscalls.exp、共享成員依賴。xlc 編譯器驅動程式會自動處理上述細節,強烈建議直接使用 xlc 而非裸呼叫 ld:# 靜態鏈接 (xlc 自動處理)
xlc -o hello_static -bnso hello.c
# 動態鏈接 (預設)
xlc -o hello_dynamic hello.c
# 1. 編譯位置無關碼
xlc -c -qpic mylib.c -o mylib.o
# 2. 建立共享庫 (產生 libmylib.a 內含 shr.o)
xlc -qmkshrobj -o libmylib.a mylib.o
# 3. 使用共享庫
xlc -o app main.c -L. -lmylib
# 執行時需設定 LIBPATH 或使用 -blibpath:/full/path:/usr/lib:/lib
| 旗標 | 用途 |
|---|---|
-bnso | 靜態鏈接 (no shared objects) |
-qpic | 產生位置無關碼 (PIC) |
-qmkshrobj | 建立共享物件 (放入 .a) |
-bI:file | 匯入符號表 (如 syscalls.exp) |
-bE:file | 匯出符號表 (建立共享庫時指定導出符號) |
-blibpath:path1:path2 | 執行期庫搜尋路徑 (嵌入可執行檔) |
-brtl | 啟用執行期鏈接 (dlopen 風格) |
.a 為統一封裝格式,內含靜態/共享成員由鏈接旗標決定使用哪種。ld 需深入理解 AIX 執行環境啟動機制,生產環境請優先使用 xlc/cc 驅動鏈接。-blibpath 或環境變數 LIBPATH,避免執行期找不到庫。