FreeBSD で iPhone 2.0 のクロス開発環境を構築

MacOS X Leopard を購入して、 Official iPhone SDK で開発を始めました。 しかし、Xcode という慣れない GUI の開発ツールではコードを書く作業効率が下がるのが実感できたので、 Official iPhone SDK のライブラリとヘッダを使った、 CUI の開発環境を構築しようと調べてみました。 本ページは、上記のような GUI を使った開発環境に馴染めないプログラマー向けです。 今回は、FreeBSD 6.3-RELEASE native 上に構築できたので、その手順を記します。

Jailbreak for iPhone 2.0

Official iPhone SDK で作成したアプリケーションは、 iPhone Developer Program に参加しないと実機での動作確認ができません。 なので、まずは、iPod touch (firmware 2.0.2) を jailbreak します。 今回は、お手軽な jailbreak ツールの QuickPwn for Mac 1.0 を利用しました。 QuickPwn は、PwnageTool 2.0.3.1 for Mac と違い、iPod touch 上の既存の内容を破壊しないようです。

DFU モードへの移行時のボタン押しのタイミング以外は、 作業手順でつまづくことはありません。 ちなみに、私は4回やり直しました。

jailbreak すると Cydia というインストーラが導入されます。 Cydia から "iPhone 2.0 Toolchain" を入れます。 これを使うと iPod touch 本体でアプリケーション開発ができます。 FreeBSD でアプリケーションを作っても iPod touch 本体で実行するには、 このツールを導入するとインストールされる ldid が必要なのです。

iPhone Toolchain を FreeBSD 上に構築

前準備

Upgrading the iPhone Toolchain のページの手順にしたがって、FreeBSD 上に iPhone Toolchain を構築します。 最初に、Apple's Darwin Open Source Releases から以下に示す必要なソースコードを入手します。 入手したソースコードは、${HOME}/Apple というディレクトリに展開しておきます。 ソースコードの入手には、Apple へのユーザ登録が必要です。

  • CF-476.14.tar.gz
  • DiskArbitration-183.tar.gz
  • IOCDStorageFamily-39.tar.gz
  • IODVDStorageFamily-26.tar.gz
  • IOGraphics-233.3.tar.gz
  • IOHIDFamily-258.1.tar.gz
  • IOKitUser-388.2.tar.gz
  • IOStorageFamily-89.tar.gz
  • Libc-498.1.1.tar.gz
  • WebCore-5525.18.1.tar.gz
  • cctools-667.8.0.tar.gz
  • configd-212.2.tar.gz
  • launchd-258.12.tar.gz
  • libsecurity_authorization-32564.tar.gz
  • libsecurity_cdsa_client-32432.tar.gz
  • libsecurity_cdsa_utilities-33506.tar.gz
  • libsecurity_cms-32521.tar.gz
  • libsecurity_codesigning-33803.tar.gz
  • libsecurity_cssm-32993.tar.gz
  • libsecurity_keychain-34101.tar.gz
  • libsecurity_mds-32820.tar.gz
  • libsecurity_ssl-32463.tar.gz
  • libsecurity_utilities-32820.tar.gz
  • libsecurityd-33470.tar.gz
  • xnu-1228.5.20.tar.gz

上記ソースファイル名は、 Upgrading the iPhone Toolchain ページのバージョンとは違いますので、ご注意ください。

iPhone filesystem の構築

Upgrading the iPhone Toolchain では、 firmware 1.1.4 の iPhone filesytem を使った手順を記述しています。 ここでは、Official iPhone SDK を元に firmware 2.0.x 用の iPhone filesystem を構築します。 SDK ファイルの都合上、作業環境は MacOS X Leopard です。

 leopard% mkdir ${HOME}/iphone-filesystem
 leopard% cd /Developer/Platforms/iPhoneOS.platform\
             /Developer/SDKs/iPhoneOS2.0.sdk
 leopard% pax -rw -p p usr ${HOME}/iphone-filesystem
 leopard% mkdir -p ${HOME}/iphone-filesystem/System/Library
 leopard% cd System/Library
 leopard% pax -rw -p p Frameworks \
            ${HOME}/iphone-filesystem/System/Library
 leopard% pax -rw -p p PrivateFrameworks \
            ${HOME}/iphone-filesystem/System/Library
 leopard# cd /Developer/SDKs
 leopard# ln -s /Developer/Platforms/iPhoneOS.platform\
                /Developer/SDKs/iPhoneOS2.0.sdk .

