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...