アプリケーションと静的ライブラリを同時開発する場合 - Xcode 4.1

SPECIAL


ビルドの連携が上手くいかない様子

Xcode 4.1 で、ワークスペースを作成して、そこでアプリケーションと静的ライブラリを同時に開発している場合、その両者でビルドの連携が上手く取れない場面があるようでした。

たとえば、あるアプリケーションプロジェクトで、同じワークスペース内の静的ライブラリをリンクしているとします。

アプリケーションにワークスペース内のライブラリをリンクするには、アプリケーション側のプロジェクトの TARGETS の "Build Phases" で行えます。

ここの "Link Binary With Libraries" で [ + ] ボタンを押して、"Workspace" 内から静的ライブラリを選択しています。

 

このようにして、開発作業を進めていたのですけど、ある時とても頻繁に、静的ライブラリが更新されてくれなかったり、アプリケーションのデバッグ時にライブラリ内のメソッドを正しく実行できないということが発生してしまいました。

心当たりを探ってみると、どうやら、静的ライブラリの内容だけを更新して、アプリケーションの内容に手を付けなかった場合に、最新の静的ライブラリはビルドされるものの、アプリケーションでは静的ライブラリのリンクのし直しが行われないような感じです。

 

解決方法などがないものかと、設定を調整してみたりしましたけど、今のところ決定的な解決策が見つからない感じです。

例えば "Product" の "Edit Scheme" から、アプリケーションの "Build" 設定を調整して、Targets として静的ライブラリを含めてみましたが、それでもこのような不整合が発生してしまう感じです。

複数のプロジェクトを同時にビルドする場合には、ここの "Parallelize Build" にチェックが入っていると上手くいかない場合もあるとの話を聞いて、そのチェックを外してみましたけど、それでも解消される感じはありませんでした。

 

静的ライブラリ側の "Run" 設定で、デバッグ時に実行するアプリケーションとして選択するようにもしてみましたが、これでも同じ様子です。

このようにすると "Build" 設定の方にも自動的に、アプリケーションがビルド対象として登録されてはくれるのですけど、この場合でも、やはりアプリケーション側のソースコードに手を付けないと、更新された静的ライブラリがリンクし直されてくれないために、古いライブラリの内容のまま、実行されてしまいました。

 

結局、今のところは、アプリケーション側でも必ずソースコードを保存し直してからビルドするという方法で対応してはいますけど、なかなか手間な感じです。

ソースコードに変更を区分けなくても、どこかのソースコードを選択して [コマンド]+[S] で上書き保存してあげれば、ちゃんとビルドされてくれるような感じですけれど、こういった無意味な手間をかけなくても、静的ライブラリのリンクを更新してくれたなら、うれしいところなのですけれどね。

 

毎回のソースコードの空保存を自動化する

ビルドの連携が上手くいかない状況が Xcode 4.3.2 になっても続いているので、それならと、毎回しなければいけないソースコードの保存作業を自動化してみることにしました。

具体的には、最終的にビルドしたいアプリケーションの Schema で、Build の Pre-actions スクリプトを登録して、そのスクリプトで何らかのファイルを自動で更新するという方法を取ってみます。

 

そのために、Xcode のシステムメニューの "Product" から "Edit Scheme ..." を選択します。

スキーマの設定画面が表示されたら、"Scheme" プルダウンメニューで目的のプロジェクトを選択して、そこの "Build" のところの "Pre-actions" を選択します。

そして、画面の下の右側にある 【+】 を押して、"New Run Script Action" を選択します。

 

このようにすると、新しい"Run Script" アクションが Build の Pre-actions に追加されるので、ここで、ソースファイルを更新するスクリプトを記述します。

ここでは、スクリプトの内容として "touch ${SRCROOT}/main.m" とすることで、ビルド直前に "main.m" ファイルが更新されたことにしています。

このとき、環境変数 "SRCROOT" を使用するために、"Provide build settings from" のところで、このファイルを持つプロジェクトを選択するのを忘れないようにしておきます。

 

このようにすることで、ビルドのたびに勝手に "main.m" ファイルの更新日が更新されるので、毎回手動で main.m を保存しなおすのと同じ効果が得られます。

無理やりな対応ですし、意味のないコンパイルが増えるのであまり心地よくは無いですけど、それでも保存し直し忘れてリンクがされないよりは開発効率が断然良くなるので、今のところはこれでしのいでおくことにします。