为什么GCC的“-l”选项的顺序很重要?

为什么GCC的“-l”选项的顺序很重要?

我正在编写一个程序udis86图书馆。实际上,我使用的是用户手册图书馆的。但是在编译时,它会产生错误。我所犯的错误是:

example.c:(.text+0x7): undefined reference to 'ud_init'example.c:(.text+0x7): undefined reference to 'ud_set_input_file'..example.c:(.text+0x7): undefined reference to 'ud_insn_asm'

我使用的命令是:

$ gcc -ludis86 example.c -o example

按照用户手册中的指示。

显然,链接器无法链接到libudis库。但如果我改变命令:

$ gcc example.c -ludis86 -o example

它开始起作用了。那么,请有人解释一下第一个命令的问题是什么吗?


慕姐4208626
浏览 1331回答 3
3回答

千巷猫影

我撞了同样的问题一段时间前。底线是,GNUTools不会总是在库列表中“搜索”以解决缺少的符号。简单的修复方法有以下任何一种:只需按照依赖关系顺序指定lib和objs(正如您在上面所发现的)。或者,如果您有一个循环依赖项(其中Liba引用libB中的一个函数,而libB在Liba中引用一个函数),那么只需在命令行上指定两次lib。这也是手册的意思。例如:gcc foo.c -lfoo -lbar -lfoo使用-(和-)Params用于指定具有这种循环依赖关系的一组档案。请参阅GNU链接器手册--start-group和--end-group..看见这里更多细节。当您使用选项2或3时,可能会引入链接的性能成本。如果你没有那么多的链接,这可能并不重要。

米脂

或使用重装第41页Oracle Solaris 11.1链接程序和库指南:档案之间可能存在相互依赖关系,因此必须通过从另一个归档中提取成员来解决从一个存档中提取成员的问题。如果这些依赖项是循环的,则必须在命令行上反复指定档案以满足以前的引用。$ cc -o prog .... -lA -lB -lC -lA -lB -lC -lA重复存档规范的确定和维护可能很繁琐。-z rescan-Now选项使此过程更简单。在命令行上遇到该选项时,链接编辑器立即处理-z rescan-Now选项。在此选项之前从命令行处理的所有档案都会立即重新处理。此处理尝试定位解析符号引用的其他存档成员。此存档重新扫描将继续进行,直到在没有提取新成员的情况下对归档列表进行传递。前面的示例可以简化如下。$ cc -o prog .... -lA -lB -lC -z rescan-now或者,-z rescan-start和-z rescan-end选项可用于将相互依赖的档案分组为存档组。当命令行上遇到关闭分隔符时,链接编辑器将立即重新处理这些组。在组中找到的档案将被重新处理,以试图找到解析符号引用的其他归档成员。此存档重扫描将继续进行,直到在未提取新成员的情况下对归档组进行传递。使用归档组,可以编写前面的示例,如下所示。$ cc -o prog .... -z rescan-start -lA -lB -lC -z rescan-end
打开App,查看更多内容
随时随地看视频慕课网APP