Forcing full AOT (ahead of time) compilation on Windows/Mac?

As many of us have seen, many of the useful features of C#/.NET are lost because of problems caused by platforms which require full AOT compilation (iOS, I’m looking at you). This prevents us from using really helpful LINQ extension methods like IEnumerable.OrderBy among other things.

The problem is, it’s hard to know which calls are going to cause problems until you actually test on device, and this takes a lot of time. Is there a way to force full AOT compilation on PC/Mac in order to reproduce these issues more quickly? (Eventually I’d like to work toward a solution which scans our assemblies for problematic code and warns us immediately.)

Full AOT compilation is not supported by Mono on all platforms. Last time I investigated (years ago…) it was supported on amd64, but not x86. So you can perform these tests on 64-bit Intel-based platforms, but not 32-bit ones. Also, the errors you get on amd64 are not exactly the same as the ones on iOS - I have seen code that works on one but not the other, in both directions.

I also don’t remember full details of the method, but hopefully this will give you a start…

You use the Mono compiler that comes with Unity - or download a newer version if you like - to process a compiled assembly (DLL or EXE) and precompile as much as possible to native code:

mono --aot=full mytestapp.exe

This generates a compiled version of the assembly that lives alongside it. Mono requires both the original assembly and the compiled version to be present at runtime.

Then you need to use mono again when you run your test app, to force the runtime to throw exceptions if JIT is ever required:

mono --full-aot mytestapp.exe

Note that the command line option here is different from the previous command.

One bit I don’t fully remember is treatment of system libraries - I don’t recall exactly but I think I had to precompile those as well, and maybe provide them alongside my own assembly.

There is more information here:

Last time I looked at this page was three years ago, and not a lot has changed, so it could be out-of-date documentation (e.g. more platforms may be supported now).