UniversalBinary

提供: MacWiki
移動: 案内検索

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


ライブラリの作成[編集]

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 の作成に不整合を持ち込んだようである。

参考リンク[編集]