为什么要学这个?
-
在学习初期,我们可能代码文件不多,又或者我们有IDE可以简单方便地进行编译操作
-
假如项目大了,源文件多了,且又是在linux环境下,这就使得我们的编译会变得非常麻烦
-
文件太多每一个文件都要写语句
-
修改少部分文件后也需要对整个项目进行编译,非常浪费时间和资源
-
-
所以就发明了make工具,但是巧妇难为无米之炊,make工具并不是这么智能地直接给你编译,而是你需要告诉他怎么做,也就是需要给他一个说明文档,这就是我们要学习的Makefile
-
Makefile是一个脚本语言
c/cpp编译过程
预处理 gcc -E hello.c -o helle.i 编译 gcc -S hello.i -o hello.s 汇编 gcc -c hello.s -o hello.o 链接 gcc hello.o -o hello
网上的简单记法:ESC对应ISO
写一个最简单的Makefile
hello:hello.c gcc hello.c -o hello .PHONY: clean: rm -rf hello
-
解释一下上面的脚本文件
-
格式为
-
目标文件:依赖文件
-
命令
-
.PHONY代表着接下来的是伪目标文件,在使用make命令时需要带上自定义的参数,例如这里的clean,就会执行下面的命令(也可以不写.PHONY)
注意
Makefile的书写规则有两个部分,一个是依赖关系(包括目标文件和依赖文件),一个是生成目标的方法(也就是命令)。
在Makefile中,规则的顺序很重要,因为Makefile中只应该有一个最终目标(也就是最后的那个可执行文件),其他的目标都是被这个目标所带出来的,所以一定要让make命令知道你的最终目标是什么。一般来说定义在Makefile中的目标可能有很多,但是第一条规则中的目标将会被确立为最终目标。如果第一条规则中的目标有很多个(还没见过这种情况),那么,默认第一个目标会成为最终的目标,make所完成的也就是这个目标 ———————————————— 原文链接:Makefile 书写规则_猪哥-嵌入式的博客-CSDN博客
写完Makefile以后呢?
-
在相同目录下,我们需要在命令行中使用make命令,make命令会自动查询Makefile文件,并在命令行中执行指定的命令
-
注意,Makefile文件没有后缀,文件名直接就叫Makefile,且M最好大写(现在makefile应该也可以被make命令找到)
引入变量
TAR=hello #变量赋值 TAR+=.c #追加操作 CC:=gcc #恒等操作 #以上这些类似于C语言中的宏定义
-
引入变量后,我们就可以在下面的命令中进行替换,这样做后就会生成一个类似于模板的东西,我们只需要修改变量的值即可
-
我们对上面的Makefile文件做一个变量替换
TAR=hello SRC=hello.c CC:=gcc $(TAR):$(SRC) $(CC) $(SRC) -o $(TAR) .PHONY: clean: rm -rf $(TAR)
-
变量替换需要使用$()
更简单点
-
前面我们写的例子中.c文件不多,如果有超多的.c文件,我们又需要一个一个文件名去编译生成多个.o文件,然后最后链接在一起
-
这时候我们就需要隐含规则,我们使用类似于通配符的东西来对文件进行匹配
%.c/o代表任意c源文件或目标文件
%.o代表任意目标文件
*.c代表所有.c源文件
*.o代表所有.o目标文件
假如没有这个通配符的话,那么对于有多个c源文件时,我们需要这么写
test:test1.o test2.o test3.0 test4.o g++ test1.o test2.o test3.0 test4.o -o test test1.o:test1.cpp g++ -c test1.cpp -o test1.o test2.o:test2.cpp g++ -c test2.cpp -o test2.o test3.o:test3.cpp g++ -c test3.cpp -o test3.o test2.o:test4.cpp g++ -c test4.cpp -o test4.o
而假如引入了通配符之后,我们只需要将其改写成这个样子
test:*.o g++ *.o -o test %.o:%.cpp g++ -c %.cpp -o %.o
这里无论多少条,哪怕到test1000,都可以利用这一句话完成