網上流傳了太多關於合並lib庫的方法,自己也嘗試過,但大多失敗。有感於這種急於解決問題,經過百般嘗試后依舊無果的無奈心情,小翁在這里用一個實例來完整闡述如何在mac中合並lib靜態庫。
這里以移動廣告平台多盟的三個lib庫為例子,之所以以此為例子,是因為我也遇到了庫沖突的問題,所以才有了本文的內容。
本文的目標:合並libDomobOfferWallSDK.a、libDomobAdWallCoreSDK+UI.a、libDomobAdSDK.a
Let`s begin!
1.依次查看所有需要合並的lib庫所支持的框架類型。i386表示支持iphone模擬器,armv6應用在iphone 3gs上,armv7應用在iphone4,armv7s應用在iphone4s以及iphone5,arm64應用在最新的iphone5s上。
lipo -info libDomobOfferWallSDK.a
輸出是:Architectures in the fat file: libDomobOfferWallSDK.a are: armv7 armv7s i386
其他同理
看到紅色粗體的fat了嗎,fat file表示這個庫里面合並了多於1個框架。
2.將lib庫拆分出armv7、armv7s、i386類型的.a:
lipo -extract_family armv7 -output libDomobOfferWallSDK_arm.a libDomobOfferWallSDK.a
很多人會以為上面這條命令就可以一步到位分離出armv7版本,因為你顯式地指出armv7了。但是,你錯了。libDomobOfferWallSDK_arm.a仍舊是fat file,也就是里面含有了arm所有版本,這也是網上很多版本的教程錯誤的原因。如果誤以為libDomobOfferWallSDK_arm.a只含armv7一個版本,則下一步的解.o操作就會失敗,會提示"is a fat file"。小翁認為,最保險的做法是每次lib變化時都用lipo -info查看一下。現在我們查看一下libDomobOfferWallSDK_arm.a庫:
lipo -info libDomobOfferWallSDK_arm.a 打印出:Architectures in the fat file: libDomobOfferWallSDK_arm.a are: armv7 armv7s
接着用如下命令進一步分離出單獨的armv7、armv7s版本:(非常重要的步驟)
lipo libDomobOfferWallSDK_arm.a -thin armv7 -output libDomobOfferWallSDK_armv7_final.a
lipo libDomobOfferWallSDK_arm.a -thin armv7s -output libDomobOfferWallSDK_armv7s_final.a
而對於i386則不用上述那么麻煩,直接用第一句-extract_family指令就能分離出只含i386版本的庫:
lipo -extract_family i386 -output libDomobOfferWallSDK_i386.a libDomobOfferWallSDK.a
經過上面操作后,我們得到了第一個待合並庫libDomobOfferWallSDK.a 的armv7、armv7s、i386三個版本的庫。剩下的兩個待合並庫同理。
3.分離出目標文件(.o)
進行實質上的合並。xcode里提示duplicate symbol都是說***.o與***.o沖突。注意,只有非fat file,也就是只含有單種版本的lib庫才能分離出.o文件
ar -x ../libDomobOfferWallSDK_armv7_final.a ar -x ../libDomobAdWallCoreSDK+UI_armv7_final.a ar -x ../libDomobAdSDK_armv7_final.a
這一步最好是在lib*_final.a的同級目錄下新建一個文件夾,專門用來接收解壓出來的.o文件。同種版本(如armv7)的都解壓到這個文件夾中,相同的.o文件他會自己覆蓋掉。
4.從.o文件中合並成靜態庫:
libtool -static -o ../libDomobUniversal-armv7.a *.o
armv7s、i386版本同理。
5.合並成最終的通用靜態庫:
lipo -create -output libDomobUniversal.a libDomobUniversal-i386.a libDomobUniversal-armv7.a libDomobUniversal-armv7s.a