gcc全靜態連結

2022-11-24 22:01:36 字數 1190 閱讀 6069

昨天看一篇關於libco的博文,裡面提到了一個由於全靜態連結導致的bug。全靜態連結?以前沒有接觸過這個概念,特意到網上搜了下,原來是一個程式將其依賴的所有動態庫都替換成對應靜態庫,即使是libc.so,libm.so,libstdc++.so這種系統級別的動態庫。全靜態連結出來的可執行程式,不依賴任何動態庫,拷貝到任何一臺機器,只需要作業系統,這個程式就可以run起來。

這種全靜態連結的方式,肯定有好有壞。

那全靜態連結如何優雅的實現呢?gcc為我們提供了(-static)、(-wl,-bstatic)、(-wl,-bdynamic),這麼幾個選項。

第一種用法:使用-static選項,將全部動態庫都用靜態庫替換。

這裡有個基於boost庫的程式,我們使用普通動態連結的方式編譯出來,看看可執行程式的依賴關係。

由上圖可見,可執行程式依賴於libboost_thread.so.1.72.0、libpthread.so.0、libstdc++.so.6、libc.so.6等等動態庫。我們再用-static編譯這個程式,再看看可執行程式的依賴關係。

由上圖可見,加入-static選項以後,連結器將動態庫全部換成了靜態庫。

第二種用法:使用-wl,-bstatic,-wl,-bdynamic選項,將部分動態庫設定為靜態連結。

gcc使用-wl將引數傳遞給聯結器。連結器使用-bdynamic強制連線動態庫,-bstatic強制連線靜態庫。所以部分靜態,部分動態連線這麼寫:

gcc -wl,-bstatic -l-wl,-bdynamic -l
我們還是使用上面的boost.cpp作為例子,本次編譯我們將libboost_thread.so.1.72.0用作靜態編譯,其他系統動態庫,任然以動態庫的方式進行連線。

由上圖可見,libboost_thread.so.1.72.0已經是靜態連結,而其他系統庫,任然是動態連結。

參考1:

參考2: