67

I know .o are object files, .a are static libraries and .so are dynamic libraries? What is their physical significance? When can I use some and when not?

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
Utkarsh Srivastav
  • 3,105
  • 7
  • 34
  • 53

3 Answers3

100

.a is an "archive". Although an archive can contain any type of file, in the context of the GNU toolchain, it is a library of object files (other toolchains especially on Windows use .lib for the same purpose, but the format of these is not typically a general purpose archive, and often specific to the toolchain). It is possible to extract individual object files from an archive which is essentially what the linker does when it uses the library.

.o is an object file. This is code that is compiled to machine code but not (typically) fully linked - it may have unresolved references to symbols defined in other object files (in a library or individually) generated by separate compilation. Object files contain meta-data to support linking with other modules, and optionally also for source-level symbolic debugging (in GDB for example). Other toolchains, again typically on Windows, use the extension .obj rather than .o.

.so is a shared object library (or just shared library). This is dynamically linked to an executable when a program is launched rather then statically linked at build time. It allows smaller executables, and a single object library instance to be used by multiple executables. Operating system APIs are typically shared libraries, and they are often used also in GNU for licensing reasons to separate LGPL code from closed-source proprietary code for example (I am not a lawyer - I am making no claims regarding the legitimacy of this approach in any particular situation). Unlike .o or .a files, .so files used by an application must be available on the runtime system. Other systems (again typically Windows) use .dll (dynamic link library) for the same purpose.

It is perhaps useful to understand that .o files are linked before object code in .a files such that if a symbol resolution is satisfied by a .o file, any library implementation will not be linked - allowing you to essentially replace library implementations with your own, and also for library implementations to call user-defined code - for example a GUI framework might call an application entry-point.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Regarding "*.o files are linked before object code in .a*", do you mean that occurs irregardless of the order you specified? – Pacerier Mar 03 '17 at 18:40
  • @Pacerier : yes. In every tool-chain I have ever encountered. It is possibly not fool-proof. If say you say have code that references symbols `a` and `b` and your define `a` in a .o to override a library implementation, but in the library both `a` and `b` are defined in the same object module then linking the library object to resolve `b` will pull in `a` conflicting with the previous definition. If the library designer _intended_ the symbols to be overridden then the symbols should be declared `weak` to overcome such issues. Alternatively only one external symbol per object module. – Clifford Sep 01 '21 at 18:38
8

Static libraries are archives that contain the object code for the library, when linked into an application that code is compiled into the executable.

Shared libraries are different in that they aren't compiled into the executable. Instead the dynamic linker searches some directories looking for the library(s) it needs, then loads that into memory. More then one executable can use the same shared library at the same time, thus reducing memory usage and executable size. However, there are then more files to distribute with the executable. You need to make sure that the library is installed onto the user's system somewhere where the linker can find it, static linking eliminates this problem but results in a larger executable file.

Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 2
    `However, there are then more files to distribute with the executable.` Ideally the exact opposite is true. Binary packages on e.g. Linux obviously don't carry around & try to install duplicates of common libraries over & over. They mark a dependency & oblige the user to install them. Even if distributing outwith a package manager, one can often assume either the user's system will already have required libs, or the user can acquire them. It's mostly Windows that often makes things so difficult that we give in & redistribute all the DLLs. Which, uh... kinda defeats the point of dynamic linking – underscore_d Oct 23 '16 at 09:47
5

.so are shared library files. .a are static library files.

You can statically link to .a libraries and dynamically link and load at runtime .so files, provided you compile and link that way.

.o are object files (they get compiled from *.c files and can be linked to create executables, .a or .so libraries. Read more about it here

rost0031
  • 1,894
  • 12
  • 21