当前位置:  开发笔记 > 编程语言 > 正文

包含Linux GCC链接器

如何解决《包含LinuxGCC链接器》经验,为你挑选了2个好方法。

我不明白GCC在Linux下如何运作.在源文件中,当我执行以下操作时:

#include 

编译器是否提取适当的二进制代码并将其插入到已编译的可执行文件中,或者编译器是否插入对外部二进制文件的引用(a-la Windows DLL?)

我想这个问题的通用版本是:在*nix下有没有与Windows DLL相同的概念?



1> Johannes Sch..:

好.当您包含math.h编译器时,将读取包含可以使用的函数和宏的声明的文件.如果调用在该文件(文件)中声明的函数,则编译器会在目标文件中的那个位置插入一个调用指令,该指令将从您编译的test.c文件中生成(让我们调用它并创建目标文件test.o).它还在该对象文件的重定位表中添加了一个条目:

Relocation section '.rel.text' at offset 0x308 contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000001c  00000902 R_386_PC32        00000000   bar

这将是功能栏的重定位条目.将在符号表中创建一个条目,注意该函数尚未定义:

9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar

test.o目标文件链接到程序时,需要链接到名为的数学库libm.so.该so扩展类似于.dll扩展窗口.这意味着它是一个共享对象文件.链接时,编译器将修复重定位表中出现的所有位置test.o,用条形函数的正确地址替换其条目.根据您使用库的共享版本还是静态库(当时称为库libm.a),编译器将在编译后执行该修复,或者在实际启动程序时在运行时执行此修复.完成后,它将在该程序所需的共享库表中注入一个条目.(可以显示readelf -d ./test):

Dynamic section at offset 0x498 contains 22 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 ... ... ...

现在,如果启动程序,动态链接器将查找该库,并将该库链接到可执行映像.在Linux中,调用执行此操作的程序ld.so.静态库在动态部分中没有位置,因为它们只是链接到其他目标文件,然后被遗忘; 从那时起它们就是可执行文件的一部分.

实际上它实际上要复杂得多,而且我也不太明白这一点.不过,这是一个粗略的计划.



2> Konrad Rudol..:

这里涉及几个方面.

首先,头文件.编译器只是将文件的内容包含在包含它的位置,仅此而已.据我所知,GCC甚至没有区别对待标准头文件(但我可能在那里错了).

但是,头文件实际上可能不包含实现,只包含其声明.如果实现位于其他位置,则必须告诉编译器/链接器.默认情况下,只需将相应的库文件传递给编译器,或者传递库名称即可.例如,以下两个是等效的(假设它libcurl.a位于链接器可以找到的目录中):

gcc codefile.c -lcurl
gcc codefile.c /path/to/libcurl.a

这告诉链接编辑器("链接器")将您的代码文件与静态库的实现相链接libcurl.a(编译器gcc实际上忽略了这些参数,因为它不知道如何处理它们,只是将它们传递给链接器) .但是,这称为静态链接.还有动态链接,它发生在程序启动时,.dll在Windows下用s 发生(而静态库对应.libWindows 上的文件).Linux下的动态库文件通常具有文件扩展名.so.

了解这些文件的最佳方法是熟悉GCC链接器,ld以及优秀的工具集binutils,您可以毫不费力地编辑/查看库文件(实际上是任何二进制代码文件).

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有