编译,连接,编译器做的一系列具体事项

通常在windows上编写代码后,需要将其在linux上编译之后才可以运行,以gcc 为例。

对于简单的我们一般直接使用:

gcc example.c -o example

其中主要做了如下工作:


对于复杂多个源码文件安装,一般有如下几个步骤:

./configure

make

make install

下面介绍这几个步骤所做的事:

1. configure

   这一步主要是检查系统的环境,检查函数库,指定软件的安装位置,这些都可以通过指定的参数设置,叫做配置,其中配置信息保存在configure可执行文件中,通常是通过autoconf工具生成的,configure 脚本考虑了不同系统的差异,并且设定了一些默认的参数,如ac_default_prefix=/usr/local。

我们也可以根据需要自己输入一些参数:

./configure --prefix=/usr/local/python --with-mysql

安装Python时安装在/usr/local/python目录,并且编译时加入mysql模块的支持。

2. 确定标准头文件和依赖库的位置

一般而言,linux默认是/usr 、/usr/lib作为库目录的搜索路径,编译第二步就是找标准库和头文件的目录;,一般配置文件中会列出几个目录,编译的时候编译器按照这个方式查找,对于自己新增的库,可通过环境变量LD_LIBRARY指明库的搜索路劲:

export LD_LIBRARY_PATH=<your-lib-path>:$LD_LIBRARY_PATH
ENV=~/.bash_profile
echo "export LD_LIBRARY_PATH=/opt/MESA/lib/:\$LD_LIBRARY_PATH" >> $ENV

或是在/etc/ld.so.conf中注明

/opt/MESA/lib

3. 确定文件的依赖关系

   如果有两个文件A, B,必须先编译完A后才可以编译B,这时就需要在makefile中写明它们的编译顺序,makefile通过configure脚本生成,因此需要先运行configure,生成makefile。

4. 头文件的预编译

    多个源码文件可能使用到同一个头文件,编译源码时,头文件也会编译,为节省时间,编译器一般会编译头文件,且只编译一次,但是不会编译头文件的宏定义,如 #define,#if ...

5. 预处理

编译完头文件后,编译器将源码中使用的头文件和宏替换掉,如下:

extern FILE *stdout;

6. 编译

预处理之后,就开始编译生成机器代码,有些编译器,还会生成中间汇编代码,然后在把汇编代码转为机器代码。

将源码转换成汇编代码,转码后的文件称为对象文件(后缀名 obj)

7. 链接

对象文件还不能直接运行,因为用到了头文件中函数,如stdout, fgets()等,需要进一步转换成可执行文件,编译器需要将外部的函数代码(通常在.lib和.a)添加到可执行文件中,称为链接,有静态链接和动态链接。

make 的作用就是从4-7步。

8. 安装

链接一般是在内存中生成可执行文件,然后就是将可执行文件安装到指定的目录,通常是安装在/usr/share/local下,并且设置相关的执行权限等其他操作。

9. 操作系统链接

程序安装成功后,需要通知操作系统该程序可用,比如office装成功后,默认可以打开指定的word文档。

这就是操作系统登记该程序的元数据:文件名,文件描述,关联的后缀名等,windows下还会在启动菜单中,建立快捷方式,linux中,在/usr/sharea/application中建立对用的.desktop文件。

make install 就完成8-9。

10. 生成安装包

通常很少这样发行软件,一般是编译器对程序进行打包,将可执行文件和相关的数据文件,以一定的目录方式打包成压缩文件,如java中的jar包,或是rpm。

11. 动态链接和静态链接

正常情况下,到这一步,程序已经可以运行了。至于运行期间(runtime)发生的事情,与编译器一概无关。但是,开发者可以在编译阶段选择可执行文件连接外部函数库的方式,到底是静态连接(编译时连接),还是动态连接(运行时连接)。所以,最后还要提一下,什么叫做动态连接。

前面已经说过,静态连接就是把外部函数库,拷贝到可执行文件中。这样做的好处是,适用范围比较广,不用担心用户机器缺少某个库文件;缺点是安装包会比较大,而且多个应用程序之间,无法共享库文件。动态连接的做法正好相反,外部函数库不进入安装包,只在运行时动态引用。好处是安装包会比较小,多个应用程序可以共享库文件;缺点是用户必须事先安装好库文件,而且版本和安装位置都必须符合要求,否则就不能正常运行。

现实中,大部分软件采用动态连接,共享库文件。这种动态共享的库文件,Linux平台是后缀名为.so的文件,Windows平台是.dll文件,Mac平台是.dylib文件。

猜你喜欢

转载自blog.csdn.net/zhongyoubing/article/details/80604653