我正在创建一个用于线程池的静态库,它依赖于其他两个自制静态库(一个自制的printf和一个自制的libc)。

但是,除非我在根项目(需要使用线程池库的根项目)上使用它们,否则在项目中不会链接诸如ft_bzero之类的子功能。因此,我的链接错误来自我的thpool库。

样品:

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


在库中,我编译每个.o并使用一个ar rc libthpool.a *.o。然后我从主项目(实际上是一个.o)编译test.c,然后

cc .objs/test.o -o test -L./libft -L./printf -L./thpool -lft -lftprintf -lthpool -lpthread


我该如何解决我的错误?

最佳答案

由于ftpool库中的代码使用ftftprintf中的代码,因此(几乎可以肯定)您需要以相反的顺序列出这些库:

cc .objs/test.o -o test -L./libft -L./printf -L./thpool -lthpool -lftprintf  -lft -lpthread


扫描静态库时,链接程序将查找当前未定义的符号的定义。如果您的测试代码仅从thpool调用函数,则在扫描ft库时未引用ft中的任何符号,因此库中不包含任何内容;如果在扫描ftprintf库时未引用ftprintf中的任何符号,则ftprintf中也不包含任何符号。当遇到thpool中引用ftftprintf事物的符号时,为时已晚。链接器不会重新扫描库。因此,您需要按顺序列出库,以便通过在(B)之前链接(A)来找到从一个库(A)到另一个(B)的所有引用。如果测试代码引用了ftftprintf中的某些功能,您可能会很幸运,或者有些幸运;可能会链接一些符号。但是,如果thpool中的某些函数首次引用ft中的函数,则按问题中的顺序,您将失去链接所有内容的机会。因此,建议重新排序。

另一种(非常肮脏,但仍然有效)的技术是通过在命令行上多次列出静态库来重新扫描它们。

对于共享库,链接规则是不同的。如果共享库满足任何符号,则整个库将可用,因此链接器会记住所有定义的符号,并且您很可能会摆脱原来的链接顺序。

您可能需要查找“拓扑排序”。您当然应该设计静态库,以使依赖项中不存在循环。这导致依赖关系的循环,唯一可靠的解决方案是重新扫描库或合并库。

关于c - 静态lib中的链接错误,除非在主项目中使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51581794/

10-17 02:42