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 を実行しても相対的にリンクできるので無事動くようになります。


これまた感動した。何かよく分からんがこれは凄い。