0

If I compile C hello world with MinGW, the resulting exe is 42Kb. If I use Tiny C Compiler, I get something 2Kb. (in both cases without specifying any options or doing anything interesting, just gcc hello.c -o hello.exe)

Now I am aware that a minimum bit of startup code is needed; but what is the extra 40kb of stuff that mingw puts there, what does it do, why is it needed?

Jesse
  • 51
  • 2
  • Yours is only 42KB, this one is even bigger 93.7KB (not Kb which is kilo/kibibit) [Why would a C executable be smaller when compared to C++ executable](http://softwareengineering.stackexchange.com/q/246167/98103). If you [compile with `-O2/-O3/-Os` the size will reduce greatly]([Why is a C++ Hello World binary larger than the equivalent C binary?](http://stackoverflow.com/q/25614505/995714)) because many unused parts are removed – phuclv Nov 19 '16 at 13:55
  • C++, but some parts apply to C as well [“Hello World” program -> .exe is 500kb big when compiled on Windows. How can I reduce its size?](http://stackoverflow.com/q/1042773/995714), [Compiled C++ executables HUGE?](http://stackoverflow.com/q/4178910/995714) – phuclv Nov 19 '16 at 13:55

1 Answers1

-1

From the FAQ:

Debugging Information

The most common reason why executables are larger than expected is that they include debugging information, which is generated when source files are compiled with the "-g" option to GCC. Even when your own source files are compiled without debugging information, libraries linked with your executable may have been compiled with "-g" (possibly including system libraries that are distributed with MinGW).

To exclude debugging information from your executable, simply use the "strip" command to remove it, or alternatively use the "-s" option when linking.

UPX (Ultimate Packer for eXecutables)

UPX is a tool that can decrease the size of executables, using very fast and very efficient in-place compression/decompression. It works for Windows and Linux executables and is free for use with all applications (including commercial apps).

Qrchack
  • 899
  • 1
  • 10
  • 20
  • Is that missing the use of shared or static libraries? – Ed Heal Nov 19 '16 at 13:36
  • 2
    What have templates, C++, exceptions and RTTI to do with a C question? – Kerrek SB Nov 19 '16 at 13:37
  • I'm adding a complete answer from the MinGW documentation, the most important one is debugging information anyway. – Qrchack Nov 19 '16 at 13:44
  • I did *not* compile it with the -g option, as I said in the question, so the debugging stuff should have only come from linked libraries. But strip only reduced the result to 20kb, so there is still seems to be a lot of extra stuff in there... – Jesse Nov 19 '16 at 14:09
  • 1
    You're using , right? Well, then it has to add all the stuff that comes from stdio – Qrchack Nov 19 '16 at 14:14
  • so does mingw link it's own c library with the exe? I thought it just links dynamic with msvcrt from windows, that's what is happening with tcc and the resulting exe only has the main function and tcc's startup function... – Jesse Nov 19 '16 at 19:09
  • @Jesse Yes, MinGW adds its own library for the GCC-specific stuff to function properly. A "Hello world" that simply returns 0 requires a minimum of libmingwex.a, libmingw32.a, libgcc.a, libmsvcrt.a (or some version-specific libmsvcrXXX.a lib), and libkernel32.a as well as crt2.o. libmingwex is required by libmingw32, and libmingw32 is required by crt2.o. libgcc provides the `___chkstk_ms` symbol required by crt2.o, and the other stuff is Windows-specific. –  Nov 19 '16 at 19:21
  • but what 'gcc-specific stuff' is it doing? this is what I want to know – Jesse Nov 19 '16 at 19:24
  • @Jesse Apparently I'm wrong. I just did something interesting by omitting everything except the C source file and the libmsvcrt.a import library: `gcc -nostdlib -O2 -s -o hello.exe hello.c -lmsvcrt`. Oddly enough, it works fine (mostly)... I just had to use `void __main(void)` to get a 3.5kb EXE file and ensure that I call `exit(0);` at the end. However, command line arguments don't work (relatively easily fixed with the `__getmainargs()` function); I can't guarantee it runs reliably since I haven't looked at how things work. I'd also love to see such a small EXE without this extra work. –  Nov 19 '16 at 20:41
  • interesting, that does not work with mingw for me. but as far as I know all you actually need is getmainargs, call main, then exit, both of which you can link to msvcrt. Removing everything but this minimum, tcc makes an exe that is 2kb that works fine, and a large ammount of it appears to be empty padding, I don't know if different parts have a minimum size I don't know much about coff format. But my question remains - "What is the 'gcc-specific stuff' and what is it doing?" – Jesse Nov 20 '16 at 11:58
  • @Jesse Apparently it's mostly Windows-specific stuff, so allow me to apologize. tcc sets some floating-point info, sets up argc, argv, and envp using `__getmainargs()` from MSVCRT, and finally calls the equivalent of `exit(main(argc, argv, envp))`. MinGW code seems to do a lot of its own work, perhaps for compatibility reasons. The Win32 readme for tcc also claims it doesn't support COFF while MinGW deals with relocations using its own `_pei386_runtime_relocator` procedure. There's a lot going on in the MinGW code, including SEH bookkeeping, but I'm not sure it can be replaced easily. –  Nov 20 '16 at 14:26