kiyoka.2013_01_28 RSSPLAIN

Related pages: !kiyoka.blog.list !kiyoka.blog.2013_01
555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555545
5

[Xcode][MacRuby] Lion上のXcode 4.5.2でSnow Leopard用のMacRubyアプリケーションをデプロイする方法

5

Xcode 4.5.2 for Lion と MacRuby 0.13 (GitHubの最新master) を使っている。

5

10.6(Snow Leopard)のアプリケーションをdeployしたいが、なかなか成功しない。

5

ビルドに使っているマシンは 10.7 なのだが、そのマシンで 10.6 のアプリをデプロイできるかという問題だ。

5

 

5

いろいろ試してきたが、MacRubyの内部を知らないと解決しないとわかってきたので、ちゃんと腰を据えて調べることにした。

5

 

5

MacOS SDK 10.6を取ってくる

5

Xcode 4.5.2 には SDK 10.7と10.8しか付属していないので、Xcodeから取り出してコピーした。

5

古いXcodeは Apple Developer Centerから xcode_4.3.3_for_lion.dmg をダウンロードした。

5
 手順は以下を参考にした。
5
 cocoa - How to build for Mac OS X 10.6 SDK in Xcode versions that don't include it - Stack OverflowEXT
5

 

5

 

5

Snow Leopard環境にデプロイ失敗

5

Lion上でビルドしたMacRubyとXcodeを使って、アプリケーションをデプロイしたが以下のエラーが出る。

5

 

5
 crash report of PasteHub.app 0.2.0 on Mac OS X 10.6.8EXT
5
 Symbol not found: __dispatch_queue_attr_concurrent
5

このシンボルは libmacruby.dylib が参照しているらしく、動的リンク時に見つからないと言われている。MacRubyのビルド方法以外悪いのだろう。

5

MacRubyがSnow Leopardには無いAPIを使っているのだろうと思われる。

5

 

5

 

5

MacRubyのソースを読む

5

このエラーメッセージから、MacRubyのソースコードを読むことにした。

5

結果、MAC_OS_X_VERSION_MAX_ALLOWEDという関係ありそうなマクロを見つけた。

5

試しに検索してみると…

5

 

5
grep -nH -r MAC_OS_X_VERSION_MAX_ALLOWED *
5
bignum.c:995:#if defined(__LP64__) && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
5
dispatcher.cpp:690://#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
5
gc.c:141://#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gc.c:1024:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gc.c:1050:#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
5
gcd.c:107:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gcd.c:252:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gcd.c:268:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gcd.c:519:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gcd.c:552:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gcd.c:1295:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gcd.c:1372:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
gcd.c:1387:#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
include/ruby/defines.h:80:#if defined(__LP64__) && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
5

 

5

こんなにある。

5

さて、今どちらの条件でビルドされているのか調べてみた。

5

 

5

[gc.c] に #errorを入れて rake してみる。

5
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
5
#error "10.7"
5
    __auto_zone = objc_collectableZone();
5
#else
5
#error "10.6"
5
    __auto_zone = auto_zone();
5
#endif
5

 

5

ビルド。

5

 

5
bash-4.2$ env CC=/usr/bin/gcc CXX=/usr/bin/g++ rake
5
plblockimp/gentramp.sh plblockimp/x86_64/blockimp_x86_64.tramp x86_64 plblockimp/
5
plblockimp/gentramp.sh plblockimp/x86_64/blockimp_x86_64_stret.tramp x86_64 plblockimp/
5
/usr/bin/gcc -std=c99 -I. -I./include -pipe -fno-common -fexceptions -fblocks -fwrapv -g -O3 -Wall -Wno-deprecated-declarations -Werror -arch x86_64  -I./icu-1060 -I./plblockimp -c gc.c -o .objs/gc.o
5
gc.c:1025:2: error: #error "10.7"
5
rake aborted!
5
Command failed with status (1): [/usr/bin/gcc -std=c99 -I. -I./include -pip...]
5
Tasks: TOP => default => all => macruby => macruby:build => macruby:dylib => rbconfig => miniruby
5
(See full trace by running task with --trace)
5

 

5

