[iOS] Static Library (4) Universal Static Library

2010年11月17日水曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

[前回] Cocoaの日々: [iOS] Static Library (3) 複数のアーキテクチャへの対応は?

Universal Static Library とは異なるアーキテクチャごとに作成した *.a ファイルを1つにまとめたライブラリのこと。


参考情報


Universal Static Library については下記が参考になる。
Universal Static Libraries @ Cocoanetics

[Mac][iPhone][develop] iPhone OS用のほぼFrameworkの作り方 - Ni chicha, ni limona -平均から抜けられない僕-



アーキテクチャ毎 *.a ファイル作成


Xcodeのテンプレート "Cocoa Touch Static Library" から作る。

参考情報を参考に作成すれば簡単、ではなかった。Xcodeのバージョンの違いのせいかシミュレータとデバイスそれぞれ用のターゲットがうまく作成できなかった。
ターゲットのアーキテクチャで iOSもしくはシミュレータを設定しても Xcode左上のプルダウンでは必ず Simulator と Deviceのどちらかを選ばなければならない。

参考にした情報では「Base SDK」が選べるみたいだが設定の仕方がわらかない。

仕方が無いので取り合えず Simulator と Device はプルダウンを切り替えつつ手作業でビルドすることにした(参考情報によればターゲットをそれぞれ作った後、別のターゲットでまとめて一気にビルドができるらしい)。

こんなクラスを作りビルド。
@interface XCSampleClass : NSObject {

}

- (NSString*)helloString;

@end
#import "XCSampleClass.h"


@implementation XCSampleClass

- (NSString*)helloString
{
 return @"Hello World";
}

@end
ここまでで Simulator と Device 毎の *.a ファイルが作成できた。


ユニバーサル *.a ファイル作成


次にこれら *.a ファイルをひとつの *.a へまとめる。まとめるのに lipo コマンドを使う。

[参考] yebo blog: ユニバーサルバイナリ化するツール lipo

まず新規にターゲットを追加する。



次に情報を開く。

PRODUCT_NAMEがターゲット名になっているのでこれを目的のライブラリ名に変更する。実際のファイルは頭に lib が付く。

ターゲット内にある「スクリプトを実行」をダブルクリックで開き以下のスクリプトを書く。※lipo 以降は1行で
# make a new output folder
mkdir -p ${PROJECT_DIR}/build/${BUILD_STYLE}-universal/${PRODUCT_NAME}
 
# combine lib files for various platforms into one
lipo -create "${PROJECT_DIR}/build/${BUILD_STYLE}-iphoneos/lib${PRODUCT_NAME}.a"
 "${PROJECT_DIR}/build/${BUILD_STYLE}-iphonesimulator/lib${PRODUCT_NAME}.a"
 -output "${PROJECT_DIR}/build/${BUILD_STYLE}-universal/${PRODUCT_NAME}.a"


ビルドしてみよう。

できた。


組み込み


さて作成したライブラリを別のプロジェクトで使ってみよう。

新規にプロジェクトを用意し、そこへ先程ビルドした libUniversalStaticLibrary.a と XCSampleClass.h をドラッグ&ドロップでコピーする。

こんなコードを書いて
#import "XCSampleClass.h"

@implementation UniversalStaticLibraryClientViewController

@synthesize label;

- (void)viewDidLoad {
    [super viewDidLoad];
 
 XCSampleClass* obj = [[[XCSampleClass alloc] init] autorelease];
 label.text = [obj helloString];
}

実行。
出た。

シミュレータ、実機、共に問題なくビルド&実行ができた。



備考


ユニバーサルなライブラリを作ることはできたが、アーキテクチャ毎にいちいち手作業でビルドしなければならないので手間がかかる。参考情報のようにアーキテクチャ毎のターゲットが作れればいいが、作れない場合は xcodebuild コマンドを使って自前でコンパイルを行うしかなさそうだ。


ソースコード


GitHub からどうぞ。

UniversalStaticLibrary at static-lib-3 from xcatsan's iOS-Sample-Code - GitHub

UniversalStaticLibraryClient at static-lib-3 from xcatsan's iOS-Sample-Code - GitHub

Responses

Leave a Response

人気の投稿(過去 30日間)