6 ms·
You can get a sub 20kb executable with C in MSVC and no weird tricks, i.e. just setting a particular combination of compiler/linker flags, like /NODEFAULTIB, /M
by ntstatusquo 24d ago
You can get a sub 20kb executable with C in MSVC and no weird tricks, i.e. just setting a particular combination of compiler/linker flags, like /NODEFAULTIB, /MERGE, /FILEALIGN:512 etc. Small enough that it's basically nothing, downloads in a couple of seconds over 56k dialup, and you get to use normal tooling. This is the compromise that makes the most sense to me, for products you're actually shipping. If you want to try out the nocrt approach, honestly the LLMs do a fine job of writing you some replacements for the parts of the crt that you likely want i.e. memcpy/memcmp/strlen helpers, with x64/arm64 SIMD and all.
Set /HEAP:4096,4096 and /STACK:65536,4096, write yourself a simple 100 line growable arena implementation, use that, avoid the heap entirely. Very quick and easy way to get a real windows program up and running that uses about 500kb of commit at baseline.
You end up with only ntdll.dll, kernelbase.dll, and kernel32.dll loaded. Trying to eliminate any of these becomes pretty painful and you venture into the territory of weird tricks that are expensive to maintain.
Dave's approach is a fun exercise though.
- Dwedit 24d agoThen you load User32.dll, and you get 2MB of commit and 1MB of private bytes. Throw in a Message Box, and it's 272KB more private bytes and 388K more commit. Windows 10 makes it literally impossible to write something that uses low memory and uses an actual window.
- ntstatusquo 23d agoTrue, the project where I used the approach above was a TUI, so windows terminal sort of eats the impact of stuff like user32 and dwrite for you. One trick I know of to make user32 a bit more lightweight is to call ImmDisableIme prior to creating your first window. This disables a lot of the TSF integration, which is notably quite slow. Not sure if it impacts memory footprint but worth a try. It of course does what the name says and disables IME support, so not a viable option if you have users who need IME