"--start-group"和"--end-group"命令行选项是什么?

103

这些命令行选项的目的是什么?请帮忙解释以下命令行的含义:

-Wl,--start-group -lmy_lib -lyour_lib -lhis_lib -Wl,--end-group -ltheir_lib

显然这与链接有关,但GNU手册并没有明确说明“grouping”具体指什么。

1个回答

123

这是为了解决在几个库(列在-(-)之间)之间的循环依赖关系。

引用为什么链接库的顺序有时会导致GCC出错?或者man ldhttp://linux.die.net/man/1/ld

-(存档文件列表-)--start-group存档文件列表--end-group

存档文件列表应该是一个存档文件列表。它们可能是显式文件名,也可能是-l选项。

指定的存档文件将被反复搜索,直到不再创建新的未定义引用为止。通常情况下,存档文件只按照命令行上指定的顺序搜索一次。如果命令行上后面的一个存档中的符号需要解析前面一个存档中的未定义符号,那么链接器将无法解析该引用。通过对存档进行分组,所有存档都将被反复搜索,直到解析所有可能的符号引用为止。

使用此选项会带来显著的性能损失。最好只在两个或多个存档之间存在不可避免的循环引用时才使用它。

因此,在组内的库可以被反复搜索新的符号,而且您不需要像-llib1 -llib2 -llib1这样的丑陋结构。

PS 存档基本上是静态库(*.a文件)


1
已接受。备注:我相信GCC首先使用动态库,除非在命令行中传递了完整的文件名(包括路径和.a后缀)。-llib1会导致GCC首先尝试链接到%.so文件,然后再尝试%.a文件。 - pic11
1
@pic11,谢谢。链接是由ld完成的,您可以通过向gcc添加-Wl,--verbose选项来查看如何搜索库(它将把--verbose传递给链接器ld)。例如对于-ltest库:attempt to open /lib/libtest.so failed \n attempt to open /lib/libtest.a failed \n attempt to open /usr/lib/libtest.so failed \n attempt to open /usr/lib/libtest.a failed \n 。链接器首先尝试打开.so文件,然后再尝试打开.a文件。这在库搜索目录中的每个目录中都会执行。 - osgx
搜索了多次新符号?我认为搜索两次就足以解决所有符号。这应该不会造成显著的性能损耗。 - Jimm Chen
13
抱歉,我最终意识到“搜两遍”是不够的。 - Jimm Chen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接