本文主要介绍Linux操作系统中make及makefile的相关知识。
1 What
make是一个在软件开发过程中所使用的工具程序(utility software),通过读取“makefile”文件以实现自动化建构软件。
make是一种转化文件形式的工具,转换生成的目标称为“target”。同时,make也检查文件之间的依赖关系,如果需要的话,它会调用一些外部软件来完成任务。make的依赖关系检查系统非常简单,主要根据依赖文件的修改时间进行判断。make使用“makefile”文件来确定一个target文件的依赖关系,然后把生成这个target文件的相关命令传给shell去执行。
大多数情况下,make被用来编译源代码,生成结果代码,然后把结果代码连接起来生成可执行文件(execute)或者库文件(library)。
许多现代软件开发的集成开发环境(如Microsoft Visual Studio)已经取代make,但是在(类)Unix环境中,仍然有许多工程师采用make来协助软件开发。
2 makefile中的常见用法
本章介绍在编写makefile过程中经常用到的函数、命令。
2.1 函数
makefile里的函数是以一个“$”符号开始,后接一个括号“()”,括号中是函数名和需要的参数列表,多个参数用逗号隔开,示例样式如下:
return = $(funcname arg1,arg2,arg3...)
2.2 wildcard函数
wildcard函数用于搜索指定目录下的文件,生成并返回一个以空格间隔的文件名列表。
示例用法如下:
SRC = $(wildcard ./foo/*.cpp)
上述用法的作用是搜索当前目录下“foo”文件夹下的所有以“.cpp”结尾的文件,搜索到的文件信息将以空格间隔生成文件名列表,并将该文件名列表返回给变量SRC。
2.3 notdir函数
notdir函数用于去掉文件信息中的目录信息,此函数经常和wildcard函数一起使用。
示例用法如下:
SRC = $(notdir $(wildcard ./foo/*.cpp))
上述用法用于去掉wildcard函数搜索结果中文件信息中的目录信息。
2.4 patsubst函数
patsubst(pattern substitute)函数用于进行文件信息替换。
示例用法如下:
OBJ = $(patsubst %.c %.o $(SRC))
上述用法会将SRC所含文件中所有“.c”结尾的文件替换为以“.o”结尾的对应文件。
3 make命令的常见用法
3.1 同时开始多个编译任务(并行编译)
在使用make命令构建项目时,可以通过“-j”选项同时开始多个编译任务。
“-j”选项的作用描述如下:
-j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg.
示例命令如下:
make -j4
运行上述命令构建项目时,可同时启动4个编译任务,因此减少了项目构建所需时间。
在使用“-j”选项构建项目时,有以下几点需要注意:
- 对于同时开始的编译任务数,需要根据构建机器的实际情况而定。为了不影响机器其他业务正常运行,通常将并发任务数设置为机器的CPU个数即可,例如某机器的CPU数量为4,则可将该选项设置为“-j4”。而并发编译任务数最大一般可设置为机器CPU数量的2倍。机器的CPU数量可通过命令“cat /proc/stat | grep cpu[0-9] -c”查看;
- 如果项目的Makefile编写不规范,没有正确地设置好各模块之间的依赖关系,那么使用“-j”选项进行并行编译可能会导致构建操作不能正常进行。