目录
第二步:编写makefile文件,管理工程,实现自动化编译(.o)
Linux中文件编译运行过程介绍:
程序的编译链接过程
要想清楚程序的编译链接过程,前提你知道什么是可执行文件吗?
文件是一个外存的概念,文件只存在于“外存”(硬盘,u盘,网盘)中,文件由两部分构成,文件名和文件主体。文件的分类:可执行文件、不可执行文件
可执行文件:在Windows操作系统中,扩展名为:*.exe,*bat等的文件是可执行文件,可执行文件由指令和数据构成。Linux是靠文件属性来判断是否可执行。
不可执行文件:其内容是由数据构成。
(图为借鉴)
预编译阶段:
a) 删除所有的“#define”,并且展开所有的宏定义;
b) 处理所有的条件预编译指令,“#if”、“#ifdef”、“#endif”等;
c) 处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置;
d) 删除所有的注释;
e) 添加行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错误和警告时显示行号;
f) 保留所有的#pragma 编译器指令,因为编译器需要使用它们。
编译阶段:
词法分析、语法分析、语义分析,代码优化,汇总符号。
汇编阶段:
将汇编指令翻译成二进制格式,生成各个 section,生成符号表
链接阶段:
a) 合并各个 section,调整 section 的起始位移和段大小,合并符号 表,进行符号解析,给符号分配虚拟地址
b) 符号重定位
Linux系统上C程序的编译过程
例如我们在这里写一个简单的helloworld程序,我们通过命令来对文件编译连接的过程进行演示和分析
第一步:创建一个普通文件test1103.c,并使用vim编辑器对它进行编辑,写下“你好”程序的C代码:
第二步:对test1103.c进行预编译操作,输入命令:
gcc -E test1103.c -o test1103.i
如图,生成了一个test1103.i文件,我们通过vim编辑器对这个文件进行查看:
如图,是一些路径和一些C语言。
第三步:对test1026.i文件进行编译操作,输入命令:
gcc -S test1103.i -o test1103.s
如图,生成了一个名为test1103.s的文件,按照上面对文件类型的介绍,这个文件中应该是将C语言翻译过后的汇编语言,我们通过vim编辑器对这个文件进行查看:
如图红圈所示就是C语言翻译完之后的汇编代码。
第四步:对test1026.s文件进行汇编操作,输入命令:
gcc -c test1103.s -o test1103.o
如图,出现了一个test1103.o的文件,我们通过vim编辑器对这个文件的内容进行查看:
这就是二进制格式的.o文件内容,可以发现,这时的文件内容大致已经变成了机器码。
第五步:对test1026.0文件进行链接操作,输入命令:
gcc test1103.o -o main
如图生成了一个名为test1103的文件:
这个test1103,就应该是按照步骤走的最终的可执行文件了,我们通过./命令,来执行当前目录下的test1103,检验一下它是否真的可执行,输入命令:
./test1103
如图程序执行成功
Linux中,如果我们已经使用vim编辑器写好了程序,其实只需要一步就可以生成可执行程序,我们拿上面的文件举例子,只需要在编写好test1026.c这个文本文件后输入命令:
gcc -o test1103 test1103.c
这条命令可以直接输出最终的可执行文件。
Linux头文件与源文件之间的关系:
在之前的学习中,头文件分为系统头文件和自己编译的头文件,比如#include<stdio.h>是系统自带的头文件。
当我们写一个项目时,我们通常要讲个待实现的函数在头文件(.h)中进行声明,然后将头文件中声明的函数功能在对应的源文件(.cpp)中进行实现:
例如我们在Linux中进行文件编译时,就在头文件中进行函数的声明,再源文件中进行函数功能的具体实现,在这里我们写一个简单的两数相乘的函数在头文件中并在源文件中进行引用
头文件中的函数声明:
源文件中对头文件的引用:
编辑运行,输入命令
gcc -o main main.c
运行结果:
编译成功且程序成功运行
Make命令及makefile文件的编写(工程文件管理):
我们通过vim编写一个加法函数和一个乘法函数并且要在main.c文件中对这两个函数进行调用。
第一步:编写add函数(add.c)
编写mul.c
在main.c程序中对add和mul函数进行调用:
第二步:编写makefile文件,管理工程,实现自动化编译(.o)
创建makefile文件,输入命令
touch makefile
使用vim编辑器对makefile文件进行编辑,输入指令:
1 all:main
2
3 main:add.o mul.o main.o
4 gcc -o main add.o mul.o main.o
5
6 add.o:add.c
7 gcc -c add.c
8 mul.o:mul.c
9 gcc -c mul.c
10 main.o:main.c
11 gcc -c main.c
12 clean:
13 rm -rf *.o main
如下所示:
保存退出后,使用make命令
结果为:
GDB调试器
GDB安装命令:sudo apt install gdb
单进程、单线程基础调试命令