##Problem
コンソールプログラムをXamarin Studioで作ってコンパイルすると出来上がるのは.exeです。Windowsならそのまま,OSXやLinuxなら mono xxx.exe
として実行することとなります。
Monoインストール環境ならシェルスクリプトでラップしてあげればいいですが,業務アプリとかはなかなかそういうわけにはいかなかったり。
検証はOSX10.8, 10.9で行っています。
##Solution
まずは mkbundle
です。こんな感じで実行します。DLLを使ったりするときは別にオプションが必要ですがそこはGoogle先生に…
mkbundle -o [output] [source.exe] --deps
事前にお膳立てが必要で,以下のような環境変数が必要です(Mac)。
export PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig
export AS="as -arch i386"
export CC="clang -arch i386 -mmacosx-version-min=10.6"
exeを投入してmkbundleを実行すると,clangやらなんやら実行されてUnix Executableが出来上がります。これを otool -L
します。出力はプログラムによりますが以下のような感じです。
% otool -L test
test:
/Library/Frameworks/Mono.framework/Versions/3.2.5/lib/libmonoboehm-2.0.1.dylib (compatibility version 2.0.0, current version 2.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
本当は mkbundle --static
があるんですが,どうにもうまく動かない。挙げ句mkbundle.csを修正して再コンパイルしろと言われる始末。それはちょっと手間だし,静的リンクさせてしまうとLGPLが強制されて困る場面も多々ありそう。
そこで実行ファイルと同じフォルダからdylibを読み込むように設定します。install-name-tool
です。こうです。
install_name_tool -change /Library/Frameworks/Mono.framework/Versions/3.2.5/lib/libmonoboehm-2.0.1.dylib @executable_path/libmonoboehm-2.0.1.dylib [source]
これでもう一度 otool -L
すると参照先が変わっているかと思います。実行ファイルと同じフォルダにdylibをコピーして配布すれば動く,はずです。
##A bit more...
それなりに簡単に単体実行ファイルを作り出すことができます。Windowsでも同じように.NET Frameworkのない環境で動作するファイルを作れますが,そんな環境はあるのでしょうか。考えなくともよさそうです。
Xamarin Studioでビルド時にこの動作を行うように設定しておくとそれなりに便利です。こんな感じです。
install_name_tool -change /Library/Frameworks/Mono.framework/Versions/3.2.5/lib/libmonoboehm-2.0.1.dylib
@executable_path/libmonoboehm-2.0.1.dylib ${ProjectName}```
##Conclusion
mkbundle, otools, install_name_tool でなんとかなります。