D11_ver0_11 - app作成
D11_ver0_11 を作りました。
ソース
http://www.wink.ac/~h-muro/d/trunk/d11_ver0_11.zip
主な変更点
最近アップしすぎなんですが、今回のはする価値アリっすよお客さん。
やっと app の作り方がおぼろげながら分かってきました。
疑問点は主に 2つでした。
- リソース(絵とか音とか入ってる)のパスの取得方法が分からん
- ダイナミックリンクライブラリ (*.dylib) の読み込み方が分からん
やっぱググればなんとかなるね。参考になったのは以下。
http://www.rubygarden.org/ruby?BundleRubyExecutableInMacOSX
http://freespace.ausgamers.com/2005/02/creating-os-x-application-bundles-step.html
リソースのパスの取得方法は、結局 Mac 側の協力がないと駄目でした。当たり前か。
なので当然 Objective-C を使ったわけですが、main() のところを少し分離して、
Xcode を使っている場合は main.cpp を Objective-C++ としてコンパイルすることにしました。
コードはこんな感じ。
// 自分を取得 NSBundle *me = [NSBundle mainBundle]; // リソースパスを取得 NSString *rpath = [me resourcePath]; // 文字列を取得 r = [rpath cString]; if (r != 0) strcpy( path, r ); [me release]; [rpath release];
path は char[] です。
これをやると、path に "実行時のフルパス/d11_stg.app/Contents/Resources" が入ります。
絵とか音とかを Resources の中に入れておけば、app がどこにあっても絶対パスで示せます。
重要なのは、これが美しいっぽい方法なのではないかということです。
次に dylib ですが、何も考えないでコンパイルするとこうなります。
% otool -L d11_stg d11_stg: @executable_path/../Frameworks/SDL.framework/Versions/A/SDL (compatibility version 1.0.0, current version 1.0.0) @executable_path/../Frameworks/SDL_image.framework/Versions/A/SDL_image (compatibility version 1.0.0, current version 1.0.0) @executable_path/../Frameworks/SDL_mixer.framework/Versions/A/SDL_mixer (compatibility version 1.0.0, current version 1.0.0) /Users/hiro/Devs/sdl/d11/build/libD9.dylib (compatibility version 1.0.0, current version 1.0.0) /Users/hiro/Devs/sdl/d11/build/libMQ.dylib (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 567.0.0) /System/Library/Frameworks/QuickTime.framework/Versions/A/QuickTime (compatibility version 1.0.0, current version 47.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 11.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.0.0)
真ん中へんにある libMQ.dylib と libD9.dylib が絶対パスなので
そこに *dylib がないとリンクできないことになります。
どうしたものかと思っていましたが、install_name_tool というスゲーコマンドを
上記のサイトで知りました。これを以下のように使うと、
% /usr/bin/install_name_tool -change /Users/hiro/Devs/sdl/d11/build/libD9.dylib @executable_path/../Frameworks/libD9.dylib ./d11_stg % /usr/bin/install_name_tool -change /Users/hiro/Devs/sdl/d11/build/libMQ.dylib @executable_path/../Frameworks/libMQ.dylib ./d11_stg
絶対パスを書き換えることができます。
% otool -L d11_stg d11_stg: @executable_path/../Frameworks/SDL.framework/Versions/A/SDL (compatibility version 1.0.0, current version 1.0.0) @executable_path/../Frameworks/SDL_image.framework/Versions/A/SDL_image (compatibility version 1.0.0, current version 1.0.0) @executable_path/../Frameworks/SDL_mixer.framework/Versions/A/SDL_mixer (compatibility version 1.0.0, current version 1.0.0) @executable_path/../Frameworks/libD9.dylib (compatibility version 1.0.0, current version 1.0.0) @executable_path/../Frameworks/libMQ.dylib (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 567.0.0) /System/Library/Frameworks/QuickTime.framework/Versions/A/QuickTime (compatibility version 1.0.0, current version 47.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 11.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.0.0)
これで libMQ.dylib と libD9.dylib を d11_stg.app/Contents/Frameworks/ の中に入れておけば、
どこで app を実行しても相対的にリンクできるので無事動くようになります。
これまた感動した。何かよく分からんがこれは凄い。