iOS編譯集成linux開源c庫(kù)的一些記錄

最近一個(gè)iOS項(xiàng)目需要使用一些Linux下面的開源c庫(kù),說(shuō)是Linux的其實(shí)是跨平臺(tái)的,各種Unix系統(tǒng)都有支持。理論上iOS來(lái)自MacOS,而MacOS其實(shí)是一種兼容的Unix系統(tǒng),所以這些庫(kù)應(yīng)該也可以在iOS上跑。當(dāng)然了這些庫(kù)并沒有直接操作系統(tǒng)硬件的。

目的是在iOS中使用開源c庫(kù),那么第一步得能在Linux或Mac上編譯他們吧,所以需要點(diǎn)一點(diǎn)Linux 編譯安裝c庫(kù)的技能點(diǎn)。 最基本的就是gcc和make使用,但實(shí)際上直接提供Makefile的庫(kù)很少,因?yàn)橐缙脚_(tái),要處理各種依賴環(huán)境的不同,所以這些庫(kù)很多都使用GUN的AutoTools系列工具編譯,除此之外還有用CMake等工具的,不過(guò)不在本次研究范圍內(nèi)。 關(guān)于Autotools,這兒有一個(gè)教程,雖然版本較老,但是還可以看一看,里面有一個(gè)例子可以跟著做一做:https://www.lrde.epita.fr/~adl/autotools.html
使用Autotools編譯的庫(kù),在Linux上基本上就是./Configure, make, make install三步就可以編譯安裝了,有的還需要一個(gè)腳本來(lái)生成Configure文件。這些庫(kù)無(wú)論是靜態(tài)庫(kù)還是動(dòng)態(tài)庫(kù)都會(huì)被安裝到Linux系統(tǒng)相應(yīng)的目錄中,比如usr/local/lib之類,而使用這些庫(kù)的應(yīng)用程序就可以指定鏈接他們。我也是剛點(diǎn)的技能點(diǎn),就不多說(shuō)了??傊褪莑inux下面基本上都是基于腳本和工具鏈編譯的,這和iOS使用XCode組織工程有很大的不同。當(dāng)然iOS實(shí)際上也可以用工具鏈編譯,有些庫(kù)就直接提供了iOS下面交叉編譯的腳本。

搞定了Linux下面的編譯,下面來(lái)看看iOS了。
有幾種情況:
1)可以將c庫(kù)在Mac上交叉編譯出iOS使用的靜態(tài)庫(kù).a文件,這個(gè).a文件是通過(guò)lipo工具合成的包含多個(gè)cpu架構(gòu)的組合版本。比如libsodium庫(kù)就提供了一個(gè)ios.sh編譯腳本,一鍵生成頭文件和.a,然后直接仍進(jìn)XCode中使用,非常方便。研究他的這個(gè)ios.sh腳本,可以給其他庫(kù)也做類似的交叉編譯。但是我安裝這個(gè)方法編譯出來(lái)的mbedtls庫(kù)雖然編譯成功但是放到XCode中之后就會(huì)出現(xiàn)連接問(wèn)題,說(shuō)是找不到符號(hào),使用-all_load后可以看到是因?yàn)閙in target不一致,但是更改后又出現(xiàn)說(shuō)沒有bitcode,我把工程的bitcode也關(guān)閉后居然又出現(xiàn)了更多的找不到符號(hào),折騰了幾個(gè)小時(shí)作為新手只好先放手了,轉(zhuǎn)用第二種方式解決。
2)第二種方式就是直接把源代碼加進(jìn)來(lái)編譯了。這個(gè)方法簡(jiǎn)單粗暴,但是也有一個(gè)問(wèn)題。因?yàn)槭褂胊utotools的工具都會(huì)有個(gè)config.h文件,這個(gè)文件是autoscan工具搜索編譯系統(tǒng)的環(huán)境自動(dòng)生成的,也就是說(shuō)如果你在Mac系統(tǒng)下面生成的config.h其實(shí)是反應(yīng)了Mac系統(tǒng)的環(huán)境,如果想得到iOS系統(tǒng)的config.h,還是需要交叉編譯,當(dāng)然可以不編譯,只是執(zhí)行Configure就行。然后另一個(gè)問(wèn)題是,如果你的XCode里面包含了幾個(gè)這些的庫(kù),他們都有config.h,XCode可能會(huì)找不到哪個(gè)庫(kù)用哪個(gè)config.h。有些比較良心的庫(kù)會(huì)提供一個(gè)宏去定義一個(gè)替換的名稱,我們需要在XCode里面設(shè)置,這個(gè)設(shè)置方法我也是搜了好久試了好幾次才找到,在other c flags里面加入DXXCONFIG_NAME=’\”xx_config.h\”’ 注意使用”和\”。
使用c庫(kù)后要注意的問(wèn)題:
1)DEBUG宏定義問(wèn)題。一般iOS開發(fā),XCode會(huì)在debug版本定義DEBUG=1。但你加入c庫(kù)后就郁悶了,因?yàn)橛械腸庫(kù)會(huì)這么寫:

#ifdef ENABLE_LOG
#define DEBUG(...) \
    do { \
        fprintf(stderr, __VA_ARGS__); \
        fprintf(stderr, "\n"); \
    } while (0)
#else
#define DEBUG(...) /* nothing */
#endif

看到了沒,無(wú)論是否定義ENABLE_LOG,DEBUG宏都被重定義了。如果你的代碼里面有這樣基于DEBUG的判斷可要小心了:

#if DEBUG
xxxx
#endif

DEBUG被重定義后,xxxx永遠(yuǎn)不會(huì)被執(zhí)行了,因?yàn)楝F(xiàn)在DEBUG要么是一段代碼,要么是空。你如果改成 #ifdef DEBUG,也不行的,因?yàn)镈EBUG永遠(yuǎn)是有定義的,xxxx總被執(zhí)行到。沒辦法只能自己再定義一個(gè)XXX_DEBUG的宏使用。萬(wàn)惡的C宏!
2)暫時(shí)記不清了,回頭再補(bǔ)充

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容