¿why does the executable contain the definition of symbols that are never used? (gcc)

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?
AFAIK, the GNU toolchain has no direct support for function-level-linking (Microsoft has had it since 1998).

rlink seems to work out quite well. https://ribosome.helixcommunity.org/2005/devdocs/FuncLevelLinking
I tend to use a large number of small object files; so my experience with this is quite limited.

There ought to be many other similar tools floating around on the net.
From here (first answer):
http://stackoverflow.com/questions/6687630/c-c-gcc-ld-remove-unused-symbols

Seems to work, if I understand the problem:
gcc -Os -fdata-sections -ffunction-sections *.cpp -o object.bin -Wl,--gc-sections
nm object.bin
00000000004003c0 T main
00000000004004bd T a()
00000000004004be T x()
While we're on this topic I have a related question - can an executable be used as a shared library/DLL?
> can an executable be used as a shared library/DLL?

Platform specific; if it is supported, we would always need -fpic (or its equivalent).
http://gcc.gnu.org/ml/gcc-help/2003-07/msg00232.html
Topic archived. No new replies allowed.