Yes, your application has to know the dependencies between your different static libraries.
- Let's say you have two static libraries
a
and b
.
a
has a function void print_a()
, and b
has a function void print_b()
that is calling to print_a()
. So, b
depends on a
.
- Their binaries will look like
liba.a
and libb.a
.
Let's say that library b
has a reference to a function defined in library a
- void print_b(void)
.
When compiling library b
only its symbols are defined in the binary's code section while the others are still undefined:
host$ nm libb.a | grep print
U _print_a <--- Undefined
0000000000000000 T _print_b <--- Defined, in code section
0000000000000068 S _print_b.eh
U _printf
Therefore, when compiling the application that wants to use both of the libraries, linking only to libb.a
won't be enough. You'll have to link your application to both libraries. Each library will provide its own symbols addresses in the code section and then your application will be able to link to both.
Something like:
gcc -o main main.c libb.a liba.a
BTW: When compiling library b
that uses a
, you can but it's not necessary to link to a
. The result will be just the same.
Why is this the behavior
When compiling + linking the application that uses static libraries, the symbols in the application source files have to be defined somewhere (with the exception of dynamic linking, but this is done only with dynamic libraries/shared objects. Here we deal with static ones).
Now, remember that a static library is just an archive of objects. When it's created there's no linking phase. Just:
- Compiling source code (
*.c
) to objects (*.o
)
- Archiving them together in a
libXXXX.a
file.
It means that if this library (library b
in my example) uses some function (void print_a(void)
) that is defined in another library (a
), this symbol won't be resolved (not as a compilation error, but as the normal behavior). It will be set as Undefined symbol (as we see in the output of nm
command) after the library creation, and it will wait to be linked later to its definition. And it's OK because a static library is not executable.
Now returning to application - the linking phase of the application needs to find all the definitions of all the symbols. If you just gave it libb.a
as an argument, it wouldn't be able to find the definition to print_a()
, because it's not there, it's still undefined. It exists only in liba.a
.
Therefore, you must provide both of the libraries.