linux下的靜態庫依賴
背景
linux的靜態庫.a和動態庫.so的區別很大,靜態庫基本上只是一系列.o檔案的集合加上符號表,沒有連結過程,不能依賴連結其他的靜態庫或者動態庫。如果靜態庫中用到了其他的庫,需要這個靜態庫的使用者在最終的連結階段清楚所有使用到的庫,然後一一連結。
如果靜態庫依賴的庫很多的話,而且依賴的關係很複雜,那麼對於最終的使用者來說絕對是一場噩夢。 方案
linux下的靜態庫其實就是一系列.o檔案的集合加上符號表。那麼如果把它所依賴的靜態庫裡的.o全部提取出來,然後再一起打包,更新符號表,是不是最終的使用者就可以不用管這些依賴了呢。
答案是的確可以,優點就是使用者不用去關心一堆靜態庫依賴,缺點是靜態庫的編寫者需要花費更多的精力,並且靜態庫的體積會增大。
那麼靜態庫依賴的動態庫怎麼辦呢。
沒有辦法,靜態庫上沒有連結資訊,也不可能把動態庫包含在裡面,所以靜態庫如果真的依賴其他庫,最好都依賴靜態庫。 打包
那麼怎樣將一個靜態庫打包到另一個靜態庫裡呢。
靜態庫打包工具ar提供了-q選項來追加.o檔案,理論上把所有依賴的靜態庫解開後打包是可行的,但是這樣很難使用指令碼來自動化打包,接下來我們使用一種很少見的方式來直接將.a添加到另一個.a中。
ar有一個選項-M,可以執行一種ar指令碼,這種指令碼的資料非常少,在man ar中都沒有介紹。我們接下來就使用這種指令碼來將一個靜態庫添加到另一個靜態庫中。
CREATE libstatic.aSAVEEND
這個指令碼的作用是建立一個空的名為libstatic.a的庫,以上指令碼儲存為ar.mac
執行ar -M < ar.mac,可以看到這裡是使用了重新導向輸入來執行指令碼的。
ar -q libstatic.a s1.oar -q libstatic.a s2.oar -q libstatic.a s3.o
然後在shell中執行上面的命令,將靜態庫自己的.o檔案添加到庫中。
OPEN libstatic.aADDLIB libstatic123.aSAVEEND
這個指令碼的作用是開啟庫檔案然後添加另一個依賴庫檔案。
將指令碼儲存後同樣使用ar -M執行。
這樣就完成了將一個庫添加到另一個庫中,此時可以使用ar -t命令查看一下庫裡面的內容,可以看到依賴庫的.o檔案都被包含進去了。