C sharp or B flat? Experiments in self-contained native executables in .NET
One of the best parts of the .NET ecosystem is the excitement around experimentation. Someone is always taking .NET to the next level, trying new things, pushing the envelope.
Michal Strehovsky has an interesting experiment on his GitHub called "bflat." This is not a product, it's a playground.
bflat is a concoction of Roslyn - the "official" C# compiler that produces .NET executables - and NativeAOT (née CoreRT) - the experimental ahead of time compiler for .NET based on CoreCLR's crossgen2. Thanks to this, you get access to the latest C# features using the high performance CoreCLR GC and native code generator (RyuJIT).
bflat merges the two components together into a single ahead of time crosscompiler and runtime for C#.
I find this characterization funny:
bflat is to dotnet as VS Code is to VS.
Michal is basically stripping .NET down to the bare minimum and combining the official compiler and and the experimental AOT (Ahead of Time) compiler to make single small EXEs that are totally self-contained.
Michal says you can get involved if you like!
If you think bflat is useful, you can leave me a tip in my tip jar and include your GitHub user name in a note so that I can give you access to a private repo when I'm ready.
Hello World today is about 2 megs. He says it's because:
By default, bflat produces executables that are between 2 MB and 3 MB in size, even for the simplest apps. There are multiple reasons for this:
- bflat includes stack trace data about all compiled methods so that it can print pretty exception stack traces
- even the simplest apps might end up calling into reflection (to e.g. get the name of the
OutOfMemoryExceptionclass), globalization, etc.
- method bodies are aligned at 16-byte boundaries to optimize CPU cache line utilization
- (Doesn't apply to Windows) DWARF debug information is included in the executable
So when I ran
bflat build, here was my output.
But when I run
bflat.exe build --no-reflection --no-stacktrace-data --no-globalization --no-exception-messages .\hello.cs
I end up with a 750kb file!
Sure, it's not C code because it'll never be C code. You get access to a LOT MORE with C#.
This could be a useful system for creating tiny apps in C# for Linux or Windows command line administration. It also showcases how the open pieces of .NET can be plugged together differently to achieve interesting results.
I'm sure there's lot of AOT limitations around Reflection, Attributes, and more, but this is still a very cool experiment, go check it out at https://github.com/MichalStrehovsky/bflat!
Sponsor: Pluralsight helps teams build better tech skills through expert-led, hands-on practice and clear development paths. For a limited time, get 50% off your first month and start building stronger skills.