なるほど、10.7のほうを通っている。

5

 

5

10.6側のコードが条件コンパイルされれば、__dispatch_queue_attr_concurrent を参照しなくなるのではないかという推測。

5

それには、MacOS 10.6 SDKが選択すれば良いはず。

5

XcodeからSDKをUIでBase SDKを選択するかのごとく、コマンドラインでgccを起動する場合でも動的にSDKを切り替えられるのではないかと思って調べてみるとあった。

5

どうやら、-isysroot -syslibroot を使えば良いらしい。

5
 例)
5
  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk
5

 

5

しかし、無理やり isysrootでMacOSX10.6にしても、コンパイルエラーになる。

5

 

5
bash-4.2$ env CC=/usr/bin/gcc CXX=/usr/bin/g++ rake
5
plblockimp/gentramp.sh plblockimp/x86_64/blockimp_x86_64.tramp x86_64 plblockimp/
5
plblockimp/gentramp.sh plblockimp/x86_64/blockimp_x86_64_stret.tramp x86_64 plblockimp/
5
/usr/bin/gcc -std=c99 -I. -I./include -pipe -fno-common -fexceptions -fblocks -fwrapv -g -O3 -Wall -Wno-deprecated-declarations -Werror -arch x86_64  -I./icu-1060 -I./plblockimp --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk -c gc.c -o .objs/gc.o
5
cc1: warnings being treated as errors
5
gc.c: In function ‘Init_PreGC’:
5
gc.c:1025: warning: implicit declaration of function ‘objc_collectableZone’
5
gc.c:1025: warning: assignment makes pointer from integer without a cast
5
rake aborted!
5
Command failed with status (1): [/usr/bin/gcc -std=c99 -I. -I./include -pip...]
5
5
Tasks: TOP => default => all => macruby => macruby:build => macruby:dylib => rbconfig => miniruby
5
(See full trace by running task with --trace)
5

 

5

原因は、Lion環境用のXcodeをインストールすると、/usr/include 以下のヘッダには

5
#define MAC_OS_X_VERSION_MAX_ALLOWED 1070
5

と定義されているので、isysrootを指定してもMacRubyの ビルド時に 10.7 API を使う条件でコンパイルされてしまう。

5

従って、isysrootは、SDK の切り替えにしか影響しないので、isysrootでは解決にならない。

5

MacRubyをSnow Leopard環境でビルドすれば良いのだろうが、このためだけに自分のOSをダウングレードするのはイヤだ。

5

 

5

ソースを改変

5

 

5

そこで、無理やりマクロを API として 10.6 までしか使わないように抑え込む。

5

そのローカルパッチを当てたものが、こちら。

5

 

5
 It can be built macruby for 10.6 on Lion(10.7) enviroment with 10.6 SDK. ·  c7963b4 · kiyoka/MacRuby · GitHubEXT
5

 

5

 

5

 

5

Xcodeでのデプロイ設定も変更が必要

5

 

5

問題はまだある。

5

Xcode 4.5.2 for Lion上で Base SDKを10.6 に設定してアプリケーションをデプロイしようすると次のリンクエラーが出る。

5

 

5
 Undefined symbols for architecture x86_64:
5
  "_objc_retain", referenced from:
5
     ___ARCLite__load in libarclite_macosx.a(arclite.o)
5
     (maybe you meant: _objc_retainedObject)
5
 ld: symbol(s) not found for architecture x86_64
5
 clang: error: linker command failed with exit code 1 (use -v to see invocation)
5

 

5

XcodeのデフォルトではLion用のObjective-C Runtimeをリンクしようするが、10.6 SDKには無いらしくエラーとなる。

5

SDK 10.6を使う場合は、ARCのライブラリはいらないはずなので、Implicitly link Objective-C Rumtie YES => NO に変更してデプロイする。

5

 

5
 objective c - _objc_retain&quot;, referenced from:__ARCLite__load error in Xcode 4.4 - Stack OverflowEXT
5

 

5

これでMacRubyのアプリケーションはデプロイ可能となる。

5

 

4

COMMENTSharon

This infomratoin is off the hizool!

5

...comment disabled...