很簡單點事情,卻沒人直接回答,一兩句話就能說清楚:
gcc使用-Wl傳遞聯結器引數,ld使用-Bdynamic強制連線動態庫,-Bstatic強制連線靜態庫。所以部分靜態,部分動態連線這麼寫:
gcc 。。。 -Wl,-Bstatic -l
舉個例子,你想靜態連線libA。a同時動態連線libB。so,(先保證你的連線路徑-L裡面能找到對應的靜態或者動態庫),這麼寫:
gcc 。。。 -Wl,-Bstatic -lA -Wl,-Bdynamic -lB 。。。
這裡需要注意,強制靜態或者動態連線標記之後的連結庫都將按照前面最近的一個標記進行連結,所以如果後面出現了一個libC,沒有指定連線標記,那麼libC將會被動態連線:
gcc 。。。 -Wl,-Bstatic -lA -Wl,-Bdynamic -lB 。。。 -lC
如果引數裡面沒指定強制的連線方式標記,那麼gcc將按照預設的優先順序去連結,優先動態連結,所以如果你這麼寫,且同時存在libC。so和libC。a那麼libC將被動態連結:
gcc 。。。 -lC
由於-B連線標記會改變預設連線方式,所以在Makefile裡面如果有人這麼幹:
LIBS += -Wl,-Bstatic -lC
那麼他後面的LIBS+=的庫就都只能以靜態方式連線了,有時候這是不行的,因為沒有靜態庫,所以會有人這麼應對:
LIBS += -Wl,-Bdynamic -lD
這樣就改回來了。但是這種胡亂改的行為是非常不好的,比較好的行為應該這樣:
LIBS += -l
STATIC_LIBS += -l
DYN_LIBS += -l
LDFLAGS := ${LIBS} -Wl,-Bstatic ${STATIC_LIBS} -Wl,-Bdynamic ${DYN_LIBS}
這樣當你不關心怎麼連線的時候用LIBS,當你想靜態連線的時候用STATIC_LIBS,當你想動態連線的時候用DYN_LIBS。
關於這個問題,有一種簡單的方法來觀察答案:
用cmake或者qmake來生成你的makefile, 他能夠根據你的GCC版本採用合適的選項。
有些是第三方軟體在程式碼裡面強制使用動態庫的,比如py就可以載入一個動態庫,這樣你是沒辦法透過gcc來搞定的,得修改原始碼
這種情況不如在自己的目錄下自舉個環境。比如用 pkgsrc 或者 gentoo prefix。
最高票的答案我編譯出現這個錯誤:
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
然後搜到了gcc引數加上 `-Wl,-Bdynamic -lgcc_s `可以解決,
最後我強制連結靜態連結libfunc。a(我的目錄下同時有 libfunc。a 和 libfunc。so):
gcc main。c -Wl,-Bstatic -lfunc -L。 -Wl,-Bdynamic -lgcc_s
有關 gcc_s :
https://
gcc。gnu。org/onlinedocs/
gccint/Libgcc。html
還有一種方法是直接指定靜態連結的庫全名:
gcc main。c -l:libfunc。a -L //這樣也是靜態連結libfunc。a