为什么在gcc的事“-l”选项的顺序? [英] Why does the order of '-l' option in gcc matter?

查看:267
本文介绍了为什么在gcc的事“-l”选项的顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编译它使用 udis86 库的程序。其实我现在用在图书馆的用户手册给出的示例程序。但是在编译时,它给错误。我得到的错误是:

I am trying to compile a program which uses udis86 library. Actually I am using an example program given in the user-manual of the library. But while compiling, it gives error. The errors I get are:

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'

我使用的命令是:

The command I am using is:

$ gcc -ludis86 example.c -o example 

的指示,在用户手册

as instructed in the user-manual.

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

Clearly, linker is not able to link libudis library. But if I change my command to:

$ gcc example.c -ludis86 -o example 

它开始工作。所以,可以请别人解释什么是与第一个命令的问题?

It starts working. So can please someone explain what is the problem with the first command?

推荐答案

由于这是如何通过GNU链接的作品所使用的连接算法(当谈到链接静态库最小)。

Because that's how the linking algorithm used by GNU linker works (a least when it comes to linking static libraries).

一个库是目标文件的集合(存档)。当你使用 -l <​​/ code>选项添加库,链接器不会无条件承担的所有的对象从库文件。只需要那些的目前所需要的那些对象文件的,即是解决一些悬而未决的当前(待定)符号的文件。在此之后,接头完全忘记有关库

A library is a collection (an archive) of object files. When you add a library using the -l option, the linker does not unconditionally take all object files from the library. It only takes those object files that are currently needed, i.e. files that resolve some currently unresolved (pending) symbols. After that, the linker completely forgets about that library.

悬而未决的符号列表不断被作为连接器处理输入目标​​文件,陆续从左至右连接器保持。由于它处理的每个目标文件,一些符号得到解决,并从列表中删除,其他新发现的尚未解决的符号被添加到列表中。

The list of pending symbols is continuously maintained by the linker as the linker processes input object files, one after another from left to right. As it processes each object file, some symbols get resolved and removed from the list, other newly discovered unresolved symbols get added to the list.

所以,如果包括使用 -l <​​/ code>某些库,链接程序使用该库来解决许多目前正在等待符号就可以了,然后完全忘记有关图书馆。如果是的之后的突然发现,它现在需要从库中一些额外的目标文件(S),链接器不会回归到图书馆检索这些额外的目标文件。这是为时已晚。

So, if you included some library by using -l, the linker uses that library to resolve as many currently pending symbols as it can, and then completely forgets about that library. If it later suddenly discovers that it now needs some additional object file(s) from that library, the linker will not "return" to that library to retrieve those additional object files. It is already too late.

由于这个原因,它始终是用一个好主意 -l <​​/ code>选项的的在链接器的命令行,这样的时候连接器获取到 -l <​​/ code>它可以可靠地确定需要哪些对象文件,它并不需要。配售 -l <​​/ code>选项作为第一个参数给连接器一般是没有意义的:在挂起的符号的最开始的列表是空的,这意味着,连接器将不采取从库中的任何东西。

For this reason, it is always a good idea to use -l option late in the linker's command line, so that by the time the linker gets to that -l it can reliably determine which object files it needs and which it doesn't need. Placing the -l option as the very first parameter to the linker generally makes no sense at all: at the very beginning the list of pending symbols is empty, meaning that the linker will not take anything from the library at all.

在你的情况,你的目标文件 example.o 包含对符号的引用 ud_init ud_set_input_file 等链接器应首先接收目标文件。将这些符号添加到待处理的符号列表。之后,你可以使用 -l <​​/ code>选项添加你的库: -ludis86 。链接器将搜索您的图书馆,并从它采取一切能够解决这些悬而未决的符号。

In your case, you object file example.o contains references to symbols ud_init, ud_set_input_file etc. The linker should receive that object file first. It will add these symbols to the list of pending symbols. After that you can use -l option to add the your library: -ludis86. The linker will search your library and take everything from it that resolves those pending symbols.

如果您第一次放置 -ludis86 选项在命令行中,连接器将有效的忽略的库中,因为一开始它不知道,这将需要 ud_init ud_set_input_file 等。后来,当处理 example.o 它会发现这些符号并将它们添加到待处理的符号列表。但是,这些符号将得不到解决到最后,因为 -ludis86 已经被处理(并忽略了)。

If you place the -ludis86 option first in the command line, the linker will effectively ignore your library, since at the beginning it does not know that it will need ud_init, ud_set_input_file etc. Later, when processing example.o it will discover these symbols and add them to the pending symbol list. But these symbols will remain unresolved to the end, since -ludis86 was already processed (and effectively ignored).

有时候,当两个(或多个)库指的是循环的方式彼此,人们可能甚至需要与相同的库两次使用 -l <​​/ code>选项,以给连接两次机会检索库所需的目标文件。

Sometimes, when two (or more) libraries refer to each other in circular fashion, one might even need to use the -l option twice with the same library, to give linker two chances to retrieve the necessary object files from that library.

这篇关于为什么在gcc的事“-l”选项的顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