Makefile运行

Makefile运行最简单的方法就是输入make命令后执行,这样子make命令会去找寻Makefile文件中第一个目标,然后寻找此目标的依赖文件,找寻依赖文件的依赖文件,然后递归去寻找依赖文件的依赖文件的依赖文件,比对其更新时间,如果对应目标所依赖文件更新时间在目标文件之前,就会执行对应目标之下的命令,以编译出最新的目标文件,这是一个递归的过程,所需细节需要自己慢慢去体会,这里反正我已经理解了,就不做过多解释。嘿嘿!
当然有时候make命令不一定要编译文件中第一个目标,可以依据参数来指定某个目标,或者传入对应参数,执行make的不同功能,此章节就是要讲述Makefile运行的细节。

make的退出码

make命令执行后有三个退出码:

  • 0:执行成功
  • 1:如果make命令运行出现错误,返回1
  • 2:如果make命令带有-q选项,使得一些目标不需要更新,返回2(后边会详细介绍)

指定Makefile

GNU make命令会依次寻找当前目录下边的“GNUmakefile” “makefile” “Makefile”文件,一旦找到,就开始读取这个文件并执行。
当然,我们也可以给make命令指定一个特殊名字的文件,让其去执行,想要达到这个目的,就需要用到make的-f参数或者是-=file命令,后边加上文件名,让其去读取运行。
如果make命令不只一次使用了-f参数,那么所指定的makefile会被连在一起传递给make命令去执行。

指定目标

一般来说,make命令执行的目标就是指定文件中的第一个目标,其他目标都是由第一个目标的依赖文件推导出来的,当然我们也可以给make命令执行目标,只需要在make命令后加上指定目标即可。理论上任何目标都可以被指定成最终目标,除非是“-”打头或者是包含了“=”的目标,前者会被认为是命令行参数,后者会被认为是变量。甚至在make命令执行文件中没有被我们明显指定的目标,也可以成为最终目标,此时就依赖于make命令的隐含规则推导规则,隐含目标同样可以被指定成终极目标。
make有一个环境变量叫”MAKECMDGOALS”,这个变量中存放了所指定的终极目标,如果使用make命令时没有指定任何目标,那么这个变量会是空值。
示例:

1
2
3
4
5
6
target:
@echo MAKECMDGOALS=$(MAKECMDGOALS)

.PHONY:app
app:
@echo MAKECMDGOALS=$(MAKECMDGOALS)

使用最普通的make命令不带任何参数,会执行第一个目标target下边的命令,结果:

1
MAKECMDGOALS=

如果我们指定make命令执行指定目标,使用make app命令,结果:

1
MAKECMDGOALS=app

通常我们书写makefile有些通用的GNU目标规范,使用通用目标规范不仅可以使我们的makefile便于理解,还可以使我们的makefile更加专业,更加规范,下边列出一些GNUmakefile编写的通用目标规范

  • all:这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
  • clean:这个伪目标功能是删除所有被make创建的文件。
  • install:这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。
  • print:这个伪目标的功能是例出改变过的源文件。
  • tar:这个伪目标功能是把源程序打包备份。也就是一个tar文件。
  • dist:这个伪目标功能是创建一个压缩文件,一般是把tar文件压成Z文件。或是gz文件。
  • TAGS:这个伪目标功能是更新所有的目标,以备完整地重编译使用。
  • check和test:这两个伪目标一般用来测试makefile的流程。