4 ms·
I wrote a program using similar principles: https://github.com/tom-seddon/kbswitch https://github.com/tom-seddon/kbswitch (two versions, one for 32-bit Windows
by to3m 11y ago
I wrote a program using similar principles: https://github.com/tom-seddon/kbswitch https://github.com/tom-seddon/kbswitch (two versions, one for 32-bit Windows XP, one for Windows XP or later with any bitness)
The EXEs are indeed pretty small:
~/github/kbswitch % ls -l `find . -name '*.exe' -or -name '*.dll'`
-rw-r--r-- 1 tom staff 5120 1 Feb 13:50 ./kbswitch/kbswitch.exe
-rw-r--r-- 1 tom staff 11264 1 Feb 13:50 ./kbswitch2/bin/kbswitch2.exe
-rw-r--r-- 1 tom staff 5120 1 Feb 13:50 ./kbswitch2/bin/kbswitch2_dll_x64.dll
-rw-r--r-- 1 tom staff 5120 1 Feb 13:50 ./kbswitch2/bin/kbswitch2_dll_x86.dll
-rw-r--r-- 1 tom staff 6144 1 Feb 13:50 ./kbswitch2/bin/kbswitch2_helper_x64.exe
-rw-r--r-- 1 tom staff 5120 1 Feb 13:50 ./kbswitch2/bin/kbswitch2_helper_x86.exe
VC++ makes freestanding programs no easier than gcc. (A good reminder that a C implementation consists of all the libraries that come with it, and not just a compiler that generates code.) Issues I recall having when putting this together (which was a few years ago now so I may have forgotten something):
- As with gcc, you need to fiddle with the linker settings to stop it including the stack check stuff
- Floating point is a bit hit or miss and using it can cause VC++ to generate calls to its helper library (I vaguely recall also getting similar stuff when using 64-bit ints)
- VC++ will generate calls to memset when default-initializing structs
- VC++ will spot many types of implementation of memset, remove them, and replace calls to them with calls to memset (particularly tiresome when trying to fix the last problem)
- the Windows headers include a number of handy-looking functions that seem just the ticket for working without the CRT, but a lot of them, once I followed through all the #ifdefs, ended up just being #defines for the corresponding CRT function
So I haven't bothered doing this for any programs since. I've heard of some people working typically without the CRT, and they seem pretty happy, but I didn't think it was worth the effort just to provide a tiny EXE with no non-system dependencies.
Regarding the size, I don't think it's a huge benefit these days - for small programs, where this stuff makes the EXE noticeable smaller, you're just not saving much. An EXE written like this might be 10K; the same EXE dynamically linked with the CRT, ~20K; the same EXE statically linked with the CRT, ~90K. That difference just isn't very important any more.
And regarding the lack of external dependencies, if you need that, you can statically link with everything (please do your own research regarding licensing and security ramifications). I think that provides you with basically all of the useful benefits of the above approach, for a fraction the effort.