除非在主项目中使用,否则静态库中的链接错误
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
库中的代码使用了 ft
和 ftprintf
中的代码,您(几乎可以肯定)需要以相反的顺序列出库:
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
中引用 ft
或 ftprintf
中的符号时,为时已晚; linker 不会重新扫描库。因此,您需要按顺序列出库,以便通过 linking (A) 在 (B) 之前找到从一个库 (A) 到另一个 (B) 的所有引用。如果测试代码引用了ft
或ftprintf
中的某些函数,你可能会走运,或者有点走运;一些符号可能被 link 编辑了。但是如果 thpool
中的函数首先引用了 ft
中的函数,那么问题中的顺序就丢失了link 一切的机会。因此建议重新排序。
另一种(非常肮脏,但 none 不太有效)技术是通过在命令行中多次列出它们来重新扫描静态库。
对于共享库,linking 的规则不同。如果共享库满足任何符号,则整个库都可用,因此 linker 会记住所有已定义的符号,并且您可能会摆脱原始的 link 顺序。
您可能需要查找 'topological sort'。您当然应该以设计静态库为目标,以便在依赖项中没有循环;这会导致依赖循环,唯一可靠的解决方案是重新扫描库或合并库。
我正在创建一个用于线程池的小型静态库,它依赖于其他 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
库中的代码使用了 ft
和 ftprintf
中的代码,您(几乎可以肯定)需要以相反的顺序列出库:
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
中引用 ft
或 ftprintf
中的符号时,为时已晚; linker 不会重新扫描库。因此,您需要按顺序列出库,以便通过 linking (A) 在 (B) 之前找到从一个库 (A) 到另一个 (B) 的所有引用。如果测试代码引用了ft
或ftprintf
中的某些函数,你可能会走运,或者有点走运;一些符号可能被 link 编辑了。但是如果 thpool
中的函数首先引用了 ft
中的函数,那么问题中的顺序就丢失了link 一切的机会。因此建议重新排序。
另一种(非常肮脏,但 none 不太有效)技术是通过在命令行中多次列出它们来重新扫描静态库。
对于共享库,linking 的规则不同。如果共享库满足任何符号,则整个库都可用,因此 linker 会记住所有已定义的符号,并且您可能会摆脱原始的 link 顺序。
您可能需要查找 'topological sort'。您当然应该以设计静态库为目标,以便在依赖项中没有循环;这会导致依赖循环,唯一可靠的解决方案是重新扫描库或合并库。