我正在尝试编译一个使用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
它开始工作。那么有人可以解释一下第一个命令有什么问题吗?
因为这就是 GNU 链接器使用的链接算法的工作原理(至少在链接静态库时)。链接器是单通道链接器,一旦发现库,它就不会重新访问库。
库是目标文件的集合(存档)。当您使用添加库时-l
选项,链接器不会无条件地采用all库中的目标文件。它只需要那些目标文件目前需要,即解析一些当前未解析(待处理)符号的文件。之后,链接器完全忘记了该库。
当链接器从左到右一个接一个地处理输入目标文件时,链接器会连续维护待处理符号列表。当它处理每个目标文件时,一些符号被解析并从列表中删除,其他新发现的未解析符号被添加到列表中。
因此,如果您使用以下方法包含一些库-l
,链接器使用该库来解析尽可能多的当前挂起的符号,然后完全忘记该库。如果它later突然发现它现在需要来自该库的一些额外的目标文件,链接器将不会“返回”该库来检索这些额外的目标文件。已经太晚了。
因此,使用-l
option late在链接器的命令行中,以便当链接器到达该位置时-l
它可以可靠地确定需要哪些目标文件以及不需要哪些目标文件。放置-l
选项作为链接器的第一个参数通常根本没有任何意义:在一开始,待处理符号列表是空的(或者更准确地说,由单个符号组成)main
),这意味着链接器根本不会从库中获取任何内容。
在你的情况下,你的目标文件example.o
包含对符号的引用ud_init
, ud_set_input_file
等等。链接器应该首先接收该目标文件。它将把这些交易品种添加到待处理交易品种列表中。之后您可以使用-l
添加您的库的选项:-ludis86
。链接器将搜索您的库并从中获取解析这些待处理符号的所有内容。
如果您将-ludis86
命令行中第一个选项,链接器将有效ignore你的图书馆,因为一开始它并不知道它需要ud_init
, ud_set_input_file
等以后加工的时候example.o
它会发现这些交易品种并将它们添加到待处理交易品种列表中。但这些符号到最后都没有得到解决,因为-ludis86
已经被处理(并被有效地忽略)。
有时,当两个(或更多)库以循环方式相互引用时,甚至可能需要使用-l
使用同一库两次选项,使链接器有两次机会从该库检索必要的目标文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)