UniversalBinary
ppc と i386 等複数のアーキテクチャのバイナリを一つのファイルに含む Mach-O executable file のこと。 Fat binary との呼び方もある。
目次
見分け方[編集]
コマンドライン[編集]
file コマンドを実行する。i386, ppc 両対応のバイナリは次のように表示される。
$ file test2 test2: Mach-O fat file with 2 architectures test2 (for architecture i386): Mach-O executable i386 test2 (for architecture ppc): Mach-O executable ppc
Finder[編集]
「情報を見る」の「種類」欄を参照する。それぞれ次のように表示される。
- アプリケーション(PowerPC) ... PPC 版アプリケーション
- アプリケーション(Universal) ... Universal Binary 版
- アプリケーション(Intel) ... Intel版
作り方[編集]
Xcode[編集]
「ファイル」メニューから「情報を見る」を選択し以下の操作をする。
- 「一般」パネルの「ターゲット SDK を使用したクロス開発」で『Mac OS X 10.4 (Universal)』を選択。
- 「ビルド」パネルの「アーキテクチャ」をダブルクリックして PowerPC と Intel の両方にチェックを付ける。
gcc を直接叩く[編集]
Xcode を使わずに gcc に直接 UniversalBinary を作成させる方法。 基本的には以下の二つの方法がある。
- 一括してコンパイルする方法
大規模なソフトにはあまり向かない。configure が endian の判断をする場合には使用できない。
$ gcc -arch i386 -arch ppc test.c -isysroot /Developer/SDKs/MacOSX10.4u.sdk -o test2 $ file test2 test2: Mach-O fat file with 2 architectures test2 (for architecture i386): Mach-O executable i386 test2 (for architecture ppc): Mach-O executable ppc
- 個々にコンパイルしたものを結合する方法
Xcode も基本的にはこの方法を採っている。
$ gcc -arch ppc -o test-ppc test.c -isysroot /Developer/SDKs/MacOSX10.4u.sdk $ gcc -arch i386 -o test-i386 test.c -isysroot /Developer/SDKs/MacOSX10.4u.sdk $ lipo -create test-i386 test-ppc -output test $ file test test: Mach-O fat file with 2 architectures test (for architecture i386): Mach-O executable i386 test (for architecture ppc): Mach-O executable ppc
- -M オプションが付いていたりして複数の arch を同時指定出来ない場合
- i386 に Intel の icc を利用したい場合
- libtiff の様に ppc (big endian), i386 (little endian) で tiffconf.h の内容が変わるものの場合
汚いですが aspell での build script を例として以下に示します。--tkoba
#!/bin/sh U_RELEASE=`uname -r` \rm -rf PPC INTEL tar zxf aspell-0.60.3.tar.gz mv aspell-0.60.3 PPC tar zxf aspell-0.60.3.tar.gz mv aspell-0.60.3 INTEL pushd PPC CFLAGS="$RPM_OPT_FLAGS -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk" \ CXXFLAGS="$CFLAGS" \ ./configure --host=powerpc-apple-darwin${U_RELEASE} --disable-dependency-tracking perl -pi -e 's@-dynamiclib@-dynamiclib -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk@g' libtool perl -pi -e 's@-bundle@-bundle -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk@g' libtool make popd pushd INTEL CFLAGS="$RPM_OPT_FLAGS -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk" \ CXXFLAGS="$CFLAGS" \ ./configure --host=i686-apple-darwin${U_RELEASE} --disable-dependency-tracking perl -pi -e 's@-dynamiclib@-dynamiclib -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk@g' libtool perl -pi -e 's@-bundle@-bundle -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk@g' libtool make popd ## Make Universal Binaries filelist=$(find ./PPC -type f |grep -v \\.o$ | xargs file | sed -e 's,^\./PPC/,,g' | \ grep -E \(Mach-O\)\|\(ar\ archive\) |sed -e 's,:.*,,g' -e '/\for\ architecture/d') for i in $filelist do /usr/bin/lipo -create PPC/$i INTEL/$i -output `basename $i` cp -f `basename $i` PPC/$i done pushd PPC make install prefix=/else/where popd
- Intel Mac 上でビルドする場合
- ライブラリ類が UniversalBinary になっているので -isysroot..... の指定は要らない。
- i386 binaries 作成の際は CFLAGS="-O2 -march=i686 -mtune=pentium-m" を OSXWS では用いている。
注意点[編集]
全般[編集]
- md5 等の check sum を内部で扱う場合
endian の問題が起きるので configure に --host=i686-apple-darwin8.x.0 を与えたものと --host=powerpc-apple-darwin8.x.0 を与えたものを個別に build した後に lipo しなければならない。 例えば、OSXWS では apt を -arch i386 -arch ppc の一気指定で構築した場合、一見成功した様に見えたが MD5SUM の検証に失敗してしまうので、個別に build する必要があった。
- search path には気をつける事
/usr/local 以下に libraries を置いている場合は configure が吐き出す log には要注意
- 単一アーキテクチャと比べて UniversalBinary のファイルサイズは当然 Fat になる。
xgraph では以下に上げる結果になった。
$ du -sh PPC/xgraph 124K PPC/xgraph $ du -sh INTEL/xgraph 128K INTEL/xgraph $ du -sh xgraph 256K xgraph
- -arch i386 -arch ppc の ppc 側にだけ CFLAGS オプションを追加することは可能でしょうか?
- 環境変数 PER_ARCH_CFLAGS_ppc, PER_ARCH_CFLAGS_i386 を使うと良いようですが、少なくとも emacs ではオプションが作用していないように見えます。
- http://developer.apple.com/jp/documentation/MacOSX/Conceptual/universal_binary/universal_binary_compiling/chapter_2_section_7.html
ライブラリの作成[編集]
xgraph や nkf 等の独立したソフトの Fat 化はそれ程難しくはないが gettext 等のライブラリ類はかなり勝手が違う。ここにはライブラリ作成時に留意すべき点を記す。
- glibtool
shared library である libhoge.dylib にしても static な libhoge.a にしても、 作成時には libtool (MacOS X では glibtool) のお世話になる。 これが結構曲者で、 CFLAGS の中の -isysroot /Developer/SDKs/MacOSX10.4u.sdk がそのままでは渡らない事が殆どである。 ./configure を走らせた後に例えば以下の様な ad hoc な対処をしている。
## fix libtool for cross compile for i in `find . -name "libtool"` do perl -pi -e 's@-dynamiclib@-dynamiclib -isysroot /Developer/SDKs/MacOSX10.4u.sdk@g' \ $i done
- FLAGS
Makefile に記述するよりも configure 時に渡した方がスマート。 OSXWS の rpm spec file には以下の記述が標準になりつつある。
CFLAGS="$RPM_OPT_FLAGS -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk" \ CXXFLAGS="$CFLAGS" \ %configure --disable-dependency-tracking
- LDFLAGS
LDFLAGS="-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" は既にインストール済のパッケージ (/usr/local/lib) とのリンクに影響するので configure には渡さない。必要な場合には libtool 側で対処する。 configure 時に上記の CFLAGS, LDFLAGS を設定すると、コンパイル時のデフォル トファイル名を決めるために gcc $CPPFLAGS $CFLAGS $LDFLAGS test.c を実行 しエラーになるので LDFLAGS は設定できなそうです。
- その他
autotools (automake, autoconf) のバージョンと glibtool との取り持ち等これまでにもいろいろと問題はあったがそれに関しては http://www.bach-phys.ritsumei.ac.jp/OSXWS/node29.html に若干まとめてある。
- libgdbm
参考までに libgdbm の作成過程を載せておきます。他に流用するときはパッケージ で利用している autoconf が古すぎるとうまく動かない可能性があるので注意して ください。-- saiki
$ cd libgdbm-1.8.3 $ aclocal $ autoconf -f $ CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386" ./configure $ archargs="-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386" make $ file .libs/libgdbm.3 .libs/libgdbm.3: Mach-O fat file with 2 architectures .libs/libgdbm.3 (for architecture ppc): Mach-O dynamically linked shared library ppc .libs/libgdbm.3 (for architecture i386): Mach-O dynamically linked shared library i386 $ su root # make install
メモ[編集]
- libwx_macud-2.5.3.dylib (Security Update 2006-007)
OSXWS で gnuplot の更新作業中に以下の不具合に遭遇
- PPC Mac 上で fat としてビルドすると Intel 上でも問題なく動く。
- Intel Mac 上で fat としてビルドすると ppc 上では以下のエラーが出て動かない。
dyld: Symbol not found: __ZTI10wxMemoryDC Referenced from: /usr/local/bin/gnuplot Expected in: /usr/lib/libwx_macud-2.5.3.dylib Trace/BPT trap
- 元々 Intel Mac のバイナリー類は fat になっている。
<Intel> $ file /usr/lib/libwx_macud-2.5.3.0.0.dylib /usr/lib/libwx_macud-2.5.3.0.0.dylib: Mach-O universal binary with 2 architectures /usr/lib/libwx_macud-2.5.3.0.0.dylib (for architecture i386): Mach-O dynamically linked shared library i386 /usr/lib/libwx_macud-2.5.3.0.0.dylib (for architecture ppc): Mach-O dynamically linked shared library ppc <PPC> $ file /usr/lib/libwx_macud-2.5.3.0.0.dylib /usr/lib/libwx_macud-2.5.3.0.0.dylib: Mach-O dynamically linked shared library ppc
- 今回は Apple が libwx_macud.dylib の作成に不整合を持ち込んだようである。
参考リンク[編集]
- http://developer.apple.com/jp/transition/index.html
- http://developer.apple.com/jp/technotes/tn2005/tn2137.html
- http://developer.apple.com/jp/documentation/MacOSX/Conceptual/universal_binary/index.html
- http://developer.apple.com/jp/documentation/DeveloperTools/Conceptual/cross_development/
- http://pcweb.mycom.co.jp/articles/2005/06/20/nextmac/