libpngを使ったc++ライブラリをiPhoneアプリに組み込む


C++ で書かれたstatic libraryをswiftで作成されたiosアプリに組み込む方法はたくさんの記事があるのでそちらを参照していただくとして、今回はlibpngを使った自作のC++ライブラリを組み込む方法を記載します。

Swift からC++ライブラリを呼び出す方法
swiftでc++の資産を使おう https://qiita.com/tomnic/items/37ee52aa18dcb5c0b51e

大事なポイント

知っている人は知っている話ですが、MacとiPhoneではCPUのアーキテクチャーが違う。下の構成がほとんどなのかな。

  • Mac: X86_64
  • iOS: arm64

そのため、自作ライブラリや自作ライブラリで使っている外部ライブラリはarm64とX86_64でビルドしなくてはだめ。これを知らなくて結構苦労した。

自作ライブラリのビルド

C++のビルドはcmakeを使っていたため結構簡単にできる。流れは、cmakeでXcodeのプロジェクトを作成して、archintectureの設定をしてビルドし、最後はlipo コマンドでそれぞれのarchitecture用にビルドされたstaticライブラリをマージする。

  1. cmake projectのルートで下記を実行。Xcodeのプロジェクトが作成される。

    cmake -G Xcode .
    
  2. XcodeのBuild settingメニューでアーキテクチャーの設定をする(ただしこの設定を下だけでは各architecture用のlibraryは作成されない。

  3. 画面左上の出力モードを設定する。arm architecture用は Generic iOS Device、x86_64用はシミュレーター(deviceは何でも良い)を選択する。

  4. ビルドを実行すると、arm64が./Release-iphoneosにX86_64は./Release-iphonesimulatorにstatic library [xxx.a]が出力される。

  5. lipoコマンドで各ライブラリをマージする。例えば xxx.aとyyy.aをマージしてzzz.aを./Releaseディレクトリに保存したい場合には下記のようなコマンドを実行する

    lipo -output ./Release/zzz.a -create ./Release-iphoneos/xxx.a ./Release-iphonesimulator/yyy.a
    
  6. マージされたstatic libraryをiOSアプリのプロジェクト内のライブラリのリンクがはられている箇所にコピーする。またobjective-Cから呼び出す関数のヘッダー情報が記載されたヘッダーファイルも、同様にiOSアプリのプロジェクト内のヘッダーのリンクがはられているディレクトリに保存する。

zlibのarm64およびx86_64ビルド

私が作成したC++ライブラリではlibpngを使っているためlibpngもarm64対応する必要があります。またlibpngは内部でzlibを使用しているため、zlibもarm64対応する必要があります。xlibはxcodebuidコマンドでビルド、libpngは./configureに引数指定してビルドしました。

  1. zlibのソースファイルをhttps://zlib.net/からダウンロードし展開する
  2. 展開されたディレクトリに移動し下記を実行してXcodeのプロジェクトファイルを作成する

    cmake -G Xcode .
    
  3. arm64、x86_64それぞれについて下記コマンドを実行してビルドする

arm64

$ xcodebuild -project "zlib.xcodeproj" -sdk "iphoneos" IPHONEOS_DEPLOYMENT_TARGET="7.0" ARCHS="armv7 armv7s arm64"  ONLY_ACTIVE_ARCH=NO clean build TARGET_BUILD_DIR="./install_zlib_arm64" -scheme="ALL_BUILD"

x86_64

$ xcodebuild -project "zlib.xcodeproj" -sdk "iphonesimulator" IPHONEOS_DEPLOYMENT_TARGET="7.0" ARCHS="x86