目录
我们继续Makefile函数使用的学习,上一节可查看:↓传送门↓。
如何编写Makefile(6)-使用函数(二)-CSDN博客
https://blog.csdn.net/L_peanut/article/details/144341556?spm=1001.2014.3001.5501 本节将介绍如何运行make。一般来说,最简单的运行方式就是在命令行直接输入make,make命令会自动寻找当前目录中的makefile来执行,一切都是自动的。但是有些时候只需make重新编译某些文件,而不是整个工程,有的时候又会有几套编译规则,需要在不同的时候使用不同的编译规则。
一、make的退出代码
mak命令的退出码有三种:
0:表示成功执行
1:如果make运行时出现任何错误,返回1
2:如果使用了make的“-q”选项,且make使得一些目标不需要更新,返回2
二、指定Makefile
GNU make寻找默认的Makefile是在当前目录下依次寻找三个文件——“GNUmakefile”、“makefile”、“Makefile”,其按顺序寻找这三个文件,一旦找到,即开始读取并执行。
我们也可以给make命令指定一个特殊名字的Makefile。前面章节内容介绍过,我们可以使用make的“-f”或“--file”参数指定,假如有个makefile文件的名字是“test.mk”,那么我们可以这样使用make来执行这个文件:
make -f test.mk
如果在命令行不只使用了一次-f参数,所有指定的makefile将会连在一起传递给make执行。
三、指定目标
一般来说,make的最终目标是makefile中的第一个目标,其它目标是由这个目标衍生出来的,这是make的默认规则。如果你的makefile中的第一个目标是由多个目标组成,可以指示make完成你所指定的目标,只需要在make命令后面加上目标的名字即可(如make clean)。
任何在makefile中的目标都可以被指定为最终目标,但是除了以“-”开头或者是包含了“=”的目标,因为有这些字符的目标,会被解析为命令行参数或者是变量。甚至没有明确写出来的目标也可以成为make的最终目标,只要make可以找到其隐式规则推导,那么这个隐含目标同样可以成为最终目标。
有一个make的环境变量“MAKECMDGOALS”,这个变量会存放你所指定的最终目标的列表,如果没有在命令行上指定目标,这个变量将是空值。这个变量可以让你使用一些比较特殊的情形。如:
sources=foo.c bar.c
ifneq ($(MAKECMDGOALS),clean)
include $(sources:.c=.d)
endif
在上面的例子中,只要我们输入的不是“make clean”,makefile就会自动包含“foo.d”和“bar.d”这两个makefile。
使用指定最终目标的方式可以很方便的让我们编译程序,如下面的例子:
.PHONY:all
all:prog1 prog2 prog3 prog4
上面这个例子中,makefile包含四个需要编译的程序——“prog1”,“prog2”,“prog3”,“prog4”。我们可以使用“make all”命令来编译所有目标(如果将all作为第一目标,则只需执行“make”),也可以使用“make prog1”来单独编译“prog1”。make可以指定所有makefile中的目标,同样也包括伪目标,于是我们可以根据这种性质来让makefile根据指定的不同的目标完成不同的任务。如:
all:这个伪目标是所有目标的目标,功能一般是编译所有目标。
clean:这个伪目标是删除所有被make创建的文件。
install:这个伪目标功能是安装已编译好的程序,即将目标可执行文件拷贝到指定目标中去。
print:这个伪目标的功能是打印出改变过的源文件。
tar:这个伪目标的功能是把源程序打包备份。
dist:这个伪目标的功能是创建一个压缩文件,一般是把tar文件压缩成Z文件或者是gz文件。
TAGS:这个伪目标的功能是更新所有的目标,以备完整地重编译使用。
check和test:这两个伪目标一般用来测试makefile的流程。
四、检查规则
有时候我们并不想让makefile中的规则执行起来,只是想要检查一下我们的命令,我们可以使用make命令的下列参数:
-n, --just-print, --dry-run, --recon
不执行参数,这些参数只是打印命令,无论目标是否更新,将把规则和连带规则下面的命令全部打印出来,但不执行,这些参数对于makefile的调试很有作用。
-t, --touch
将目标文件的时间更新,但不更改目标文件,也就是说make在假装编译目标,但不是真正的编译目标,只是将目标变为已编译过的状态。
-q, --question
寻找目标,如果目标存在就不会输出信息,也不会执行编译。如果目标不存在,会打印一条信息。
-W<file>, --what-if=<file>, --assume-new=<file>, --new-file=<file>
这个参数需要指定一个文件,一般是源文件(或者是依赖文件),Make会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和“-n”参数一起使用,来查看这个依赖文件所发生的规则命令。
五、make的参数
下面列举一些GNU make 3.8版本中的参数定义:
-b, -m
这两个参数的作用是忽略和其它版本make的兼容性。
-B, --always-make
认为所有的目标都需要更新(重新编译)。
-C<dir>, --directory=<dir>
指定读取makefile的目录,如果有多个“-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:“make -C ~home/user -C prog”等价于“make -C ~home/user/prog”。
-debug[=<options>]
输出make的调试信息,有几种不同的级别可供选择,如果没有参数,就输出最简单的调试信息。下面是<options>的取值:
①a:即all,输出所有的调试信息。
②b:即basic,只输出简单的调试信息。
③v:即verbose,在b选项的级别之上,输出的信息包括哪个makefile被解析,不需要被重编译的依赖文件(或者是依赖目标)等。
④i:即implicit,输出所有的隐含规则。
⑤j:即jobs,输出执行规则中命令的详细信息。如命令的PID、返回码等。
⑥m:即makefile,输出make读取makefile,更新makefile,执行makefile的信息。
-d
等价于“-debug=a”。
-e, --environment-overrides
指明环境变量的值覆盖makefile中定义的变量的值。
-f=<file>, --file=<file>, --makefile=<file>
指定需要执行的makefile。
-h, --help
显示帮助信息。
-i, --ignore-errors
在执行时忽略所有的错误。
-I<dir>, --include-dir=<dir>
指定一个makefile的搜索路径,可以使用“-I”参数来指定多个目录。
-j[<jobsnum>], --jobs[=<jobsnum>]
指同时运行命令的个数,如果没有这个参数,make执行时能执行多少就执行多少,如果有一个以上的“-j”参数,仅最后一个“-j”有效。
-k, --keep-going
出错也会继续运行,如果生成一个目标失败,那么依赖于这个目标的命令就不会执行。
-l<load>, --load-average[=<load>], -max-load[=<load>]
指定make运行命令的负载。
-n, --just-print, --dry-run, --recon
指输出执行过程中的命令序列,但并不执行。
-o<file>, --old-file=<file>, --assume-old=<file>
不重新生成指定的<file>,即使这个目标的依赖文件比它新。
-p, --print-data-base
输出makefile中的所有数据,包括所有规则和变量。这个参数会让一个简单的makefile都会输出一堆信息。如果你只是想输出信息而不是想执行makefile,可以使用“make -qp”命令。如果想查看执行makefile前的预设变量和规则,可以使用“make -p -f/dev/null”。这个参数输出的信息包含makefile文件的文件名和行号。
-q, --question
不运行命令,也不输出。只是检查所指定的目标是否需要更新,如果是0则需要更新,如果是2说明有错误发生。
-r, --no-builtin-rules
禁止make使用任何隐含规则。
-R, --no-builtin-variables
禁止make使用任何作用于变量上的隐含规则。
-s, --silent, --quiet
命令运行时不输出命令的输出。
-S, --no-keep-going, --stop
取消“-k”参数的作用,因为有些时候make的选项是从环境变量“MAKEFLAGS”中继承的。
-t, --touch
相当于UNIX的touch命令,只是将目标的修改日期更新,即阻止生成目标的命令运行。
-v, --version
输出make程序的版本、版权等关于make的信息。
-w, --print-directory
输出运行makefile之前和之后的信息,对于跟踪嵌套式调用make时很有用。
--no-print-directory
禁止-w选项。
-W<file>, --what-if=<file>, --new-file=<file>, --assume-file=<file>
假设目标<file>需要更新,如果和“-n”选项使用,那这个参数会输出该目标更新时的运行动作,如果没有“-n”则像运行UNIX的“touch”命令一样,使<file>的修改时间为当前时间。
--warn-undefined-variables
只要make发现未定义的变量,就会输出警告信息。
-运行make&spm=1001.2101.3001.5002&articleId=144403705&d=1&t=3&u=e8dbfffaf3ba4dda8116ba93a810ee33)
3311

被折叠的 条评论
为什么被折叠?



