I wrongfully though that when you linked several *.o the final executable would only have the necessary symbols, not all of them.
Lets say that we have
a.o:
0000000000000000 T a()
0000000000000001 T b()
0000000000000002 T c()
m.o:
0000000000000000 T m()
0000000000000001 T n()
main.o:
U x()
0000000000000000 T main
x.o:
U a()
0000000000000000 T x()
|
main() calls x() that calls a(), all the other functions are empty.
So now lets link all these object files and look at the executable (fat removed)
$ g++ *.o -o object.bin
$ nm -C object.bin
0000000000400580 T a()
0000000000400581 T b()
0000000000400582 T c()
0000000000400584 T m()
0000000000400585 T n()
0000000000400588 T x()
0000000000400480 T main |
so it has all the functions.
However, if instead an static library is created
$ ar rcs lib.a a.o m.o x.o
$ g++ main.o lib.a -o lib.bin
$ nm -C lib.bin
0000000000400588 T a()
0000000000400589 T b()
000000000040058a T c()
0000000000400580 T x()
0000000000400480 T main |
that does not have the unused functions m() and n(), but it does have b() and c().
If I understand it correctly, the undefined symbols in main.o are found in x.o so all the object file is imported. x.o also has undefined symbols, found in a.o, and again all the object file is imported.
However m.o is unneeded and thus discarded. So the dependencies are resolved at object file level instead of function level.
The thing is, we don't need the whole a.o, just the a() definition. If a rule like `only 1 function per source file' were followed, then we'll end with just the functions that we are actually using.
So ¿is there a way to make the tool behave as such?