以下是C程序一般的编译过程:

gcc的编译流程分为四个步骤,分别为:
· 预处理(Pre-Processing)

  对C语言进行预处理,生成*.i文件。
· 编译(Compiling)

  将上一步生成的*.i文件编译生成汇编语言文件,后缀名为*.s
· 汇编(Assembling)

  将汇编语言文件*.s经过汇编,生成目标文件,后缀名为*.o
· 链接(Linking)

  将各个模块的*.o文件链接起来,生成最终的可执行文件

示例代码:

 //hello.c源代码

 #include<stdio.h>
int main()
{
printf("Hello World!\n");
return ;
}

1.预编

gcc -E hello.c -o hello.i

编译器对各种预处理指令(#include #define #ifdef 等#开始的代码行)进行处理,还要删除注释,添加行号和文件名标识。

预处理器(cpp)根据以字符#开头的命令(directives),修改原始的C程序。如hello.c中#include <stdio.h>指令告诉预处理器读系统头文件stdio.h的内容,并把它直接插入到程序文本中去。结果就得到另外一个C程序,通常是以.i作为文件扩展名的。

2.编译

gcc -S hello.i -o hello.s

编译过程是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件。。

3.汇编

gcc -c hello.s -o hello.o

汇编过程是编译器把汇编代码转换与计算机可认识的二进制文件。

4.链接

gcc hello.o -o hello

在这个源程序中并没有定义”printf”的函数实现,且在预编译中包含进的”stdio.h”中也只有该函数的声明,而没有定义函数的实现,因为系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径”/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数”printf” 了,而这也就是链接的作用。

函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。
(Linux下动态库文件的扩展名为".so"(Shared Object)。按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号)。这样,线程函数库被称作 libthread.so。静态库的文件名形式是libname.a。共享archive的文件名形式是libname.sa。共享archive只是一种过渡形式,帮助人们从静态库转变到动态库。)
完成了链接之后,gcc就可以生成可执行文件

GCC编译过程的更多相关文章

  1. Linux学习---GCC编译过程

    (一)GCC编译过程 预处理 cpp -o a.i a.c     //生成预处理文件 等同于[gcc -E] //预处理为将宏定义(#define)等进行替换. 编译 /user/lib/gcc/i ...

  2. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

  3. 1.GCC编译过程

    一. GCC编译过程 gcc -E hello.c -o hello.i // 预处理.将代码中包含的头文件和宏进行替换 gcc -S hello.i -o hello.s // 汇编.将当前文本转换 ...

  4. unix gcc编译过程

    gcc编译过程 现代编译器常见的编译过程: 源文件-->预处理-->编译/优化-->汇编-->链接-->可执行文件 对于gcc而言: 第一步 预处理       命令: ...

  5. gcc 编译过程

    gcc 编译过程从 hello.c 到 hello(或 a.out)文件, 必须历经 hello.i. hello.s. hello.o,最后才得到 hello(或a.out)文件,分别对应着预处理. ...

  6. Linux系统GCC常用命令和GCC编译过程描述

    前言: GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理 C语言.GCC 很快地扩展,变得可处理 C++.后来又 扩展能够支持更多编程语言,如Fortran. ...

  7. gcc编译过程简述

    在linux系统上,从源文件到目标文件的转化是由编译器完成的.以hello.c程序的编译为例,如下: dfcao@linux: gcc -o hello hello.c 在这里,gcc编译器读取源文件 ...

  8. system 系统调用、gcc编译过程

    system 库函数的功能是执行操作系统的命令或者运行指定的程序 #include <stdio.h> #include <stdlib.h>//引入库 int main() ...

  9. 和菜鸟一起学c之gcc编译过程及其常用编译选项【转】

    转自:http://blog.csdn.net/eastmoon502136/article/details/8162626 版权声明:本文为博主东月之神原创文章,未经博主允许不得转载. 上篇文章,知 ...

随机推荐

  1. Python环境配置安装

    2016年12月20日14:15:23 -------------- 参考菜鸟教程: Python 环境搭建 | 菜鸟教程  http://www.runoob.com/python/python-i ...

  2. 【总结】.Net面试题集锦 (二)

    一.前面的话 本文的面试题不是很难,这里只是想记录个人的思考过程,另一方面希望有更好的解决办法的大牛留下宝贵的思路,大家共同学习进步. 二.题目 思路:第一步:把一维数组的值和次数存入Dictiona ...

  3. Java中如何把一下字符串转换成map

    首先,你先确认你的字符串是否是json格式的,如果是json格式,那你可以使用Gson.jar或json-lib-xx-jdk.jar两个包来自动解析解析. 使用Gson更简单些,只需要导入一个包就可 ...

  4. svn提交时提示 Aborting commit: remains in conflict 解决办法

    出现在rename一个目录时,再提交时一直报错 Aborting commit: remains in conflict 使用右键菜单 svn - resolve 即可解决.用cleanup之类的都没 ...

  5. vim删除以#,空格开头的行

    1,删除以#号开头的行: :g/^#/d :%s/^#.*\n 2,删除以空格开头的行: :g/^\s/d                “\s代表空格” :%s/^\s.*\n 3,删除以空格#开头 ...

  6. Java中接口的实现问题

    1.Java 接口的访问权限 interface A{}//接口A包访问权限 public interface A{}//接口A公有访问 interface A{ void function1(): ...

  7. View绘制机制

    View 绘制机制 1. View 树的绘图流程 当 Activity 接收到焦点的时候,它会被请求绘制布局,该请求由 Android framework 处理.绘制是从根节点开始,对布局树进行 me ...

  8. asp.net MVC4 表单 - CheckBox兴趣爱好

    1.Model层定义属性 public class vmUser { public string userName { get; set; } public string sex { get; set ...

  9. [译]IIS 8.0应用初始化

    原文 代码 或者点这 通过IIS 8.0应用初始化特性管理员可以配置IIS为一个网站或多个网站提前执行初始化任务.当应用在初始化期间,可以通过配置先返回一个静态页面知道应用的初始化任务完成. 通过配置 ...

  10. [Algorithm & NLP] 文本深度表示模型——word2vec&doc2vec词向量模型

    深度学习掀开了机器学习的新篇章,目前深度学习应用于图像和语音已经产生了突破性的研究进展.深度学习一直被人们推崇为一种类似于人脑结构的人工智能算法,那为什么深度学习在语义分析领域仍然没有实质性的进展呢? ...