Jo Even Skarstein wrote:
I see that libgcc is 85Kb on my system (gcc 2.95). Is this why helloworld.c results in a 102Kb binary?
No.A library (.a) is a collection of .o files. When a library is specified when linking a program, only the required .o files are extracted from the .a and embedded into the final executable. So you can have a very big library, when linking with it you will get only the contents you need, and your program will not be bigger as required.
The big problem is the dependencies between functions. A .o uses functions from another .o, and so on. Finally, if you don't take care, you have the whole world linked to your program.
I believe the problem come from the MiNTLib. Before reaching main, the library has to do a lot of work: initialize the memory, split the command line, etc. To do this, it has to use other functions from the library, and so on. One big problem is usually printf(). It contains a lot of functionalities, all of them are linked when you use at least one printf() in your code.
The dependency problem could be analyzed with the right tools to see where the problems are, and it may be improved. Personally I don't plan to work on this, because I prefer to get things working before optimizing them.
The first thing to do is to put only one function in each .c file, thus a .o will contain only one function, and the dependencies will be minimized. The whole contents of a .o (and their dependencies) are always linked (at least with a.out object files).
And final note: GCC does not produce big or bad code. If you look at the assembler code produced, you will see that it is usually very good.
The best compiler options to get small executables are : gcc -O2 -fomit-frame-pointer -sAbout libgcc: it contains only small standalone functions, I believe it does not increase significantly the size of the executable.
Note that because other OSes have shared library support and usually big amount of memory, they don't care about the size problems. For example, the glibc used by Linux is huge. But it is loaded only once in memory. Linux executables linked statically are very big, too. Because of that, some people are developing lightweight standard libraries, like uclibc, dietlibc... to minimize the size of embedded executables.
-- Vincent Rivière