背景
Swift project 中 c/c++
混編一般可以通過創(chuàng)建 bridging-header.h
文件來完成, 然而如果是在 framework
中這種操作是不被準(zhǔn)許的, 即使是在 executable target
中雖然能完成集成但是也十分不優(yōu)雅
方案
使用 modulemap
是目前解決此類問題的主要途徑, 包括c/c++/Objective-c
混編. 關(guān)于 modulemap
的介紹可以參考 apple 的官方文檔(點我直達(dá)). 另外在實際使用中, 我們一般會通過 git submodule
來將需要混編的 libs
集成到項目
使用
-
集成
libs
直接將需要集成的 libs
丟進(jìn)項目
-
創(chuàng)建
module.modulemap
文件
在工程中創(chuàng)建 module.modulemap
文件 (這里直接在 excutable target
下創(chuàng)建) 選擇新建 empty
, 文件名填寫 module.modulemap
- 編輯
module.modulemap
文件
module Unsafe [system] [extern_c] {
header "../lib/include/unsafe-header.h"
export *
}
module SomeModule [system] [extern_c] {
header "PATH_FOR_HEADER"
export *
}
Warning: Unsafe
是 module name
, header
的 path
是 module.modulemap
的實體路徑(不是 xcode 中看到的虛擬路徑)的相對路徑
, 否則會報錯找不到頭文件, Copy Bundle Resources
中不能添加 module.modulemap
文件, 否則第二次編譯會報錯 Redefinition module
-
工程配置
- 方法一: 通過
Configuration Settings File
無疑是最簡單的, 這里不做贅述 - 方法二:
Build Settings -> Import Paths
填寫$(SRCROOT)/Modulemap
(當(dāng)前target
文件夾路徑), 如果libs
源碼導(dǎo)入, 報錯各種頭文件找不到, 可以設(shè)置下Building Settings -> Header Search Paths
->$(SRCROOT)/Modulemap/lib/include/
- 方法一: 通過
結(jié)束
到這里整個集成便完成了(這里是demo)
注意: 有些 c/c++ source code
的編寫風(fēng)格可能對編譯器不友好, 導(dǎo)致實際調(diào)用的時候報錯, 比如 c++
的 bool
類型, 頭文件沒有直接暴露 struct
的具體實現(xiàn)(只是提供了聲明), 這就需要對 source code
進(jìn)行改動.
另外 Swift
不支持直接與 Cpp
混編(調(diào)用), 實際是通過 C
來完成, 因此 C
的 header File
通常要添加如下聲明
#ifdef __cplusplus
extern "C" {
#endif
void entry(); /* Your functions or variables */
#ifdef __cplusplus
}
#endif