gcc编译器:
将高级语言代码编译成为机器可识别的指令代码
编译文件
编译步骤:
1.预处理,展开所有代码 gcc-E只预处理 -o 指定修改后的文件名称
2.编译:纠错,没有错误则将c语言代码编译为汇编代码 gcc -S只进行编译工作
3.汇编:将汇编代码编译为机器指令代码 gcc -c
走完汇编只是将当前的.c编译成了自己的机器指令代码
其他的函数还没有拿过来,这个文件虽然是机器指令代码,但是不能执行
4.链接:将所有调用的代码实现都拿过来生成可执行程序
库:存放实现函数代码的地方
动态库:
生成可执行程序,链接动态库,称为动态链接
文件格式 lib***.so
代码冗余量小,占用资源小,对库的依赖程度高
静态库:
生成可执行程序,链接静态库,称为静态链接
文件格式 lib***.a
直接将库文件中的代码拷贝到可执行程序中,代码冗余量高,对库的依赖程度低
(windows 下 动态.dll,静态库.lib)
gcc编译器默认链接方式是动态链接
gcc -static 链接方式指定为静态链接
Makefile
就是一个文本文件,但是有一个make命令,逐步执行makefile中记录的编译规则
makefile用于记录项目的编译规则,辅助项目的自动化编译
命名:M/makefile
#注释以#开头
#Makefile编写规则
目标对象 不一定要生成,而是为了让make能够找到依赖关系
依赖对象 主要用于判断目标对象是否是最新的
目标对象:依赖对象
[tab]为了生成目标对象所执行的命令
预定义变量
$@ 指目标对象
$^ 指所有依赖对象
$< 所有依赖对象中的第一个
wildcard 获取文件名
$()将括号中的字符串当作命令处理
命令的执行结果当作变量内容赋值给别的变量
SRC=$(wildcard./*.c)
main:$(SRC)
gcc -o $@ $^
makefile只为了生成第一个目标对象而存在,假如目标对象已经存在,make会判断依赖对象和目标对象的时间,判断目标对象是否是最新的,如果是最新的,则不需要编译,直接退出,不是最新的则重新生成
但是makefile这个特性导致只生成一个程序,因此后边如果还有目标对象要生成,是不会生成的
Makefile有个其他的特性:如果依赖对象不存在,则会在makefile中查找依赖关系,看能不能生成这个依赖对象,如果有有则生成,没有则报错退出
.PHONY --声明伪对象
伪对象:不管是不是最新的,反正每次都要重新生成
执行:make程序到当前工作目录下找makefile文件,解释执行
1.到当前目录下查找makefile文件,找不到报错
2.在文件中找第一个目标对象,并把这个对象当作终极目标
3.检测这个目标对象和依赖对象的最后一次修改时间,判断是否需要
重新编译,如果需要修改时间一样则不需要重新编译,退出
4.如果目标对象不存在,则直接生成,但是依赖对象有可能不存在
5.为了生成终极目标,首先要保证依赖对象都存在,所以会先去生成所有
依赖对象(依赖对象的生成的依赖关系也是用户在下边定义的)
声明伪对象:.PHONY
伪对象:每次都需要重新生成
假如当前目录下有多个makefile时(makefile/Makefile),优先执行makefile
但是make只能执行一个
预定义变量:$@ $^ $<
= 非即时赋值
:= 即时赋值
?= 变量有值则不重新赋值
+= 追加
四种赋值方式区别