views:

276

answers:

1

For a reason i want to unpack a static lib (libx.a) into individual object files (a.o b.o c.o), and specify these object files (a.o b.o c.o) in the linker input list instead of libx.a, with other linker options remaining the same.

However, i have noticed the above change has resulted in quite some difference in the output executable. Basically, (a.o b.o c.o) method will result in larger output size.

So what's the difference between the two methods (libx.a and individual object files)? And is there a way to work around?

The GNU binutil (for and ar ld) version i'm using is 2.16.1

Thanks.

+1  A: 

Ld removes unused parts of linked .lib archives (like variables with global linkage). This optimization cannot take place when the object files are passed directly, since the linker cannot determine if some unreferenced element of an .o file is needed by some unknown part later (for example because it would be extern visible by the module export list) or can be removed entirely. When a .lib is put in place in the linking process the linker knows for sure that it can drop unnecessary elements.

Rudi
I don't doubt that what you say is true, but it must be q quirk of ld specifically. As far as I can see, as long as you're on the final link step, ld should be able to do all the same dead code stripping with .o files as it does with a .a file.
Mark Bessey
The difference between .lib and .o files is that ld treats unreferenced .o files in .lib files as discardable, while every .o files gets included into the output. This is because there exist special symbols (for example c++ constructors) which get grouped into special sections by ld (even when they are unreferenced) to perform special functionions. There also exist a switch (--whole-archive) to instantiate every unreferenced .o file from .lib files, but I don't know if there is a switch to drop unneded .o files.
Rudi
Thank you everyone. It's good to know that.But does that mean if I always link individual object files into a static lib first before linking the final executable, I can more likely get a smaller output (if there was unreferenced code/data)? And if that is true, it can be a useful technique (sounds counter-intuitive, though).And come back to my original problem (cannot specify output seciton for static libs in the linker script), is there a way to workaround?Thanks.