虽然学过编译原理,但其实我一直不是很清楚一个程序生成可执行文件的过程,记得以前有老师讲过,用一下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的阶段,所以也没有多认真地看过资料,有点惭愧。后面还是要用到的,看来还得好好学,先把有用的资料记录一下。