<>1. gcc的安装
<>2. 分步编译连接
C语言的编译过程:
一个C语言程序,需要经过预处理、编译、汇编、链接,才能得到可执行程序
gcc提供分布编译链接,分别为:
* 预处理: gcc -E main.c -o main.i
* 编译: gcc -S main.i -o main.s
* 汇编: gcc -c main.s -o main.o
* 链接: gcc main.o -o main
* 也可以单步执行直接预处理编译汇编链接成功,执行下面这条语句: gcc -o main main.c gcc main.c
最后生成的main为可执行程序,如果没有错误的情况下,直接运行此文件即可
下面对这一过程进行演示:
*
写了一个main.c
*
预处理
*
编译、汇编、链接
*
运行main程序
*
一步预处理编译汇编链接
<>3. 编译链接过程
<>3.1 预编译阶段
* 删除所有的“#define”,并且展开所有的宏定义,即将宏定义展开,换掉程序中宏的值;
* 处理所有的条件预编译指令,“#if”、“#ifdef”、“#endif”等;
* 处理“#include”预编译指令,将被包含的库文件插入到文件中;
* 删除所有的程序注释;
* 添加行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错误和警告时显示行号;
* 保留所有的#pragma 编译器指令,因为编译器需要使用它们。
<>3.2 编译阶段
词法分析、语法分析、语义分析,代码优化,汇总符号。
<>3.3 汇编阶段
将汇编指令翻译成二进制格式,生成各个 section,生成符号表
<>3.4 链接过程
* 合并各个 section,调整 section 的起始位移和段大小,合并符号表,进行符号解析,给符号分配虚拟地址
* 符号重定位
上面这种编译过程,在单个文件的时候不会特别麻烦,但是如果有多个C语言文件需要编译的时候,就显得十分麻烦,我们发现在windows系统中,执行C语言程序,我们看不到各个单个的过程,只需要点击一下执行按钮即可执行,其实windows的一些编译器,自动为我们写好了一键执行文件,当我们点击执行按钮的时候,调用这个执行文件,自动执行编译等过程,在Linux中,其实我们也可以进行这种操作,我们可以按照下面这个过程创建一个文件,通过在文件中加入一些语句,来实现对于多个文件的编译等过程。
<>4. makefile和make
管理工程、实现自动化编译,如下:
*
写一个add.h
*
写一个add.c
*
写一个max.h
*
写一个max.c
*
写一个main.c
*
按照传统的编译
*
使用makefile来实现
这里面如果make没有安装,则会提示按照什么命令进行安装,照着提示命令安装就行了
<>5. gdb调试
<>5.1 Debug和Release
* Debug
Debug版本往往被称作可调式版本,生成的可执行文件中包含调试需要的信息,作为开发人员,最常用的就是debug版本的可执行文件
因为调试信息是在编译的时候加入到中间文件.o中的,所以必须在编译时候控制其生成包含调试信息的中间文件
执行下面这条语句,即可获取中间文件: gcc -o hello hello.c -g
* Release
发行版本,提供给用户使用的版本,通过gcc默认生成的就是Release版本
对于C语言的调试过程,首先通过将源代码编译、连接生成Debug版本的可执行文件,然后通过
gdb Debug版本的可执行文件名
进入调试模式
<>5.2 单进程、单线程基础调试命令
* 首先写一个test.c文件,我们来执行一些常见的gdb调试信息,代码如下:
从上面我们可以看出一些常用的指令,比如: b 行号 //给行号加断点 b 函数名 //给函数的第一行的地方加一个断点 info break
//显示断点的信息 l //显示源代码 按一下生成一段代码,会接着上面现实的继续显示 r //运行程序 n //单步执行程序 s
//进入即将被调用的函数中执行 finish //跳出函数 q //退出调试 p val
//打印变量的值,注意这里面的val可以是地址,也可以是表达式,也可以是数组的所有元素 c //继续执行