Xcode 4.3でスタティックリンクライブラリィを扱う (その2

さて、今日はアプリケーションからスタティックライブラリをリンクする設定を行う手順をまとめる。
外部のライブラリィを自分のプロジェクトに組込む等、普段はこちらのほうが有用だろうか。

2.アプリケーションプロジェクトでスタティックリンクライブラリを組み込む

アプリケーションプロジェクトにスタティックリンクライブラリプロジェクトを追加する

まずは対象となっているアプリケーションのプロジェクトに、先日作ったスタティックリンクライブラリ用のプロジェクトを追加する。
方法は「Add Files to〜」で使用するライブラリのプロジェクト(xxxx.xcodeproj)を追加するだけだが、実はここが重要で、私はここで追加の方法の選択を間違っていたために失敗していたのである。


Xcode4.xの「Add Files to〜」によるプロジェクトへのファイル追加は対象となるディレクトリの扱いに関して二通りある。

  • Create groups for any added folders

追加したフォルダに対してXcode内で認識できる"グループ"を追加する。(黄色のフォルダとして描画される) ここで作成されるのは論理的なグループでありXcode内部でしか認識されない階層であり、作成後にはファイルシステムと同じように見えても同期している訳ではないので注意が必要である。

  • Create folder reference for any added folders

こちらは追加したフォルダに対してファイルシステム上の物理フォルダへの参照(リンク)を作成する。従ってOSのファイルシステムの構造がそのままでプロジェクトに追加される。(水色のフォルダとして描画される)

これらを用途によって使い分けなくてはならない訳だ。

スタティックリンクライブラリのプロジェクトを追加する場合、追加する対象はプロジェクトファイル(.xcodeproj)だが、追加時のフォルダの指定を後者の"Create folder reference for any added folders"にしなくてはならない。そうすることでXcodeは.xcodeprojを認識し、プロジェクトの構造がアプリケーションのプロジェクト内に展開される。

スタティックリンクライブラリのプロジェクトがアプリケーションプロジェクト下に読込まれているのが判るだろうか。

もう一度書くが、"Create groups for any added folders"では追加されるのはプロジェクトファイルのみであり、他のファイルが展開されない。"Create folder reference for any added folders"にしなくてはならない。

ターゲットのビルドフェーズでライブラリを組み込む

今までは"PROJECT"レベルの設定だったが、ここからは各ビルドTARGET毎の設定になる。
アプリケーションではスタティックライブラリのヘッダを参照するためリンク時にスタティックリンクライブラリを追加する必要がある。

  1. ボタンを押下するとダイアログが開き、上で追加したスタティックリンクライブラリプロジェクト中のライブラリの実体(xxx.a)が"Link Binary With Libraries"に見えているので追加する。


リンカの依存関係に必要なライブラリィとして追加されているのが判るだろうか。

ヘッダのパスを指定する (User Header Search Paths)

アプリケーションをエラー無しにコンパイルするには、スタティックリンクライブラリの作成時にpublicとして公開したヘッダファイルを参照できる必要がある。そのためにビルドセッティングの"User Header Search Paths"に環境変数$(BUILT_PRODUCTS_DIR)を設定する。(実際には$(BUILT_PRODUCTS_DIR)/$(TARGET_NAME)だが、上位のパスに/**が付加されてリカーシブサーチとなるようで、$(TARGET_NAME)は無くても探してくれるようだ)


ここまでの設定を間違いなく行えば、スタティックリンクライブラリを組み込んだ状態でアプリケーションプロジェクトのコンパイルが成功する。

はずなのだが、実際にはこのままコンパイルを行うと既存クラスを拡張するカテゴリをロードできずにコンパイルが失敗する。(成功しているように見える場合もあるが、実際には実行に失敗する。)

-ObjCのおまじないを追加する

以前にも書いたことがあるが、Objective-Cのリンカにはバグがあり、スタティックライブラリ中で定義されているカテゴリをロードすることができない。これを回避するためにはアプリケーション側のビルドセッティングパラメタ"Other Link Flags"にパラメタ"-ObjC"追加する必要がある。

Unrecognized Selector その後

さて、ではビルドして出力結果を見てみよう。

このようにアプリケーションのインストールディレクトリにアプリケーションバンドル(AppWithStaticLiv.app)と、スタティックライブラリ(LibtestStatic.a)と、公開設定されているヘッダファイル(TestStatic.h)がコピーされていれば成功だ。 おめでとう。

これで本当にスタティックライブラリを組み込んだiPhoneアプリケーション用のプロジェクトをビルドできるようになった。

それにしても面倒だ。
外部でビルドしたスタティックリンクライブラリを使うだけでこれだけの作業が必要とか、今回のように一度まとめることで簡単になるかなと思ったのだが、やはり面倒だった。 単にプロジェクトを追加するだけでコンパイル可能になるのが正しい姿だと思うのだが。