• <fieldset id='fw6gs'></fieldset>
    1. <tr id='fw6gs'><strong id='fw6gs'></strong><small id='fw6gs'></small><button id='fw6gs'></button><li id='fw6gs'><noscript id='fw6gs'><big id='fw6gs'></big><dt id='fw6gs'></dt></noscript></li></tr><ol id='fw6gs'><table id='fw6gs'><blockquote id='fw6gs'><tbody id='fw6gs'></tbody></blockquote></table></ol><u id='fw6gs'></u><kbd id='fw6gs'><kbd id='fw6gs'></kbd></kbd>
    2. <span id='fw6gs'></span>

        <ins id='fw6gs'></ins>

        <dl id='fw6gs'></dl>

        <i id='fw6gs'></i>

        <i id='fw6gs'><div id='fw6gs'><ins id='fw6gs'></ins></div></i>

        <code id='fw6gs'><strong id='fw6gs'></strong></code>
            <acronym id='fw6gs'><em id='fw6gs'></em><td id='fw6gs'><div id='fw6gs'></div></td></acronym><address id='fw6gs'><big id='fw6gs'><big id='fw6gs'></big><legend id='fw6gs'></legend></big></address>
          1. 编译器的工作过程

            • 时间:
            • 浏览:366
            • 来源:自己学好网

              源码要运行 ,必须先转成二进制的机器码  。这是编译器的任务 。

              比如 ,下面这段源码(假定文件名叫做test.c)  。

              #include <stdio.h>
              
              int main(void)
              {
                fputs("Hello, world!\n", stdout);
                return 0;
              }
              

              要先用编译器处理一下  ,才能运行 。

              $ gcc test.c
              $ ./a.out
              Hello, world!
              

              对于复杂的项目 ,编译过程还必须分成三步 。

              $ ./configure
              $ make  
              $ make install
              

              这些命令到底在干什么  ?大多数的书籍和资料  ,都语焉不详  ,只说这样就可以编译了 ,没有进一步的解释  。

              本文将介绍编译器的工作过程  ,也就是上面这三个命令各自的任务  。我主要参考了Alex Smith的文章《Building C Projects》  。需要声明的是  ,本文主要针对gcc编译器  ,也就是针对C和C++  ,不一定适用于其他语言的编译  。

              第一步 配置(configure)

              编译器在开始工作之前  ,需要知道当前的系统环境  ,比如标准库在哪里、软件的安装位置在哪里、需要安装哪些组件等等  。这是因为不同计算机的系统环境不一样  ,通过指定编译参数  ,编译器就可以灵活适应环境 ,编译出各种环境都能运行的机器码  。这个确定编译参数的步骤 ,就叫做"配置"(configure)  。

              这些配置信息保存在一个配置文件之中 ,约定俗成是一个叫做configure的脚本文件  。通常它是由autoconf工具生成的  。编译器通过运行这个脚本  ,获知编译参数  。

              configure脚本已经尽量考虑到不同系统的差异 ,并且对各种编译参数给出了默认值  。如果用户的系统环境比较特别  ,或者有一些特定的需求  ,就需要手动向configure脚本提供编译参数  。

              $ ./configure --prefix=/www --with-mysql
              

              上面代码是php源码的一种编译配置  ,用户指定安装后的文件保存在www目录  ,并且编译时加入mysql模块的支持  。

              第二步 确定标准库和头文件的位置

              源码肯定会用到标准库函数(standard library)和头文件(header)  。它们可以存放在系统的任意目录中 ,编译器实际上没办法自动检测它们的位置  ,只有通过配置文件才能知道 。

              编译的第二步  ,就是从配置文件中知道标准库和头文件的位置  。一般来说  ,配置文件会给出一个清单  ,列出几个具体的目录  。等到编译时 ,编译器就按顺序到这几个目录中  ,寻找目标  。

              第三步 确定依赖关系

              对于大型项目来说  ,源码文件之间往往存在依赖关系 ,编译器需要确定编译的先后顺序 。假定A文件依赖于B文件  ,编译器应该保证做到下面两点 。