2009-09-04

Leopardとx86_64 binary

Snow Leopardで普通に作ったx86_64 binaryは、Leopardでは動作しない。

printfしかしないようなbinaryの場合、

Leopard用は

/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 103.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)


Snow Leopard用は

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)


と依存しているdylibが違いますし、あとdyldあたりのinterfaceが変わっているような雰囲気です。


Snow LeopardでLeopardでも動くbinaryを作るには、

$ MACOSX_DEPLOYMENT_TARGET=10.5 gcc a.c


とか、

$ MACOSX_DEPLOYMENT_TARGET=10.4 gcc -arch x86_64 -arch i386 -arch ppc a.c


とか。


そもそもUNIXな範囲でx86_64なbinaryがSnow Leopard上で常に有利なの? という話もありますが、それはさておき、

Snow Leopard: 10.6 x86_64
Tiger/Leopard: 10.4 i386/ppc


なuniversal binaryを作ってみたい。


Xcodeだと、MACOSX_DEPLOYMENT_TARGET_x86_64てな感じの設定があるので、

$ MACOSX_DEPLOYMENT_TARGET=10.5 MACOSX_DEPLOYMENT_TARGET_x86_64=10.6 gcc -o a.out -arch i386 -arch x86_64 a.c


もいけるのかと思いきや、gccには通用しません。


ということで、lipoを使います。とりあえずi386 10.5とx86_64 10.6のuniversal binaryを作ってみます。

$ MACOSX_DEPLOYMENT_TARGET=10.5 gcc -o a.out.i386.10.5 -arch i386 a.c

$ MACOSX_DEPLOYMENT_TARGET=10.6 gcc -o a.out.x86_64.10.6 -arch x86_64 a.c

$ lipo -create a.out.i386.10.5 a.out.x86_64.10.6 -output a.out


できました。

$ otool -arch all -L a.out
a.out (architecture i386):
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 103.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)
a.out (architecture x86_64):
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)


それっぽくlinkされています。


てことで喜び勇んでLeopardで動かしてみると、

dyld: unknown required load command 0x80000022


...

ということで、Leopardではx86_64を動かせちゃうので10.6なx86_64を動かしてしまう訳ですね。


ついでにだめもとで試してみると

$ lipo -create a.out.x86_64.10.5 a.out.x86_64.10.6 -output a.out.2
lipo: a.out.x86_64.10.5 and a.out.x86_64.10.6 have the same architectures (x86_64) and can't be in the same fat output file


やはりだめですね。


よって、i386はLeopardで、x86_64はSnow Leopardで、てなことはできなさそうです。