ものがたり(旧)

atsushieno.hatenablog.com に続く

how to build reduced CLR

JBに、おまいの秘密が暴露されてるぞと言って見せたら、「これ確かにすげーおれに似てるね」などと予想外の返事が返ってきた。ううむ、言われてみると確かに似てる…頭の辺とか特に。

そんなわけで、最近はJBとmoonlight用に軽量化されたCLRをどうやってビルドするかという話をしていた。基本的にはmscorlib/System/System.Xml.Coreをどうビルドするかという話である。

moonlight specialでもちょっとだけ話したことだけど、silverlightのコアライブラリをビルドする基本的な手順としては、v2.1(silverlightのライブラリのバージョン)にのみ含まれるメンバーを#if NET_2_1 ... #endif で追加して全体をビルドした後、SL版に存在しないメンバー(ここでは2.1のアセンブリからpublic APIのリストを抜き出したmasterinfosが使われることになる)をinternalにして隠し、セキュリティ関係の属性を書き換えるといった作業が、JBのcecilベースのツールで行われることになる。#if NET_2_1をメンバーの削除にまで使い出すと鬱陶しくてたまらないので、基本的にはそういうことはしない。

と言っても、これはあくまで基本的な方針で、実際には僕はもうSystem.Xml.Core.dllを#if !NET_2_1でやっつけてしまっていたりする。なにしろSystem.Xml.Core.dllにはXmlReaderとXmlWriterしか含まれていないので、上記の手順を踏むとかえって面倒になる。

…と書くと何か簡単に出来そうに見えるけど(ホントか?)、実はそんなに簡単ではない。ひとつには、循環参照が障壁になる。例によって、.NET 2.0においては、System.dllをビルドするには、System.Xml.dllとSystem.Configuration.dllとSystem.Security.dllが必要になって、System.Xml.dllをビルドするには、System.dllとSystem.Configuration.dllが必要になる(循環している)。たとえば、System.dllに含まれるConfigXmlDocumentは、XmlDocumentが無ければビルドできないので、System.Xml.dllが存在していない最初の時点ではビルドされない。

で、これが、System.Xml.Coreになると、そもそも完全なビルドでもXmlDocumentは含まれていないので、いくら循環してもこれを解決することはできない。だから、System.dllのビルドの時点では、System.Xml.Core.dllではなくSystem.Xml.dllを参照することになると思う*1。そしたらinjectがめんどくさそうだけど(System.Xml.dllへの参照…Typeを含む…を全部System.Xml.Core.dllへの参照に置き換えないといけないので)。

…などと考えると、結局System.dllでも別のdll.sourcesを作って削った方がやりやすいんじゃないかという気もしなくもないのだけど、System.Xml.Coreでも#if !NET_2_1は25回くらい使ってしまったので、System.dllはもっと面倒かなという気もしている。どんだけ面倒になるかこっそり実験してみようかしらん。

あと、これに関連して、agclr.dllだのSystem.Silverlight.dllだのといったsilverlightアセンブリをどうビルドするかという話もしていた。gmcsでビルドされるのは、デフォルトでは2.0のmscorlibを参照するアセンブリになり、そのままだとめんどくさいので、slmcsみたいなのを作って、それを使ってビルドするということになりそうだ。これはgmcsのスクリプトで参照しているアセンブリディレクトリをnet_2_0からnet_2_1に替えるだけで済むかもしれないけど、gmcs.exeでSLアセンブリに含まれていない型が使われているかもしれないので、その辺はまだ分からない。

…といったごちゃごちゃした事情もあって、実のところこの辺は21日間でやっつけることもなく、その後の21日間でやっつけられる見込みも特になかったりする。Silverlightアプリのporting作業が不要になるのは、もうちょっと先のことになるだろう。

*1:今の方針でビルドする限り