make之makefile 八 make 的运行

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013896064/article/details/83040895

一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前文件夹的makefile来运行,一切都是自己主动的。但也有时你或许仅仅想让make重编译某些文件,而不是整个工程,而又有的时候你有几套编译规则,你想在不同的时候使用不同的编译规则,等等。本章节就是讲述怎样使用make命令的。

一、make的退出码

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

0 —— 表示成功运行。
1 —— 假设make运行时出现不论什么错误,其返回1。
2 —— 假设你使用了make的“-q”选项,而且make使得一些目标不须要更新,那么返回2。

Make的相关參数我们会在后续章节中讲述。


二、指定Makefile

前面我们说过,GNU make找寻默认的Makefile的规则是在当前文件夹下依次找三个文件——“GNUmakefile”、“makefile”和“Makefile”。其按顺序找这三个文件,一旦找到,就开始读取这个文件并运行。

当前,我们也能够给make命令指定一个特殊名字的Makefile。要达到这个功能,我们要使用make的“-f”或是“--file”參数(“--makefile”參数也行)。比如,我们有个makefile的名字是“hchen.mk”,那么,我们能够这样来让make来运行这个文件:

make –f hchen.mk

假设在make的命令行时,你不仅仅一次地使用了“-f”參数,那么,全部指定的makefile将会被连在一起传递给make运行。


三、指定目标

一般来说,make的终于目标是makefile中的第一个目标,而其他目标通常是由这个目标连带出来的。这是make的默认行为。当然,一般来说,你的makefile中的第一个目标是由很多个目标组成,你能够指示make,让其完成你所指定的目标。要达到这一目的非常easy,需在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 prog2”来单独编译目标“prog2”。

即然make能够指定全部makefile中的目标,那么也包括“伪目标”,于是我们能够依据这样的性质来让我们的makefile依据指定的不同的目标来完成不同的事。在Unix世界中,软件公布时,特别是GNU这样的开源软件的公布时,其makefile都包括了编译、安装、打包等功能。我们能够參照这样的规则来书写我们的makefile中的目标。

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

当然一个项目的makefile中也不一定要书写这样的目标,这些东西都是GNU的东西,可是我想,GNU搞出这些东西一定有其可取之处(等你的UNIX下的程序文件一多时你就会发现这些功能非常实用了),这里仅仅只是是说明了,假设你要书写这样的功能,最好使用这样的名字命名你的目标,这样规范一些,规范的长处就是——不用解释,大家都明白。而且假设你的makefile中有这些功能,一是非常实用,二是能够显得你的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”參数一同使用,来查看这个依赖文件所发生的规则命令。

另外一个非常有意思的使用方法是结合“-p”和“-v”来输出makefile被运行时的信息(这个将在后面讲述)。


五、make的參数

以下列举了全部GNU make 3.80版的參数定义。其他版本号和产商的make大同小异,只是其他产商的make的具体參数还是请參考各自的产品文档。

“-b”
“-m”
这两个參数的作用是忽略和其他版本号make的兼容性。

“-B”
“--always-make”
觉得全部的目标都须要更新(重编译)。

“-C <dir>”
“--directory=<dir>”
指定读取makefile的文件夹。假设有多个“-C”參数,make的解释是后面的路径曾经面的作为相对路径,并以最后的文件夹作为被指定文件夹。如:“make –C ~hchen/test –C prog”等效于“make –C ~hchen/test/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”才是有效的。(注意这个參数在MS-DOS中是没用的)

“-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文件的文件名称和行号,所以,用这个參数来调试你的makefile会是非常实用的,特别是当你的环境变量非常复杂的时候。

“-q”
“--question”
不运行命令,也不输出。仅仅是检查所指定的目标是否须要更新。假设是0则说明要更新,假设是2则说明有发生错误。

“-r”
“--no-builtin-rules”
禁止make使用不论什么隐含规则。

“-R”
“--no-builtin-variabes”
禁止make使用不论什么作用于变量上的隐含规则。

“-s”
“--silent”
“--quiet”
在命令运行时不输出命令的输出。

“-S”
“--no-keep-going”
“--stop”
取消“-k”选项的作用。由于有些时候,make的选项是从环境变量“MAKEFLAGS”中继承下来的。所以你能够在命令行中使用这个參数来让环境变量中的“-k”选项失效。

“-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发现有未定义的变量,那么就输出警告信息。

猜你喜欢

转载自blog.csdn.net/u013896064/article/details/83040895
今日推荐