Universal Binaryを作成するには、GCCに対して「-arch」オプションを複数回指定すればよい。Xcodeと同様に、「-arch」が1つだけ指定されていればそのCPU向けのコードを作成し、「-arch」が複数回指定されていた場合は自動的にUniversal Binaryとしてすべてを結合した実行ファイルを生成する(実行例1)。
% cc -arch ppc -arch ppc64 main.c
% ./a.out
hello, world
Makefileなどでコンパイルを制御し、いったんオブジェクトファイルを作ってからそれをまとめている場合は、オブジェクトファイルの作成時だけではなく、リンクのときも「-arch」オプションを忘れないように指定する必要がある点に注意されたい。
また、Xcodeでの開発時と同じく、コマンドラインからビルドする場合もそのアーキテクチャの共有ライブラリがすべて存在していなければならない点は変わりない(実行例2)。これを回避するには、GCCに「-isysroot」オプションを追加し、Xcodeと同じようにターゲットSDKを指定するとよい(実行例3)。
% cc -arch ppc -arch i386 main.c
/usr/bin/ld: for architecture i386
/usr/bin/ld: warning fat file: /usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libSystem.dylib does not contain an architecture that matches the specified -arch flag: i386 (file ignored)
/usr/bin/ld: Undefined symbols:
___keymgr_dwarf2_register_sections
__cthread_init_routine
_atexit
_errno
_exit
_mach_init_routine
_puts
collect2: ld returned 1 exit status
lipo: can't open input file: /var/tmp//ccbAi41c.out (No such file or directory)
% cc -arch ppc -arch i386 main.c -isysroot /Developer/SDKs/MacOSX10.4u.sdk
% ./a.out
hello, world
何らかの理由でビルド時に一気にUniversal Binaryを作成するのではなく、アーキテクチャごと個別にビルドした後に1つのUniversal Binaryにまとめたい場合もある。例えば、EmacsやTeXのようにダンプ*を使用するソフトウェアの場合、それぞれ個別のCPUでダンプした後に、その生成物をUniversal Binaryとしてまとめなければ意味がない。
そうしたときに使用するのがlipoコマンドだ。lipoコマンドはFATヘッダとfat_arch構造体の操作を行い、Universal Binaryから特定のアーキテクチャのコードだけを抜き出したり、複数のコードをまとめることができる。先のダンプの例の場合、いったんそれぞれのCPUのマシンで個別にビルドし、生成されたバイナリを1カ所にまとめ、lipoコマンドでつなぎ合わせることでUniversal Binary化できる(実行例4)。
% cc -o ppc.out -arch ppc main.c
% cc -o i386.out -arch i386 main.c -isysroot /Developer/SDKs/MacOSX10.4u.sdk
% lipo -create -output mab.out -arch ppc ppc.out -arch i386 i386.out
% file ./mab.out
./mab.out: Mach-O fat file with 2 architectures
./mab.out (for architecture ppc): Mach-O executable ppc
./mab.out (for architecture i386): Mach-O executable i386
% ./mab.out
hello, world
メモリ上の状態をすべてファイルに出力したもの。不正な処理をしてカーネルから強制終了されたときに生成されるcoreファイルや、カーネルがクラッシュしたときに残されるファイルがダンプだ。EmacsやTeXなどは、それ自身のバイナリをロードした後に大量の初期設定やスクリプトを読み込む。これを実行時に毎回行っていては効率が悪い。そこで、いったん素体となるコマンドをビルドした後、そのコマンドを実行し必要なファイルや初期設定を読み込んだ後の状態をメモリ上に構築、強制的にコアダンプさせることでその状態を保存する。次回起動時からはダンプをロードすることで起動の高速化を図っている。
Copyright © ITmedia, Inc. All Rights Reserved.