[Mono-list] Minimal requrements

Paolo Molaro lupus@ximian.com
Wed, 1 Dec 2004 12:09:02 +0100

On 12/01/04 George Birbilis wrote:
> > With mono you can create reduced versions of the assemblies so that
> > they match your requirements. We're investigating a tool to do
> > this automatically, in the meantime you can experiment by
> > tweaking the build files to build only the classes you need.
> but since .NET supports dynamic class loading, removing stuff can be a
> potential source of runtime errors (class not found)
> the problem is you can't run an app through a tool to tell you which classes
> it uses, since it might be loading some by name and using them
> programmatically via interfaces those "plugin" classes implement

Sure, that's why the tool also takes a list of classes and methods
you want included anyway, even if there are no direct references to
them. We need this, because, for example, some classes are used
by the runtime and they are not referenced anywhere by IL code.
This tool is not used to create a version of the mono libraries that can 
run any app: the default build does that. The tool is useful in two
*) people using bundles to embed the mono runtime: they just want one or 
two apps and don't need all the functionality of corlib/System etc.
so they can build a reduced version and ship a much smaller bundle.
*) people using mono in embedded systems who want to run a well
defined set of apps: they can download to the device just the code
needed to run those apps.
There is also an additional potential use: instead of putting lots
of ugly conditional compilation checks in the sources to get
versions of the libraries compatible with the 1.0, 1,1, 2.0, CF etc
we could have a description of the API in a separate file and feed that
to the tool, so we'd always compile the full corlib and the tool is used
to extract the subset needed. Of course we still need some conditional
compilation #ifs, but this way they could be vastly reduced. This
still needs to be investigated.
In the plugin case, you'd list the plugins together with the app that
requires them: this way all the code needed by the plugins is
considered, too.

I wrote a quick prototype a few days ago: it operates at the type level
(because that way I just needed to feed the build system a different
list of files to compile, without any change to the tools) so it's very coarse,
but it reduced the corlib size by 20%.
The real version should work like this:
*) start from the Main() method of all the apps needed
*) parse the IL code of the methods
*) queue each referenced method so it's parsed later
*) queue each type to be considered later
*) record which types have the constructor invoked
*) record the referenced fields
*) record attributes etc
*) record virtual and interface method calls
*) for each type that can be constructed, queue the methods in the type
that could be invoked through a virtual or interface call
*) queue the .cctor for the type if needed
*) repeat until the worklist is empty

The tool should take a list of types or methods that should be considered
'roots' beside the Main entry points: this process is a sort of garbage 
collection for IL assemblies. There are a few details missing, like handling 
properties, but that is just a SMOP.
Once we have collected all the info, we get a list of:
[assembly]type index
[assembly]method index
[assembly]field index
We can write it to a file and it's an easy change to get monodis to skip
disassembling the listed types, methods and fields.
The resulting IL file is compiled using ilasm and you get back an
assembly which contains just what is needed to run the list of apps
Of course it's important that monodis/ilasm can roundtrip the assemblies
correctly: people who want to help with this project could try
roundtripping mcs, corlib, System etc and file and fix the bugs that
may be found in the process.
Miguel, as you see, there is also no perl script involved (though of course
I used it for my prototype;-).

> as for a CF-compatible version of Mono, it would be nice to have, since one
> would be able to build IL code that is working on both Linux-based and
> PocketPC-based devices without changes

Sure: since you look familiar with the CF version, you're likely the best
person to contribute the needed support. There are three issues:
*) excluding from the compilation the classes/methods that are not present
in the CF: you can just use a NET_COMPACTF #define
*) adding the code for types and methods that our assemblies don't provide
*) make the pubtokens and versions match (we have already some code to
deal with this issue, it should be easy, Sebastien has the details).



lupus@debian.org                                     debian/rules
lupus@ximian.com                             Monkeys do it better