.O Files VS .A Files

.o files vs .a files

.o files are objects. They are the output of the compiler and input to the linker/librarian.

.a files are archives. They are groups of objects or static libraries and are also input into the linker.

Additional Content

I didn't notice the "examples" part of your question. Generally you will be using a makefile to generate static libraries.

AR = ar 
CC = gcc

objects := hello.o world.o

libby.a: $(objects)
$(AR) rcu $@ $(objects)

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@

This will compile hello.c and world.c into objects and then archive them into library. Depending on the platform, you may also need to run a utility called ranlib to generate the table of contents on the archive.

An interesting side note: .a files are technically archive files and not libraries. They are analogous to zip files without compression though they use a much older file format. The table of contents generated by utilities like ranlib is what makes an archive a library. Java archive files (.jar) are similar in that they are zip files that have some special directory structures created by the Java archiver.

Difference between .a .o and .lo file

The '.lo' file is a library object, which may be built into a shared library, and the '.o' file is a standard object file

The .lo file is the libtool object, which Libtool uses to determine what object file may be built into a shared library

What is *.o file?

A file ending in .o is an object file. The compiler creates an object file for each source file, before linking them together, into the final executable.

What exactly is in a .o / .a / .so file?

You're pretty much correct in the general idea for object files. In the "table that specifies at which addresses in the file" I would replace "addresses" with "offsets", but that's just wording.

.a files are simply just archives (an old format that predates tar, but does the same thing). You could replace .a files with tar files as long as you taught the linker to unpack them and just link with all the .o files contained in them (more or less, there's a little bit more logic to not link with object files in the archive that aren't necessary, but that's just an optimization).

.so files are different. They are closer to a final binary than an object file. An .so file with all symbols resolved can at least theoretically be run as a program. In fact, with PIE (position independent executables) the difference between a shared library and a program are (at least in theory) just a few bits in the header. They contain instructions for the dynamic linker how to load the library (more or less the same instructions as a normal program) and a relocation table that contains instructions telling the dynamic linker how to resolve the external symbols (again, the same in a program). All unresolved symbols in a dynamic library (and a program) are accessed through indirection tables which get populated at dynamic linking time (program start or dlopen).

If we simplify this a lot, the difference between objects and shared libraries is that much more work has been done in the shared library to not do text relocation (this is not strictly necessary and enforced, but it's the general idea). This means that in object files the assembler has only generated placeholders for addresses which the linker then fills in, for a shared library the addresses are filled in with addresses to jump tables so that the text of the library doesn't need to get changed, only a limited jump table.

Btw. I'm talking ELF. Older formats had more differences between programs and libraries.

What is the difference between a .o file and a .lib file?

A .LIB file is a collection of .OBJ
files concatenated together with an
index. There should be no difference
in how the linker treats either.

Quoted from here:

What is the difference between .LIB and .OBJ files? (Visual Studio C++)

Why does the gcc linker behave differently with .a files and .o files?

As far as the linker is concerned, the difference between a static library and an object file
in the linkage sequence is:-

  • An object file is to be linked, just because it is an object file, whether or not it provides
    definitions of any symbols that the executable needs. If you don't want an object
    file to be linked, don't mention it to the linker.

  • A static library is an archive of object files that are to be extracted from the
    library and linked if required, where an object file in a library is required
    if and only if it provides a definition of at least one hitherto undefined
    symbol that the linker has observed in an object file or library appearing earlier in
    the linkage sequence.

Distribution of .o or .a files with headers

When using .a files, do I have to distribute the .cpp files with it or just the .h files?

Only the headers.

What are .o/.a files really

.o files are object code, .a are archives (collections of object files). They're compiled and assembled machine code, that need to be linked in order an executable file to be created.

and why do I need to distribute the .cpp files with it?

You don't.

What are .a and .so files?

Archive libraries (.a) are statically linked i.e when you compile your program with -c option in gcc. So, if there's any change in library, you need to compile and build your code again.

The advantage of .so (shared object) over .a library is that they are linked during the runtime i.e. after creation of your .o file -o option in gcc. So, if there's any change in .so file, you don't need to recompile your main program.
But make sure that your main program is linked to the new .so file with ln command.

Related Topics

Leave a reply