iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0

這篇文章你會學到的

  • 用make編譯出靜態檔 .a
  • 用make編譯出動態檔 .so

用make編譯出靜態檔 .a

步驟:

  1. .c 變成 .o
  2. .o變成 .a

gcc 指令

GCC online source

# 編譯物件檔
gcc -c xxx1.c -o xxx1.o
gcc -c xxx2.c -o xxx2.o
# 把兩個.o打包成靜態庫
ar rcs xxx1lib.a xxx1.o xxx2.o

ar → gnu 的 archive 工具,用來打包或操作靜態函式庫 (gnu是什麼可以看Day5內容)
rcs → 三個旗標組合(replace / create / symbol index)

旗標 意義
r replace / insert:把後面的物件檔(.o)加入到 archive,如果已存在同名成員就取代。 Stack Overflow
c create:如果 archive(靜態庫)不存在,就建立一個新的。若已存在,這個選項讓它不要報錯,繼續進行。 Stack Overflow
s write an index:在 archive 內建立 symbol 索引表(table of contents),讓 linker 搜尋符號時更快。GNU ar 中這個索引會提升符號查找效率。 Stack Overflow

xxx1lib.a → 你要建立的 靜態函式庫 檔案名稱
xxx1.o xxx2.o → 要被打包進去的 物件檔 (object files)

make 指令

CC = gcc
AR = ar
ARFLAGS = rcs

TARGET = xxx1lib.a
OBJS = xxx1.o xxx2.o

$(TARGET): $(OBJS)
	$(AR) $(ARFLAGS) $@ $^

用make編譯出動態檔 .so

gcc指令

GCC online source

# 編譯位置獨立物件檔
gcc -fPIC -c xxx1.c -o xxx1.o
gcc -fPIC -c xxx2.c -o xxx2.o

# 連結成動態庫
gcc -shared -o xxxlib.so xxx1.o xxx2.o

-fPIC 告訴編譯器產生位置獨立的程式碼,建立 動態連結庫 (.so)
位置獨立碼 (PIC, Position Independent Code)

編譯方式 是否位置獨立 適用
普通編譯 固定位址,需 relocation 靜態庫 .a、獨立執行檔
-fPIC 可載入到任意位址 動態庫 .so

https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fPIC
https://stackoverflow.com/questions/5311515/gcc-fpic-option
https://en.wikipedia.org/wiki/Position-independent_code

除了-fPIC之外還有其他的使用方法

語法/旗標 功能 / 為什麼要這個
-fPIC(Position Independent Code) 產生位置獨立的物件碼。這樣編出的 library 可以被載入到記憶體的任何位置運行,不會因為地址不同導致 relocation 問題。動態庫需要這樣才比較安全穩定
-shared 告訴 linker(用 gcc 裝飾成 linker mode)要產生共享庫(.so),而不是直接連成可執行檔或靜態庫

make 指令

CC = gcc
CFLAGS = -Wall -fPIC
LDFLAGS = -shared

TARGET = xxxlib.so
OBJS = xxx1.o xxx2.o

$(TARGET): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $^

可以查語法的地方

需要注意的地方

  • 不同平台/不同架構
  • 版本兼容性可能會有問題 (動態庫都會有的問題)
    不同 CPU 架構或不同作業系統對 -fPIC 的支援可能不同
  • 使用 -fPIE 與 -pie

上一篇
[Day 16] [gcc+make] 靜態函示庫? 動態函示庫? 如何用gcc/make編譯兩者?
下一篇
[Day 18] [make → cmake] makefile在大型專案中的問題
系列文
30 天精通 C 語言建置與除錯:從 Makefile 到 CMake 跨平台實戰23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言