Xcode 5 で iOS 用 static library を作ろう！


Xcode 5 と iOS 7 SDK で、static library （静的ライブラリ）を作る手順をメモりました。
今回はRunScriptを利用して複数アーキテクチャ （armv7,armv7s,arm64含む）まで対応出来るものを作ってみます。

##目次
**1.プロジェクトの新規作成
2.Target追加
3.Run Scriptを追加
4.Copy Fileの追加
5.Architecturesの追加
6.Schemeの編集
7.実行
8.実装について**


##1.プロジェクトの新規作成
Menu > File > New > Project...

iOS > Other > "cocoa Touch static library" を選択

ここでは例として　Product Name を 「Hoge」 とするとします。

##2.Target追加
RunScriptを追加するためのTargetを追加します。

Menu > Editor > Add Taget…

iOS > Other > "Aggregate" を選択

ここでは例として　Product Name を 「Hoge-Universal」 とするとします。

##3.Run Scriptを追加
2.で作成した、"Hoge-Universal" の Build Phase を編集します。

Menu > Editor > Add Build Phase > Add Run Script Build Phase.

Scriptを追加します。

こんな感じ

```
xcodebuild_hoge() {
    xcodebuild \
    -target "${PROJECT_NAME}" \
    -project ${PROJECT_NAME}.xcodeproj \
    -configuration ${CONFIGURATION} \
    -sdk $1 clean build
}

BUILD_DIR="${SRCROOT}/build"
LIB_DIR="${SRCROOT}/library"
LIB_NAME="lib${PROJECT_NAME}.a"

IOS_LIB="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${LIB_NAME}"
SIM_LIB="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${LIB_NAME}"
DEST_LIB="${LIB_DIR}/${LIB_NAME}"


# remove dir
rm -rf "${BUILD_DIR}"
rm -rf "${LIB_DIR}"

# 1. xcodebuild
xcodebuild_hoge iphoneos
xcodebuild_hoge iphonesimulator

# mkdir
mkdir -p "${LIB_DIR}"

# 2. lipo
lipo "${IOS_LIB}" "${SIM_LIB}" -create -output "${DEST_LIB}"
```

xcodebuild で、Architectureごとにlibraryを作っています。
lipo で 全部まとめて １つのlibHoge.aにしています。
※細かい設定は必要に応じて変更してください。


##4.Copy Fileの追加
.aの中に含まず外に出すを指定
ヘッダファイル等をあえて外出しにしたい場合なんかはここで指定しておきます。


今回は例として 3.での出力ディレクトリと同じ場所にHoge.hを出力するように指定しています。

Menu > Editor > Add Build Phase > Add Copy files Build Phase.

**Destination** Absolute Path を選択
**Path** ${SRCROOT}/library を指定



##5.Architecturesの追加
このままだと、有効なアーキテクチャ（iphoneosで一つiphonesimulatorで一つ）のみ対応するライブラリしか出来ないので、複数のArchitectureに対応出来るように Build Settings の設定を変更します。

###Architectures

**Architectures** 
"standard architectures (including64-bit)" を選択

**Build Active Architecture Only**
Release側がNOになっている事を確認
 ->これがYESだと、iphoneos / iphonesimulator それぞれ１つずつの有効な Architecture しか反映されません。

**Valid Architectures**
 armv7 armv7s arm64 の他に Simulator用の i386 x86_64 を追加

###Deployment

**iOS Deployment Target**
デフォルトを最低iOSバージョン、arm64 Architecture に 7.0を指定

詳細：ライブラリをiOS7.0未満を対象とするアプリで利用する場合は、その最低バージョンをデフォルトに設定します。今回は64bitに対応させたいので、arm64についてはiOS7.0以上となるよう項目を追加して設定します。

**ex. 最低 64bit対応 かつ iOS5.0以降で使えるようにしたい場合の設定**
>Deployment Target:
　Debug 5.0
　　arm64  architecture:  7.0
　Release 5.0
　　arm64  architecture:  7.0

##6.Schemeの編集
release buildでライブラリを生成するように設定を変更します。

Schemeの "Hoge-Universal" を選択後 EditScheme を選択
Run の Build Configuration を"release"へ変更

##7.実行
以上の設定をした後に build すると、 プロジェクト/library/ 下にlibHoge.a と Hoge.h が生成されています。

```
lipo -info Hoge.a
```

lipoコマンドでlibHoge.aの中身を確認すると

```
Architectures in the fat file: /hoge/library/libHoge.a are: armv7 (cputype (12) cpusubtype (11)) i386 x86_64 (cputype (16777228) cpusubtype (0))
```

armv7,armv7s,arm64,i386,x86_64のアーキテクチャが確認出来ます。

##8.実装について

先ほどのライブラリは中身が空なので、ソースをちょろっと追加

```Hoge.h
#import <Foundation/Foundation.h>

@interface Hoge : NSObject {
}

-(void)hoge;
-(void)fuga;
-(void)bye;

@end
```

```Hoge.m
#import "Hoge.h"

@implementation hoge

-(void)hoge {
    NSLog(@"hoge!");
}

-(void)fuga {
    NSLog(@"fuga!");
}

-(void)bye {
    NSLog(@"...bye (;_;)");
}

@end
```


呼び出し側でHogeをimportして、こんな感じで。

```example.m
#import "Hoge.h"

@implementation example 


-(void)test {
 // :
 // :

 Hoge * hoge = [[Hoge alloc] init];
 [hoge hoge];
 [hoge fuga];
 [hoge bye];

}

@end
```


**実行結果**

```
hoge!

fuga!

...bye (;_;)
```