Xcode4.2のArchitectures設定
Xcodeプロジェクトの設定で、ArchitecturesのところがXcode4.1.2までは"armv6 armv7"となっていたのが、Xcode 4.2からは、

のように、"Standard (armv7) - $(ARCHS_STANDARD_32_BIT)"などとなっていて、armv6が外されています。
このままビルドすると、Deployment TargetにiOS4.3以前を指定している場合に問題が発生するようです。
iOS4.3以前をサポートする場合は、

のように、armv6も追加しておく必要があるようです。(参照:mipoiさんのブログ)
デフォルトの選択肢の中には"Standard (armv7)"しかないのですが、Other...を選んで+ボタンを押して自分で追加すれば良いようです。
自分でタイプして大丈夫なのかとなんとなく不安だったので調べてみると、次のファイルに定義されているようなので、大丈夫そう。
/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/iPhoneOSArchitectures.xcspec
そもそもarmv6とかarmv7とかって何?
私はそもそもarmv6とか7とかっていうものに馴染みがなかったので調べてみると、モバイルデバイスなどで使われるCPUの命令セットアーキテクチャのことらしい。PCのCPUはIntel社のx86がメジャーなアーキテクチャの一つであるように、省電力のモバイルデバイスではARM社のアーキテクチャがメジャーらしい。
Wikipediaのこちらのページによくまとまっていました。
iOSアプリを開発するに当たって知っておきたいことは、どのデバイスがどのアーキテクチャに対応しているかということだと思います。Wikipediaの表をまとめると、次のようになります。
ARMv6に対応: iPhone, iPhone 3G, 1st & 2nd Generation iPod Touch
ARMv7にも対応: iPhone 3GS, iPhone 4, iPhone 4S, iPad, iPad2, 3rd & 4th Generation iPod Touch
armv7に対応していない古いデバイスをサポートするには、armv6をビルドの設定に入れておかなければならないようです。
armv6とarmv7の違いは、armv7では浮動小数点の演算の最適化が行われているといったようなことらしいですが、ここではあまり深入りはしません。。。こちらのQ&Aなどをご参照のこと。
ちなみに、ARM6、ARM7とARMv6、ARMv7は似て見えるけど実は全く別のもののようなので表を見るときにはご注意。>_<
Xcode 4.2で使えるコンパイラ
Xcode 4.1以前では、コンパイラは
- GCC 4.2
- LLVM GCC 4.2
- LLVM Compiler 2.0
が選べました。
Xcode 4.2では、
- LLVM GCC 4.2
- Apple LLVM Compiler 3.0
だけになり、GCC 4.2はサポートされていないようです。
LLVMコンパイラの問題について
以前、Xcode 4.1を使っていたときに、LLVM GCC 4.2を使ってアプリをリリースしたことがありましたが、そのビルドはiPad 2だけで起動時にクラッシュしてしまうという問題が発生しました。(3台のiPad2 + iOS 4.xで100%再現。コンパイラを変えてビルドすると動作した。デバッグビルドではLLVM GCC 4.2でも動作したので、リリースビルド時のコンパイラの最適化に問題があった気がします。)
他にも、Core Dataを使うときにLLVMコンパイラで不具合が発生するという話もあり、それ以来、GCC 4.2を使ってきました。
しかし、Xcode 4.2で、AppleはGCC 4.2のサポートを完全に終了してしまったようです。プロジェクトの設定で無理やりGCC 4.2を設定すると、次のようなエラーがでてビルドできません。
Unsupported compiler 'GCC 4.2' selected for architecture 'armv6'
どうやら時代の流れに逆らわずに、新しいものをトライするしかないようです・・・。
幸運なことに、Xcode 4.2のLLVM GCC 4.2でコンパイルしたビルドではiPad 2でクラッシュしていた問題が発生しなくなりました。(iPad 2 + iOS4.3、iPad 2 + iOS 5.0で確認。)
また、Apple LLVM Compiler 3.0を使ってビルドすると、1st Generation iPod Touch + iOS 3.1.3でアプリが起動せずにクラッシュするという問題が発生しました。理論的にはLLVM GCC 4.2とApple LLVM Compiler 3.0では、パーサーが異なるだけで出来上がるバイナリは同じになるはずなのですが・・・現実は何か違いがでてしまうようです。
結局、私は当面はLLVM GCC 4.2を使う方針で決定しました。
アーキテクチャ毎に異なるコンパイラを使用する方法
Xcodeのプロジェクトの設定で、コンパイラの設定の”+”ボタンを押して、対象とするアーキテクチャ毎にコンパイラを使い分けることもできるようです。(物書堂さんに教えていただきました)

例えば、ARMv6の古いデバイスにはLLVM GCC 4.2を、ARMv7をサポートしている新しいデバイスにはApple LLVM Compiler 3.0を使うといった設定ができるようです。
この設定を使って、1st Generation iPod Touch(ARMv6)向けにはLLVM GCC 4.2を使ってクラッシュを回避できないかと試してみたのですが・・・やはりクラッシュしてしまいました。orz
何かが間違っているのかもしれませんが・・・ー_ー;
とりあえずLLVM GCC 4.2のみの設定ならば問題なさそうなので、当面はこれで行くことにします。。。
新しいモノ(Xcodeとかコンパイラとか)は魅力的に見えて何でもすぐに試したくなるけど、やっぱりいろいろと不具合があってコワイ。。。でもリスクを取って新しいモノを使っていかなければならないこともありますね。。。





