前言:没接触Linux下编译之前,觉得很神秘,特别是makefile,一个简单的make命令就能编译一个大型项目生成一个可执行文件,接下来跟大家分享下学习的makefile的知识。
目录:
1.makefile简介
2.makefile规则
3.makefile隐晦规则
4.makefile伪目标
5.makefile变量
6.makefile条件控制语句
7.makefile文件引用
8.makefile函数
9.makefile注释,换行,-f
10.makefile动手实践
1.makefile简介
首先,我们通常使用的make都是gnu make,也就是一种解析makefile的make工具,关于gnu和Linux还有一段不为人知的故事,大家可以自己查下。makefile就是一个文档,make工具通过解析这个文档,把一个个.c .cpp文件通过gcc/g++命令编译成.o(临时文件 Object file),再通过gcc/g++命令编译成一个二进制的可执行文件,也可以将.o文件链接成一个.a(静态链接库,Windows下为.lib)。
2.makefile规则
makefile接触最多的一个词就是目标,它可以是一个可执行文件,.o,伪目标。makefile编译就是把最终生成的可执行文件这个目标,依赖其他的目标,一层层依赖,最终依赖到.c,.cpp文件。另外,make编译的时候当发现目标所依赖的目标发生变化的时候,才会重新编译,节省了编译时间。makefile目标依赖如下,此处很关键:
target : prerequisites
command
...
**提示:cmmand前面是一个tab
示例:
main : main.o
cc -o edit main.o
main.o : main.c main.h
cc -c main.c
3.makefile隐晦规则
#原文件
main : main.o
cc -o edit main.o
main.o : main.c main.h
cc -c main.c
#变一下
main : main.o
cc -o edit main.o
main.o : main.c main.h
#再变一下
main : main.o
cc -o edit main.o
main.o : main.h
#隐晦规则:编译工具gcc会自动搜索main.o同目录的同名.c文件,即main.c,即自动推导。
当然还有很多其他的隐晦规则,就不一一列举。
4.makefile伪目标
常见伪目标all,clean..这些伪目标不会生成文件,主要是为了执行一些命令。
.PHONY : clean
clean :
rm -f *.o
** .PHONY是为了避免一种情形,当前目录下已存在名为clean的文件,在执行clean这个目标的时候,发现已存在clean文件,并clean什么也没有,make工具会认为此目标所依赖的目标没有发生更新,就不会重新编译这个目标,也就不会执行下面的rm命令。
5.makefile变量
makefile中的变量没有类型。通常用来定义一个目录或一些目标。
b = main.o head.o
a = $(b)
$(a)是对变量a的调用。
a := $(b)
:=是另一种用法,区别是:=后面只能调用前面已经定义过的变量。避免产生循环调用。
6.makefile控制语句
if .../ifeq...
...
else
...
endif
foreach
...
7.makefile文件引用
#文件引用前面没有"#"
include "build.mk"
8.makefile函数
我们可以使用使用make提供的函数,也可以自己定义函数,也可以叫命令包。
define fun
command
endef
调用函数:$(fun ...)
9.makefile注释,换行,-f
#此处注释,同shell注释#开头
/ 此处换行,也可以作为多行注释,所以此处也是注释,哈哈哈~
make命令执行默认会去执行当前目录下的makefile或者Makefile文件,或者可以用 -f、 --file 指定执行的makefile文件。make命令后面可以跟想要执行的目标,不然默认执行makefile开头的第一个目标。
make -f build.mk
10.makefile动手实践
说的再多不如动手实践,能力的获得%70来自实践。
赶紧动手写起来吧!
最后,makefile后面进阶,则需要多写makefile,想写出简洁可维护的makefile,还是挺难的,也可以深入了解下make工具的执行原理,以及gcc/g++的编译原理。推荐学习下大神陈皓的《跟我一起写 Makefile》。