编译与链接的知识.doc

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
编译与链接的知识 ? 编译与链接的知识2010-07-05 23:52linux下编译hello.c程序,使用gcc hello.c,然后./a.out就可以运行;在这个简单的命令后面隐藏了许多复杂的过程,这个过程包括了下面的步骤 宏定义展开,所有的#define在这个阶段都会被展开预编译命令的处理,包括#if#ifdef一类的命令展开#include的文件,像上面hello world中的stdio.h,把stdio.h中的所有代码合并到hello.c中去掉注释gcc的预编译采用的是预编译器cpp,我们可以通过-E参数来看预编译的结果,如: gcc-E hello.c-o hello.i生成的hello.i就是经过了预编译的结果在预编译的过程中不会太多的检查与预编译无关的语法(#ifdef之类的还是需要检查,#include文件路径需要检查),但是对于一些诸如;漏掉的语法错误,在这个阶段都是看不出来的。写过makefile的人都知道,我们需要加上-Ipath一系列的参数来标示gcc对头文件的查找路径 小提示: 1.在一些程序中由于宏的原因导致编译错误,可以通过-E把宏展开再检查错误,这个在编写PHP扩展,python扩展这些大量需要使用宏的地方对于查错误很有帮助。 2.如果在头文件中,#include的时候带上路径在这个阶段有时候是可以省不少事情,比如#include public/connectpool/connectpool.h,这样在gcc的-I参数只需要指定一个路径,不会由于不小心导致,文件名正好相同出现冲突的麻烦事情.带路径的方式要多写一些代码,也是麻烦的事情,路径由外部指定相对也会灵活一些. 编译 这个过程才是进行语法分析和词法分析的地方,他们将我们的C/C++代码翻译成为汇编代码,这也是一个编译器最复杂的地方 使用命令 gcc-S hello.i-o hello.s可以看到gcc编译出来的汇编代码,现代gcc编译器一般是把预编译和编译合在一起,使用cc1的程序来完成这个过程,编译大文件的时候可以用top命令看一个cc1的进程一直在占用时间,这个时候就是程序在执行编译过程.后面提到的编译过程都是指cc1的处理包括了预编译与编译. 汇编 现在C/C++代码已经成为汇编代码了,直接使用汇编代码的编译器把汇编变成机器码(注意还不是可执行的). gcc-c hello.c-o hello.o这里的hello.o就是最后的机器码,如果作为一个静态库到这里可以所已经完成了,不需要后面的过程. 对于静态库,比如ullib,COM提供的是libullib.a,这里的.a文件其实是多个.o通过ar命令打包起来的,仅仅是为了方便使用,抛开.a直接使用.o也是一样的 小提示: 1.gcc采用as进行汇编的处理过程,as由于接收的是gcc生成的标准汇编,在语法检查上存在不少缺陷,如果是我们自己写的汇编代码给as去处理,经常会出现很多莫名奇妙的错误. 链接的过程,本质上来说是一个把所有的机器码文件组合成一个可执行的文件上面汇编的结果得到一个.o文件,但是这个.o要生成二执行文件只靠它自己是不行的,它还需要一堆辅助的机器码,帮它处理与系统底层打交道的事情. gcc-o hello hello.o这样就把一个.o文件链接成为了一个二进制可执行文件. 这个地方也是本文讨论的重点,在后面会有更详细的说明 小提示: 有些程序在编译的时候会出现linker input file unused because linking not done的提示(虽然gcc不认为是错误,这个提示还是会出现的),这里就是把编译和链接使用的参数搞混了,比如 g++-c test.cpp-I././ullib/include-L././ullib/lib/-lullib这样的写法就会导致上面的提示,因为在编译的过程中是不需要链接的,它们两个过程其实是独立的 静态链接 链接的过程 这里先介绍一下,链接器所做的工作 其实链接做的工作分两块:符号解析和重定位 符号解析 符号包括了我们的程序中的被定义和引用的函数和变量信息 在命令行上使用nm./test test是用户的二进制程序,包括 可以把在二进制目标文件中符号表输出 00000000005009 b8 A__bss_start 00000000004004 cc tcall_gmon_start 00000000005009 b8 bcompleted.1 0000000000500788 d__CTOR_END__ 0000000000500780 d__CTOR_LIST__ 00000000005009 a0 D__data_start 00000000005009 a0 Wdata_start 0000000000

文档评论(0)

shujukd + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档