Makefile 功能
Makefile 可以使项目实现自动化编译,不用每次都输入指定的源文件和参数。
一个 Makefile 包含描述了整个工程的编译和链接等规则。
Makefile 优势
1、 编译需要链接库、确定编译顺序
若用C语言的单纯命令进行编译,编译的命令如下所示:
gcc -o outfile temp.c temp1.c ...
gcc 只会默认链接一些基本的C语言标准库,很多源文件依赖的标准库都需要我们手动链接。
例如
temp.c 用到了数学计算库 math 中的函数,需手动添加参数 -Im。
temp1.c 使用到了线程,需手动添加参数 -lpthread。
这种利用单纯命令进行文件编译另外还要考虑文件链接的顺序。这将会造成命令很长,这样每次进行编译会很麻烦
Makefile 能够大大简化编译过程。
第一次编译只需把要链接的库文件放在 Makefile 中,制定相应的规则和对应的链接顺序。以后编译只需要执行 make 命令,工程就可以自动编译。
2、编译大的工程会花费很长的时间
一个大的项目进行单线程编译所耗费的时间是很长的,但是若采用Makefile对文件进行编译则会大大减少编译所花费的时间。
Makefile 支持可多线程并发操作,每次发起 make 命令只会编译我们修改过的文件,没有修改的文件不用重新编译,极大的缩短了编译所需耗费时间。
简单 Makefile 举例
1、使用 Makefile 的步骤
①、编写好 Makefile 文件 ②、在 shell 中执行 make 命令 ③、make 会去当前文件下找要执行的 Makefile 文件
通过上述3个步骤程序就会自动执行,得到最终的目标文件
2、在 Makefile 文件添加如下代码,实现编译 test.c 文件
test:test.c
gcc -o test test.c
test 是目标文件、最终编译生成的可执行文件
test.c 是依赖文件
gcc -o test test.c 是重建目标文件需要执行的操作
Makefile 的主要内容
1、显式规则
在 Makefile 中指出目标文件、依赖文件、生成命令。
2、隐晦规则
在 Makefile 中简略地填写信息。
3、变量的定义
在 Makefile 中定义一系列的变量,变量一般为字符串。
当 Makefile 被执行时,其中变量都会被扩展到相应的引用位置上。
4、文件指示
包含三个部分:
①、一个 Makefile 中引用另一个 Makefile。类似 C 语言中的 include。
②、根据某些情况指定 Makefile 中的有效部分。类似 C 语言中的预编译 #if。
③、定义一个多行的命令。
5、注释
Makefile 中只有行注释,和 Shell 脚本一样,其注释是用 ‘#’ 字符。
Makefile 的工作流程
1、创建一个包含有多个源文件和 Makefile 的目录文件,源文件之间相互关联
例子:Makefile 代码
main:main.o test1.o test2.o
gcc main.o test1.o test2.o -o main
main.o:main.c test.h
gcc -c main.c -o main.o
test1.o:test1.c test.h
gcc -c test1.c -o test1.o
test2.o:test2.c test.h
gcc -c test2.c -o test2.o
2、执行 make 命令
make 读取当前目录下的 Makefile 文件,并将 Makefile 文件的第一个依赖关系作为其执行的最终目标。
在例子中第一个规则就是目标 “main” 所在的规则。该规则描述了 “main” 的依赖关系,并定义了链接 ***.o 文件生成目标 “main” 的命令。make 在执行最终目标 “main” 的命令之前,先处理目标 “main” 的所有的依赖文件(.o)的更新规则。
各规则之间的关系
对 “.o” 文件为目标的规则处理有下列三种情况:
①、目标 “.o” 文件不存在,使用其描述规则创建它;
②、目标 “.o” 文件存在,目标 “.o” 文件所依赖的 “.c”、“.h” 文件中的有修改过,则根据规则重新编译
③、目标 “.o” 文件存在,目标 “.o” 文件所依赖的 “.c”、“.h” 文件中的未修改过,则不进行编译
“.o” 文件作为编译过程中的中间文件,作用是检查某个源文件是不是进行过修改,减少最终目标文件的重建过程的工作量。
3、清除工作目录中的过程文件
在 Makefile 文件的末尾添加语句
.PHONY:clean
clean:
rm -rf *.o test
在完成编译任务后可通过 “make clean” 命令清除编译过程中生成的中间文件和最终目标文件。