最後に、install_headers.sh スクリプトを使って /Develop/SDKs 以下から必要なヘッダをコピーします。 はじめに、install_headers.sh の INCLUDE_DIR 変数を環境に合わせて編集してください。

 leopard% ./install_headers.sh

iPhone 2.0 Toolchain の構築

Upgrading the iPhone Toolchain の "Filesystem Location" 節からはじまる一連の作業を行います。 一応、自動化目的の toolchain.sh スクリプトを作成しました。 使用する場合は一通り目を通して、自分の環境に合わせて変数を編集してください。

"Building Darwin CC Tools" 節まで作業が進んだら、 FreeBSD 用の odcctools-9.2-ld.FreeBSD.patch を当てます。 これは、Linux 依存の "/proc/self/exe" に関するコードを FreeBSD で利用できるように "/proc/curproc/file" を使った方法に変更します。 パッチの作成には、 Binary Hacks ―ハッカー秘伝のテクニック100選に、 同様の事例が記載されたので参考にしました。

上記の方法でパッチを当てた後は、target を arm-apple-darwin9 に変更して、FreeBSD でも同様の手順通りに作業を進めます。

 freebsd% cd odcctools-9.2-ld
 freebsd% patch < odcctools-9.2-ld.FreeBSD.patch
 freebsd% cd build/cctools-iphone
 freebsd% CFLAGS=-m32 LDFLAGS=-m32 ../../odcctools-9.2-ld/configure \
          --target=arm-apple-darwin9 \
	  --prefix=/opt/local \
          --disable-ld64
 freebsd% make
 freebsd# make install
 freebsd% cd build/gcc-4.2-iphone
 freebsd% ../../llvm-gcc-4.2/configure \
          --target=arm-apple-darwin9 \
          --prefix=/opt/local \
          --with-build-sysroot=/opt/local/share/iphone-filesystem \
          --enable-languages=c,c++,objc,obj-c++ \
          --with-as=/opt/local/bin/arm-apple-darwin9-as \
          --with-ld=/opt/local/bin/arm-apple-darwin9-ld \
          --enable-wchar_t=no \
          --with-gxx-include-dir=/usr/include/c++/4.0.0
 freebsd% make
 freebsd# make install
 freebsd# ln -s /opt /opt/local/share/iphone-filesystem

iPod touch 用アプリケーションの動作確認

FreeBSD 上に構築した iPhone 2.0 Toolchain 環境で正しくアプリケーションが作れるか動作確認をします。 FreeBSD 上の arm-apple-darwin9-gcc でコンパイルした実行ファイルを iPod touch 側に転送して、ldid コマンドでコードに署名をします。

 freebsd% cat <<EOT > hello.c
 #include 
 int main() { printf("Hello, World!\n"); }
 EOT
 freebsd% arm-apple-darwin9-gcc -o hello hello.c
 freebsd% scp -p hello root@[iPhone IP Address]:
 iphone$ ldid -S hello
 iphone$ ./hello
 Hello, World!

なお、UIKit を使った自作プログラムは、 コードを結構修正しないとコンパイルできないようで、 実際に GUI アプリケーションが作れるかは未確認です。

2008年9月15日追記。
Two versions of Hello World (SDK headers vs Open Tool Chain headers) の SDK 版のプログラムが本クロス開発環境でコンパイルでき、 iPod touch (firmware 2.0.2) 上で動作することを確認しました。 LDFLAGS に余計なオプションがありますが、 以下に示す Makefile でコンパイルできました。

CC=arm-apple-darwin9-gcc 
LD=$(CC)

HEAVENLY= /opt/local/share/iphone-filesystem
CFLAGS= -fobjc-abi-version=2 -redefined_supress
LDFLAGS= -bind_at_load \
	 -L${HEAVENLY}/usr/lib \
	 -F${HEAVENLY}/System/Library/Frameworks \
	 -F${HEAVENLY}/System/Library/PrivateFrameworks \
	 -multiply_defined suppress \
         -framework CoreFoundation \
         -framework Foundation \
         -framework UIKit \
         -framework QuartzCore \
         -framework CoreGraphics \
         -framework GraphicsServices \
         -framework CoreSurface \
	 -lstdc++ -licucore -llockdown -lz -lxml2 \
         -lobjc

all: Hello

Hello: HelloSDK.m
	$(LD) $(LDFLAGS) -o $@ $^
#	/usr/bin/ldid -S Hello

%.o: %.m
	$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

clean:
	rm -f *.o Hello
Google