汉扬编程 编程大纲 GCC编译C语言程序的全过程

GCC编译C语言程序的全过程

GCC编译C语言程序的全过程

接上文:用gcc编译C代码示例

GCC编译C语言程序的全过程

使用GCC将C语言源代码文件生成可执行文件的过程,需要经历四个的步骤:

GCC编译C语言程序的全过程

预处理(Preprocessing)编译(Compilation)汇编(Assembly)链接(Linking)

1、预处理(Preprocessing)将C源程序预处理,生成.i文件。

预处理过程实质上是处理“#”,将#include包含的头文件直接拷贝到.c当中;将#define定义的宏进行替换;将#if #else #endif定义的无用代码过滤掉,同时将代码中没用的注释部分删除等。

预处理所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。

2、编译(Compilation)预处理后的.i文件编译为汇编语言,生成.s文件。

编译所要作的工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。

3、汇编(Assembly)将.s文件经过汇编,生成.o目标文件。

汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。

目标文件由段组成。通常一个目标文件中至少有两个段:

代码段:该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。4、链接(Linking)将.o文件链接起来生成一个可执行文件。

链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。

根据库函数不同的链接方式,链接处理可分为静态链接和动态链接两种。使用静态链接的好处是,依赖的动态链接库较少,具有较好的兼容性;缺点是生成的程序比较大。使用动态链接的好处是,生成的程序比较小,占用较少的内存。

C语言中静态库和动态库简介

需要注意的是,.i文件、.s文件、.o文件可以认为是中间文件或临时文件,若使用 GCC 一次性完成C语言程序的编译,那么只能看到最终的可执行文件,这些中间文件都是看不到的,因为 GCC 已经将它们删除了。

C语言静态库的制作与使用

GCC编译C语言程序的全过程

静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。

静态库在程序开发工作中,经常会遇到我们的程序需要链接外部库的做法。

比如想要在我们的C工程中调用SQLite数据库的相关接口进行数据库操作,那么我们首先需要做的事情是获取SQLite的源码,然后将SQLite源码编译成静态库libsqlite.a,最终我们在程序中包含SQLite的头文件并调用相关接口,并且在编译的时候链接libsqlite.a静态库。

最终生成的可执行文件就会包含我们自己写的程序和SQLite数据库功能。

静态库可以理解成程序的集合,包含了常用的公共代码部分(glibc)或者实现了专用的功能(SQLite)。这样我们在编写程序时就不需要重复实现相关的功能,直接包含头文件并连接需要的库即可。大大减少了我们编码的工作量。

静态库的制作本节看一下如何制作一个静态库。

这里我们实现一个公共的加法操作函数tadd(int a, int b);首先实现tadd()函数及其头文件tadd.h:

// tadd.cint tadd(int a, int b){ return ((a) + (b));}// tadd.h#ifndef __TADD_H__#define __TADD_H__int tadd(int a, int b);#endif将tadd.c编译为目标文件:

$ gcc -c tadd.c -o tadd.o这里只是将tadd.c编译为tadd.o,gcc 的 -c 选项指的是对于源文件只编译但是不进行连接。所以tadd.o只是一个编译好的二进制目标文件,并不是链接好的可执行文件。

接下来我们将会使用这个编译好的目标文件,将该文件打包为静态库。

$ ar rcs libtadd.a tadd.oar工具可以将目标文件打包成静态库,ar打包之后的文件就可以在程序中进行链接使用。

测试现在我们写一个测试代码对刚才生产的静态库进行测试:

// prog.c#include <stdio.h>#include "tadd.h"int main(){ int a = 122; int b = 8; int c = tadd(a, b); printf("a + b = %d\\n", c); return 0;}编译方法:

$ gcc prog.c -o prog -L./ -ltaddprog.c是测试的C文件,会在该文件中调用tadd()函数,-L参数表示需要链接的静态库文件的路径,-ltadd参数表示需要链接libtadd.a静态库。

这里我们把libtadd.a和tadd.h两个文件放在和prog.c的同级目录。

执行结果:

$ a + b = 130

本文来自网络,不代表汉扬编程立场,转载请注明出处:http://www.hyzlch.com/mianfei/6764.html

MATHCAD+如何设置断?

C++基础部分_C++文件操作_二进制文件的读操作

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部