Linux环境下的编译,链接与库的使用.docVIP

  1. 1、本文档共27页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Linux环境下的编译,链接与库的使用

Linux环境下的编译,链接与库的使用 From: HYPERLINK // 为什么使用ullib有时会出现 undefined reference error 的错误? 为什么在动态链接库里ul_log会把日志输出到屏幕上? 为什么用-static 编译有时候会报warning? 我们在使用基础库或者第三方库的时候,经常遇到这样那样的问题,本文结合公司目前的主要环境,说明库的原理,使用的注意事项。 从程序到可执行文件 从hello world 说起 include stdio.h int main() { printf(“hello worldn”); return 0; } 上面这一段程序任何一个学过C语言的同学都是闭着眼睛都可以写出来,但是对于将这样一个源代码编译成为一个可执行文件的过程却不一定有所了解。 上面的程序如果要编译,很简单 gcc hello.c 然后./a.out就可以运行,但是在这个简单的命令后面隐藏了许多复杂的过程 一般来说,可以把这样的过程分成4个: 预编译, 编译, 汇编和链接。 预编译:这个过程包括了下面的步骤 宏定义展开,所有的#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 , 这样在gcc的-I参数只需要指定一个路径,不会由于不小心导致,文件名正好相同出现冲突的麻烦事情. 不过公司由于早期出现了lib2和lib2-64两个目录, 以及头文件输出在include 目录下, 静态发布等一些历史原因, 有些时候使用带完整路径名的方式不是那么合适( 比如 #include 中间有一个include 显的很别扭). 不过个人认为所有的#include 都应该是尽量采用从cvs 根路径下开始写完整路径名的方式进行预编译的过程,只是受限于公司原有习惯和历史问题而显的不合适, 当然带路径的方式要多写一些代码,也是麻烦的事情, 路径由外部指定相对也会灵活一些. 编译:这个过程才是进行语法分析和词法分析的地方, 他们将我们的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 也是一样的 小提示: gcc 采用as 进行汇编的处理过程,as 由于接收的是gcc生成的标准汇编, 在语法检查上存在不少缺陷,如果是我们自己写的汇编代码给as去处理,经常会出现很多莫名奇妙的错误. 链接: 链接的过程,本质上来说是一个把所有的机器码文件组合成一个可执行的文件 上面汇编的结果得到一个.o文件, 但是这个.o要生成二执行文件只靠它自己是不行的, 它还需要一堆辅助的机器码,帮它处理与系统底层打交道的事情. gcc -o hello

文档评论(0)

bm5044 + 关注
实名认证
文档贡献者

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

1亿VIP精品文档

相关文档