I understand that code included in an executable at compile-time can come from object files (.o files) and statically-linked libraries (.lib/.a files). What is fundamentally and conceptually the difference between these two? Why is there a different concept between "object code" and a "statically-linked library"? What are the advantages and disadvantages to each, and why use one as opposed to the other? Can statically-linked library(ies) be made from object file(s), and vise-versa, can object file(s) be made from statically-linked library(ies)?
Object files are compiled but unlinked code. Libraries contain object files. Thus your question becomes, "Why use statically-linked libs if I can just use object files?" Here's why.
Unlike a collection of objects, each of which have their own symbol tables, a library has a single, unified symbol table, created when ar
is called by the library developer using the s
switch. s
calls ranlib
to create a unified symbol table for all objects in that archive.
Running ranlib
in shell shows in the first line of help text:
Generate an index to speed access to archives.
And from the generic ranlib docs:
An archive with such an index speeds up linking to the library and allows routines in the library to call each other without regard to their placement in the archive. T
See also the FreeBSD ranlib docs - different wording, same idea: Speed of linkage.
A library is simply a file containing many object files, which can be searched to resolve symbols.
So typically, when you link objects together, you get all the objects in one executable (though some optimising linkers can throw out unused ones).
When you give a library to the linker, it examines each of the object files within it and brings in those that are needed to satisfy unresolved symbols (and will probably continue to bring them in until either all symbols are resolved or no more can be).
It's just a way of efficiently packaging up a lot of objects into a single file so that the linker can do more of your work - you don't have to worry about which objects you need.
If you think of the C library, you may have a printf.o
, puts.o
, fopen.o
as a result of keeping your source well separated. You don't want the user to have to explicitly list every single object file they want so you package the whole lot up into libc.a
and tell them they just need to link with that single file.
The statically-linked bit is irrelevant here, it just decides that the objects should go into the executable at link time rather than being dynamically loaded at run time. It's explained here.
libc.a
and let the linker work it out? Maybe I'm inherently lazy but that's not always a bad thing :-) As to how the linker works, it could throw away ones that satisfy no symbols even if you explicitly list them. Most don't though ISTR Visual Studio was smart like that. –
Tedmann © 2022 - 2024 — McMap. All rights reserved.