SmolSharp – Extremely small standalone C# executables using NativeAOT

breve1 pts0 comments

GitHub - ascpixi/smolsharp: 🐜 Extremely small standalone C# executables using NativeAOT · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

ascpixi

smolsharp

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star<br>244

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>19 Commits<br>19 Commits

src

src

tools

tools

.gitignore

.gitignore

LICENSE

LICENSE

README.md

README.md

shaderpkg.bat

shaderpkg.bat

View all files

Repository files navigation

🐜 SmolSharp

SmolSharp is a repository that demonstrates the ability to use NativeAOT to build extremely small binaries without any kind of external utility or linker. For example, for a simple hello world program, by default, NAOT produces a binary that is 2998272 bytes in size with the following properties:

true<br>true<br>Size<br>true">PublishAot>truePublishAot><br>Optimize>trueOptimize><br>OptimizationPreference>SizeOptimizationPreference><br>PublishTrimmed>truePublishTrimmed>

With the SmolSharp.props file being imported, the compiler produces a binary that is only 2021 bytes in size - a 0.07% of the original file-size.

Project overview

Project Name<br>Binary size<br>Description

HelloWorld<br>2021 B<br>A console program that outputs "Hello World".

Mandelbrot<br>2879 B<br>A windowed program that renders a fractal (the Mandelbrot set).

Ocean<br>7316 B<br>A windowed OpenGL program that renders a ray-marched stylized ocean.

As of pull-request Compile as x86 by Michal Strehovský, the projects may also be compiled in 32-bit mode, which reduces file sizes even further:

Project Name<br>Binary size<br>Description

HelloWorld<br>1711 B<br>A console program that outputs "Hello World".

Mandelbrot<br>2299 B<br>A windowed program that renders a fractal (the Mandelbrot set).

Ocean<br>5832 B<br>A windowed OpenGL program that renders a ray-marched stylized ocean.

You may find this version in the /bit32 branch.

h264.mp4

Screen capture of the Ocean demo

Inner-workings

All of the functionality of SmolSharp is contained in the SmolSharp.props file. The following techniques are employed in order to achieve minimal binary sizes:

Custom standard library - SmolSharp uses the bflat zerolib standard library, serving as the primary size-saving technique. However, this results in the lack of any kind of GC and removes all built-in BCL classes and functionality, requiring the use of raw P/Invokes to interface with Windows' APIs.

Raw P/Invokes - all external [DllImport] declarations are specified in the list in the MSBuild .props file, removing the need for a dynamic loader. To prevent redundant RhpReversePInvoke calls, every [DllImport] is marked with the [SuppressGCTransition] attribute.

ILC configuration - several MSBuild properties instruct the IL compiler (ILC) to optimize and generate code with binary size as its top priority. All Win32 resources (usually embedded in the .rsrc section) are omitted by setting the internal property _Win32ResFile to an empty string, in a target that executes before the LinkNative target (or for .NET 8+, by setting an undocumented property).

Native object file manipulation - the alignment of all sections in the native object file is set to their minimum accepted value using objcopy. Additionally, since no exception handling is used, the SEH exception data directory (the .pdata section) is removed.

Linker flags - several MSVC linker flags are specified, significantly reducing the size of the final binary image:

/align:16 - sets section alignment to 16 bytes, which, based on testing, is the minimum accepted value

/manifestuac:no - forces the linker to never embed any UAC manifest

/opt:ref /opt:icf - enables linker reference optimization

/safeseh:no - allows the linker to skip embedding SEH data

/emittoolversioninfo:no - removes linker/compiler version information (the Rich header). Undocumented.

/emitpogophaseinfo - removes the debug directory from the final output. Undocumented.

/nodefaultlib - excludes CRT libraries from the binary

/fixed - instructs the operating system to load the binary at a static address, disabling relocations and...

smolsharp binary size file linker program

Related Articles