ものがたり(旧)

atsushieno.hatenablog.com に続く

メモ: MonoTouchとMoonlightのバージョン競合

ちょっと困った問題に遭遇したのでメモ。

最初に要点を簡単にまとめておくと、MonoTouch-enabled MonoDevelopには、他の環境に無いややこしい問題がひとつある。MoonlightのアセンブリとMonoTouchのアセンブリのバージョン番号が同一(2.0.5.0)なので、アセンブリの「参照の編集」が正しく行われないというものだ。これを解決するには、単純にMonoDevelopのアドインマネージャでiPhone開発アドインを無効にして、MonoDevelopを再起動してから、Moonlightプロジェクトを開くと良い。

これは、もともとMonoTouchのプロファイルがMoonlightのものをベースにしていて*1cecil linkerを使ったアセンブリの調整と不要なコードの削除もMoonlightのアセンブリと同様に行われている、ということにある。

MonoTouchチームはその後ベータ版を公開し、いくつかのフィードバックを経てそのアセンブリ構成は少しずつ変わっていった。たとえば現在のMonoTouchにはCoreCLRではなくCLRレベルでチューニングされたSystem.Xml.dllが含まれている。MonoのXmlSerializerはインタープリタ型と動的コード生成型のふたつが含まれていて*2、前者は問題なく使用できるというわけだ。また、XSLT実装でも、msxsl:scriptなどは使えないはずだが、XslCompiledTransformなども実装していないので*3この方面でも動的コード生成が無く、問題なくiPhone開発に使用できる。

というわけで、今やこれらのバージョン番号が同一になっていることは、むしろ混乱を招くのでよろしくない。その上、これはMonoDevelop上で参照を編集する際にも問題になる。というのは、同一のAssemblyNameをもつアセンブリなので、区別ができなくなってしまうのである。結果的に、Moonlightのプロジェクトを開発しているときも、常にMonoTouchのアセンブリを参照してきてしまう。すると、バージョン番号は同一だが内容の異なるアセンブリが、mxapでxapにパッケージされデプロイされてしまう、ということになり、特に実行環境がSilverlightであるMac上では、分かりやすくエラーになる(何も実行されない)。

そんなわけで、MonoTouchのアセンブリ名は変更すべきだというのが、僕やMD開発者の弁なのだけど、どうも今のスケジュール感でMonoTouchをそのように修正するのは難しいらしく(この辺はどういう議論があったのか僕は知らない)、このままの仕様で通ってしまいそうな気配がある。とはいえ、今後ずっとそのような問題を抱えたまま続けていくとも考えにくいので、次のバージョンで変わるかもしれない。まだベータ版だし、先行きはまだ分からない。

ちなみに、そのままでは困るので、古いバージョンを別途インストールして動かしてみたりとか、試行錯誤してみたけど、とりあえずMonoTouchのアドインを無効にして再起動するという方法以外のworkaroundは見つからなかった。まあ、当座はこれでしのげるのではないかと思う。もともとMD on Macは(所詮Macアプリなので)複数プロセスで起動できないわけだし…

*1:CoreCLRベースの実装を提供するというのが、現実的な案だということは理解してもらえると思う

*2:.NETは後者だけ。もっともsgenを使用すればその一部または全部が不要になるはず

*3:.NETのcompiled XSLT実装は.NETのnonpublic classのnonpublic memberに依存しているのでサポートしようがない