Mono embedder managed tool-chain 09 Jan 2009


sncf Miguel blogged a list of iPhone applications that were made using Unity3D, and scripted with Mono. I'm delighted to have cute applications using Mono to show, and one involves raptors! One of the concern for Unity3D is to reduce the size of the download as much as possible. And Mono certainly weight a little bit in the download. We have a page on our wiki which describes how to reduce the size of the runtime, but am writing today about what Unity3D uses to reduce the size of the different managed parts, be it the core libraries, or the managed part of the game itself. They are using two different tools to reduce the size of the assemblies. So first of all, once the application is compiled, the first tool they use is the Mono Linker. I already had the occasion to write about the linker, as it is a tool that I started writing during the second Google Summer of Code I spent as a student, and that I've worked on when I joined Novell. The linker is today a mature piece of code, that is exercised during every single Mono build, as it is used to produce the Moonlight 2.0 version of our class library. So they are using the linker, and this makes sure that everything that is not needed by the game or the engine is removed from the assemblies. When the linking stage is achieved, they pre-compile the assemblies to native code using our AOT (Ahead of Time) compiler. This is necessary, as the iPhone prevents any JIT to run. After AOT, you end up with a native binary, and the original managed binary, which still contains the intermediate code. If the assembly has been completely AOTed, this intermediate code is no longer necessary. Here comes the second tool they're using. This is a tool which is pretty new, and that I wrote for this specific usage. It's called `mono-cil-strip`, and is now built along the traditional tools that we ship, such as ilasm or the linker. It uses a special mode of Cecil I hacked on, which preserves the original metadata structure of the assembly, but empties every single method body. It's necessary to keep the native binary in sync with the managed binary, while still removing parts of it. If you're compiling your assemblies ahead of time, and looking for some bytes to save, here's a neat way to do so. Sadly I don't have numbers handy, so I'll encourage you to give it a try, but here we are, every single iPhone application produced using Unity3D went through Cecil (twice!). And that's pretty cool :)