编译过程的那些事儿

来源:互联网 发布:电商公司数据分析 编辑:程序博客网 时间:2024/05/19 02:43
预编译
首先是源代码文件hello.c和相关的头文件,如stdio.h等被编译器cpp预编译成一个.i文件。对于C++程序员来说,它的源代码文件的扩展名可能是.cpp或.cxx,头文件的扩展名可能是.hpp,而预编译后的文件扩展名是.ii。第一步预编译的过程相当于如下命令(-E表示只能进行预编译):
$gcc -E hello.c -o hello.i

预编译过程主要处理那些源代码文件的以“#”开始的预编译指令。比如“#include”、“#define”等,主要处理规则如下:

将所有的“#define”删除,并且展开说有的宏定义。
处理所有条件预编译指令,比如“#if”、“#ifdef”、“#elif”、“#else”、“#endif”。
处理“include”预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件可能还包含其他文件。
删除所有的注释“//”和“/**/”。
添加行号和文件名标识,比如#2“hello.c”,2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。
保留所有的#pragma编译器指令,因为编译器须要使用它们。
经过编译后的.i文件不包含任何宏定义,因为所有的宏已经被展开,并且包含的文件也已经被插入到.i文件中。所以我们无法判断宏定义是否正确时,可以查看预编译后的文件来确定问题。

$gcc -S hello.i -o hello.s 产生汇编代码

现代版本的GCC把预编译和编译两个步骤合并成一个步骤,使用一个叫做ccl程序来完成这两个步骤。这个程序位于“/usr/lib/gcc/i486-linux-gun/4.1/”,我们可以直接调用ccl来完成它
或者使用命令
$gcc -S hello.c -o hello.s

对于C语言的代码来说,这个预编译的程序ccl,对于C++来说,有对应的程序叫做cclplus;Objective-C是cclobj;fortran是f771;java是jc1。所以实际上gcc这个命令只是这些后台程序的包装,它会根据不同的参数要求去调用预编译编译程序cc1、汇编器as、连接器ld。

汇编

$as hello.s -o hello.o
$gcc -c hello.s -o hello.o
$gcc -c hello.c -o hello.o

链接
链接比较复杂
0 0
原创粉丝点击