Edited at

Clang Modules (modulemap) を利用してCライブラリをSwiftで使う

More than 1 year has passed since last update.


はじめに

みなさん、こんにちは。

iOS / tvOSアプリデペロッパーのhiroakitです。

この記事ではSwiftでCあるいはC++で書かれたライブラリを利用する方法についてご紹介いたします。

この記事の執筆時に使用した開発環境は以下の通りです。

$ sw_vers                                                                               

ProductName: Mac OS X
ProductVersion: 10.12.6
BuildVersion: 16G1114

$ xcrun -find xcode build
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild

$ xcodebuild -version
Xcode 9.2
Build version 9C40b

$ xcrun -find clang
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang

$ clang --version
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin


動機

Cライブラリ (e.g, OpenJPEG) をSwiftのフレームワークにして利用したいことがあると思います。

この記事では説明用に以下のCのライブラリで進めたいと思います。

- libExample.a

- include/Example.h
- include/ExampleEncoder.h

このライブラリをSwiftで書かれたアプリがフレームワークでインポートして利用したいとします。


import UIKit
import Example

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
ExampleEncoder.run(urlString: "https://www.example.com/", profile: "path/to/profile")
}
}

この場合、CライブラリをSwiftでラップしてフレームワークにするときに、 下記のように .modulemap ファイルを用意する必要があります。


framework module Example {
umbrella header "Example.h"

export *
module * { export * }

header "ExampleEncoder.h"
}

このExample.frameworkをアプリ側で追加したら、そのフレームワークのパスをXcodeプロジェクトの下記設定項目に設定する必要があります。


  • FRAMEWORK_SEARCH_PATHS

  • LIBRARY_SEARCH_PATHS


.modulemap ファイルとは

.modulemap ファイルとはCライブラリで利用しているヘッダーファイルをClang Modulesを通じてSwiftに伝えるために必要なものです。

以下は.modulemapファイルの形式を示したものです。module map言語を使い記述します。

[explicitopt] [frameworkopt] module module-id attributesopt {

/* module-member */
}

なお、module map言語はClangのメジャーバージョン間で動作保証がされていません。そのため、Xcodeが内包しているClangのメジャーバージョンが変わった場合、この辺りの動作について開発者の意図通りになっているか確認する必要があります。

The module map language is not currently guaranteed to be stable between major revisions of Clang.


まとめ

modulemapを用意することでCライブラリをSwiftで利用する方法についてご紹介しました。

modulemapは一発でうまくいかないこともあるので、その辺りの覚悟とセットでご用意ください。

参考資料にmodulemapの例を記載しました。


参考資料