目录
[3. 汇编(生成机器可识别代码)](#3. 汇编(生成机器可识别代码))
[4. 连接(生成可执行文件或库文件)](#4. 连接(生成可执行文件或库文件))
[4.知识补充 软件的本质](#4.知识补充 软件的本质)
[5.知识补充 动态库和静态库](#5.知识补充 动态库和静态库)
一.linux编译器gcc/g++的使用
1.编译过程
-
预处理(进行宏替换)
-
编译(生成汇编)
-
汇编(生成机器可识别代码)
-
连接(生成可执行文件或库文件)
2.如何使用gcc
(gcc只能编译c语言代码,g++c语言和c++的代码都可以编译)
(由于gcc与g++的使用完全相同,这里只以gcc为例介绍)
gcc 【选项】 要编译的文件名 【选项】产生的新文件的名字
gcc test.c
gcc E test.c
gcc E test.c -o test.exe//具体选项后文介绍
3.gcc如何完成
1.预处理(进行宏替换)
//-E 为只激活预处理,这个不生成文件,需要把它重定向到一个输出文件里面,使用 -o,后缀使用.i
gcc -E test.c -o test.i
从现在开始,进行程序的翻译,将预处理工作做完就停下
a.去注释
b.头文件展开(就是把头文件的内容进行展开)
c.条件编译
d.宏替换
以下两张图分别是头文件展开,去注释和宏替换的效果图
这里是条件编译的效果
正常进行预处理
(知识点补充:这里可以不进入gcc就能够定义宏,我们可以理解为,gcc既然可以替换宏,进行头文件展开,那么它天然就是可以修改文件内容的)
知识补充
我们为什么可以在windows或者linux上进行c/c++或者其它形式的开发呢?因为我们的系统中装上了c/c++开发相关的头文件和库文件
2.编译(生成汇编)
在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
gcc -S test.i -o test.s
//从现在开始,进行程序的翻译,将编译工作做完就停下,后缀使用s
也可以直接
gcc -S test.c -o test.s
如下是生成的汇编
3. 汇编(生成机器可识别代码)
读者在此可使用选项"-c"就可看到汇编代码已转化为".o"的二进制目标代码了
gcc -c test.s -o test.o
//从现在开始进行程序的翻译,将汇编工作做完就停下,后缀使用o
也可以直接
gcc -c test.c -o test.o
我们使用od 文件名
来查看二进制内容的文件
.o指的是课重定位目标二进制文件,简称目标文件 即.obj文件
不可独立执行,需要经过链接才能执行
4. 连接(生成可执行文件或库文件)
gcc test.o -o mytest
将可重定位二进制文件和库进行链接形成可执行文件
可执行程序形成的时候,不是没有顺序地形成,它的二进制编码是有自己的格式的 --ELF格式
代码最终编译成功后我们可以./文件名来运行可执行程序,可执行程序默认被命名为a.out
二.知识补充 软件的本质
实质上头文件包含的是方法的声明,而方法的实现在库中,库其实就是把源文件(.c)进行一定的翻译,然后打包,只提供我们一个文件,不提供太多的源文件,而且也可以起到隐藏源文件的效果
也就是说
头文件提供的方法声明 + 库文件提供的方法的实现 + 我们的代码 = 软件
三.知识补充 动态库和静态库
在linux下, 以.so结尾的为动态库,以.a结尾的为静态库
库有自己的命名规则,例如libname.so.xxx,只有中间那一小部分才是库的名字
在我们的机器上,默认只会安装动态库,静态库默认是没有安装的
1>动态链接和静态链接
在编译器使用动态库进行动态链接的时候,会进行跳转,跳转到库中执行,再返回我们的代码调用处,动态库不能缺失,一旦对应的动态库缺失,影响的不止一个程序,可能导致很多程序都无法正常运行
而在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序中,该程序以后就不用再依赖静态库了
2>注意点
1.在linux中,编译形成可执行程序,默认采用动态链接-提供动态库
如果我们没有动态库,只有静态库,gcc还是能找到静态库进行静态链接的,-static的本质是改变调用库的优先级
2.在linux中,如果要按照静态链接的方式进行形成可执行程序,需要添加-static选项-提供静态库
3>安装静态库
sudo yum install -y glibc-static
4>动态库与静态库优缺点分析
动态库因为是共享库,可以有效节省资源,(磁盘空间,内存空间,网络空间等),动态库一旦缺失,会导致与它链接的各个程序都无法运行
对于静态库,程序在链接完成之后就不再依赖静态库,程序可以独立运行,但是体积比较大,比较消耗资源
四.知识补充debug与release发布模式
程序编译默认为release发布
我们可以使用
gcc test.c -o test_debug -g
使用-g来修改发布模式
我们可以在开发的时候把-g带上,debug可以被追踪调试,但是相对其大小会比release大一些
五.make与makefile
make是一条指令
makefile是一个当前目录下的文件
构建一个可以编译和清理项目的makefile文件
touch Makefile // 这屋里M大小写都可以
vim Makefile //进入文件
mytest.exe : mycode.c //依赖关系
gcc -o mytest.exe mycode.c //这行的开头要求是一个tab 这行称为依赖方法
.PHONY: clean
clean:
rm -f mytest.exe
make 编译
make clean 清理可执行文件