2017年1月9日月曜日

XCodeでsubmoduleでC/C++のソースを持ってくる方法

XCodeのプロジェクトに、GitHub上の別プロジェクトのソースをsubmoduleとして組み込みたいのですが、検索してもあまり良い方法が見つからなかったので、個人的なメモを兼ねてそのやり方を書いておきます。

なお、これは実際LaiNES-iOSで実施している手順です。
https://github.com/suzukiplan/LaiNES-iOS
あと非公開ですがInvader Block 6のリポジトリでも同じやり方でVGSモジュールを組み込んでいます。

まず、XCodeでプロジェクト作成直後のLaiNES-iOSのディレクトリ構成が以下のような感じだったとします。

$ pwd
/Users/suzukiplan/programs/LaiNES-iOS
MacBook-Pro:LaiNES-iOS suzukiplan$ ls -l
total 208
drwxr-xr-x  34 suzukiplan  staff   1156  1  9 08:40 LaiNES
drwxr-xr-x   5 suzukiplan  staff    170  1  8 17:30 LaiNES.xcodeproj
MacBook-Pro:LaiNES-iOS suzukiplan$ 

このディレクトリ上で、git submodule add をします。

$ git submodule add https://github.com/suzukiplan/LaiNES.git cpp

※本当はそのままの名称にしたかったのですがXCodeで作成したプロジェクトのディレクトリと被ってしまうのでC++モジュールのリポジトリはcppという名称にリネームしています。

そして、Finderでそのcppディレクトリを開き、コンパイル対象のモジュールをドラッグ&ドロップでXCodeのプロジェクトに持っていきます。
この時、「Copy items if needed」のチェックを外すことで、プロジェクト内からcppを参照する形にします。
このやり方で追加すれば、同じリポジトリ内で相対パス参照でモジュールを参照する形になります。

試しに、project.pbxprojファイルの内容を覗いてみると、確かに相対パス参照になっていることが分かります。

$ cat LaiNES.xcodeproj/project.pbxproj | grep apu.cpp
74B47A4C1E1F748200B5ADFE /* apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74B47A451E1F748200B5ADFE /* apu.cpp */; };
74B47A451E1F748200B5ADFE /* apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = apu.cpp; path = cpp/src/apu.cpp; sourceTree = SOURCE_ROOT; };
74B47A451E1F748200B5ADFE /* apu.cpp */,

74B47A4C1E1F748200B5ADFE /* apu.cpp in Sources */,

あとは、このリポジトリを git clone した時、何もせずにXCodeでプロジェクトを開くと参照切れでエラーになってしまうので、忘れずに git submodule init と git submodule update をする必要があります。

この手順で困るケースとしては、参照するモジュールがディレクトリ階層を意識する構成になっている時です。その場合、何か色々とやる必要があって面倒くさいです。(だから、私はXCodeで扱う前提のC/C++リポジトリを作る時、いつもソースコードは src ディレクトリ以下に階層を掘らないようにしたり、ファイル名が被らないように気をつけているつもり)

まぁ、本格的に複雑な構成のプロジェクトにするなら、cocoa podsを使うべきですが、cocoa podsを使うまでもない簡易的なモジュール組み込みをしたい場合のTIPSということで。

しかし、cocoa podsは極力使いたくない... 遅いしわざわざフレームワークとして作るのが面倒だし、ついでに podfile や podspec の書き方に謎が多い(それでいて公式ドキュメントも中途半端なものしかない)ので、どう書けば良いのか分からず色々と試行錯誤 → 動作がイチイチ遅いので無駄に時間を浪費 というコンボが頻発するので、苦手です。

余談ですが、XCodeの公式ツール類が充実してなさっぷりは酷すぎる。
cocoa pods的なものは公式で準備すべきなのに未だに無いとか。
それでいて、非公式プラグインはバッサリ切ってくるというね。
Android Studioと並行して使っているとXCodeの酷さが色々と目立ちます。
XCodeも公式にIDEAベースとかにした方が、色々と良くなったりしそうな気がする。