程序的编译链接关系及库文件编写

虽然学过编译原理,但其实我一直不是很清楚一个程序生成可执行文件的过程,记得以前有老师讲过,用一下UNUX就会很清楚整个过程的了。

确实,看Makefile文件时就发现,原来在这文件里是写得很详细的。虽然我也没有看得很懂,但是看了一些资料也是清楚了一些吧。这个基本过程还是应该要清楚的。

 

“”

关 于程序编译的一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在 Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

编 译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在 C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文 件)。

链 接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只 管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给 中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

总 结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编 译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File.

 

 

上述的描述把编译链接的关系写得挺清楚的,也算是解决了我一直困惑的问题吧。

上面的资料来自: http://dev.csdn.net/htmls/20/20025.html

 

于是就到了Makefile文件编写的问题了,“make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。” 个人觉得Makefile文件的编写真的挺难的,我看了一两天都看得不是太懂,当然,我比较心急,急于求成,没有多有耐心地看,这也是看不懂的最主要原因吧。

 

但是,网上确实有个很好的教材:

http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/make-04.html

下面是一位牛人写的教程,很多但写得很细,也是我没有耐心看下去的那个教程……囧

http://so.csdn.net/BlogSearchResult.aspx?q=%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99%20Makefile

 

 

连接后可以生成库文件,库文件又分为静态库与动态库:

“    如果程序是在编译时加载库文件的,就是使用了静态库。如果是在运行时加载目标代码,
就成为动态库。换句话说,如果是使用静态库,则静态库代码在编译时就拷贝到了程序的代码段,程序的体积会膨胀。如果使用动态库,则程序中只保留库文件的名字和函数名,在运行时去查找库文件和函数体,程序的体积基本变化不大。
    静态库的原则是“以空间换时间”,增加程序体积,减少运行时间;动态库则是“以时间换空间”,增加了运行时间,但减少了程序本身的体积。”

 

“静态库文件的扩展名一般为.a,其编写步骤很简单。
 ⑴编写函数代码
 ⑵编译生成各目标文件
 ⑶用ar文件对目标文件归档,生成静态库文件。
    注意归档文件名必须以lib打头。
   使用要点:
   ⑴在gcc 的-I参数后加上静态库头文件的路径。
   ⑵在gcc 的-L参数后加上库文件所在目录
   ⑶在gcc 的-l参数后加上库文件名,但是要去掉lib和.a扩展名。比如库文件名是libtest.a 那么参数就是 -l test”

 

“ 动态库一般以.so结尾,就是shared object的意思.
   其基本生成步骤为
   ⑴编写函数代码
   ⑵编译生成动态库文件,要加上 -shared 和 -fpic 选项 ,
     库文件名以lib开头, 以.so 结尾。
    
   使用方式分为两种: 隐式调用和显示调用 
    隐式调用类似于静态库的使用,但需修改动态链接库的配置文件/etc/ld.so.conf;
    显示调用则是在主程序里使用dlopen、dlsym、dlerror、dlclose等系统函数。”

 

详细介绍看: http://blog.chinaunix.net/u2/86665/showart_1881391.html  

 

 

总结一下,由于现在还没到写Makefile的阶段,所以也没有多认真地看过资料,有点惭愧。后面还是要用到的,看来还得好好学,先把有用的资料记录一下。

 

http://blog.csdn.net/chhangh/archive/2010/07/02/5709586.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值