Reputation: 683
I'm creating a little static library for having thread pools, and it depends on 2 other homemade static libraries (a homemade printf
and a homemade mini libc
).
But sub-functions like ft_bzero
are not linked in the project unless I use them on the root project, the one that needs to use thread pools library. So I have the linking error coming from my thpool
lib.
Sample :
cc -Wall -Werror -Wextra -MD -I ./ -I ./jqueue -I ../libft/incs -I
../printf/incs -o .objs/thpool_create.o -c ./thpool_create.c
ar rc libthpool.a ./.objs/thpool_create.o etcetc
In the libraries, I compile every .o
and use an ar rc libthpool.a *.o
. Then I compile .o
from main project (a single test.c
actually), and then
cc .objs/test.o -o test -L./libft -L./printf -L./thpool -lft -lftprintf -lthpool -lpthread
How can I solve my errors?
Upvotes: 0
Views: 141
Reputation: 754820
Since the code in the ftpool
library uses code from ft
and ftprintf
, you (almost certainly) need to list the libraries in the reverse order:
cc .objs/test.o -o test -L./libft -L./printf -L./thpool -lthpool -lftprintf -lft -lpthread
When scanning a static library, the linker looks for definitions of symbols that are currently undefined. If your test code only calls functions from thpool
, then none of the symbols in ft
are referenced when the ft
library is scanned, so nothing is included from the library; if none of the symbols from ftprintf
are referenced when the ftprintf
library is scanned, nothing is included from ftprintf
either. When it comes across the symbols in thpool
that reference things from ft
or ftprintf
, it's too late; the linker doesn't rescan the libraries. Hence you need to list the libraries in an order such that all references from one library (A) to another (B) are found by linking (A) before (B). If the test code references some of the functions in ft
or ftprintf
, you may get lucky, or a bit lucky; some symbols may be linked in. But if there are functions in thpool
that make the first reference to a function in ft
, with the order in the question, you've lost the chance to link everything. Hence the suggested reordering.
Another (very grubby, but nonetheless effective) technique is to rescan the static libraries by listing them several times on the command line.
With shared libraries, the rules of linking are different. If a shared library satisfies any symbol, the whole library will be available, so the linker remembers all the defined symbols, and you might well get away with the original link order.
You might need to look up 'topological sort'. You should certainly aim to design your static libraries so that there are no loops in the dependencies; that leads to cycles of dependencies, and the only reliable solutions are either to rescan the libraries or combine the libraries.
Upvotes: 1