除非在主项目中使用,否则静态库中的链接错误

Linking error in static lib unless used in main project

我正在创建一个用于线程池的小型静态库,它依赖于其他 2 个自制静态库(一个自制 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

扫描静态库时,linker 查找当前未定义的符号定义。如果您的测试代码仅调用来自 thpool 的函数,那么扫描 ft 库时会引用 ft 中的 none 个符号,因此不会从库中包含任何内容;如果在扫描 ftprintf 库时引用 ftprintf 中的 none 个符号,则 ftprintf 中也不会包含任何内容。当它遇到 thpool 中引用 ftftprintf 中的符号时,为时已晚; linker 不会重新扫描库。因此,您需要按顺序列出库,以便通过 linking (A) 在 (B) 之前找到从一个库 (A) 到另一个 (B) 的所有引用。如果测试代码引用了ftftprintf中的某些函数,你可能会走运,或者有点走运;一些符号可能被 link 编辑了。但是如果 thpool 中的函数首先引用了 ft 中的函数,那么问题中的顺序就丢失了link 一切的机会。因此建议重新排序。

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

对于共享库,linking 的规则不同。如果共享库满足任何符号,则整个库都可用,因此 linker 会记住所有已定义的符号,并且您可能会摆脱原始的 link 顺序。

您可能需要查找 'topological sort'。您当然应该以设计静态库为目标,以便在依赖项中没有循环;这会导致依赖循环,唯一可靠的解决方案是重新扫描库或合并库。