Xcodeのバイナリの仕掛け

Xcodeをlipoで調べると、x86系、PowerPC系共に32bitと64bitに対応している(バイナリを持っている)事がわかります。ですが、普通に起動すると、32bitバイナリの方が起動してしまいます。

fat_magic 0xcafebabe
nfat_arch 4
architecture ppc7400
    cputype CPU_TYPE_POWERPC
    cpusubtype CPU_SUBTYPE_POWERPC_7400
    offset 4096
    size 132272
    align 2^12 (4096)
architecture ppc64
    cputype CPU_TYPE_POWERPC64
    cpusubtype CPU_SUBTYPE_POWERPC_ALL
    offset 139264
    size 198896
    align 2^12 (4096)
architecture i386
    cputype CPU_TYPE_I386
    cpusubtype CPU_SUBTYPE_I386_ALL
    offset 339968
    size 128000
    align 2^12 (4096)
architecture x86_64
    cputype CPU_TYPE_X86_64
    cpusubtype CPU_SUBTYPE_X86_64_ALL
    offset 471040
    size 170080
    align 2^12 (4096)

ところが、Xcode.app/Contents/MacOS/Xcodeを直接実行すると、しっかりと64bit版が起動します。

「なんでかなー?」と悩む事30分。Finderの「情報を見る」に「32 ビットモードで開く」というチェックがあるのを発見しました。このチェックが入っていると、64bitなバイナリが含まれていても、優先して32bitなバイナリを実行するようになるみたいです。

更に調べてみたところ、Info.plistLSArchitecturePriorityキーで使用するアーキテクチャの優先度を指定できるようです。

Leopardで追加されたこのキーはString型の配列で、現時点で i386/x86_64/ppc/ppc64 の値を入れる事が出来ます。基本的には配列の先頭に近いアーキテクチャほど、実行の優先度が高くなります。

しかし、最も優先されるのは先のFinderによる設定のようです。LSArchitecturePriorityがi386/x86_64の順になっていても、「32 ビットモードで開く」にチェックが付いていなければ、x86_64のバイナリで起動します。

Appleの資料によれば、ppcをi386よりも前に書けば、Intel Mac下における強制Rosetta実行も可能らしいです。ただし、LSRequiresNativeExecutionキーがYesだと、Rosetta環境では実行されなくなるみたいです。

色々と実験してみたのですが、Info.plistを書き換えてると、その内書き換えた内容が反映されなくなる?ようで、これらのキーの挙動の全容がいまいち掴めていません。まぁ、普通のアプリを作る上では、特に弄る必要はなさそうですけど。