📄 1008.html
字号:
include $(sources:.c=.d)<br>
例中使用替换变量来将源文件列表’ foo.c bar.c’转换为依赖关系文件的列表。因为’.d’文件和其它文件一样,不需要更多工作,make会在需要时重新生成它们。<br>
4.编写命令<br>
规则的命令是由一一执行的shell命令组成。除了以分号隔开写在依赖关系后的命令,每个命令行必须以tab字符开始空行和注释行可以出现在命令行中,处理时被忽略(注意:以tab字符开始的空行不是’空’行,是一条空命令)。<br>
可以在命令中使用任何程序,但这些程序是由$(SHELL)来执行的。<br>
4.1.回显<br>
通常make打印出要执行的命令,称之为回显,这和亲自敲命令的现象是一样的。当行之前有’@’字符时,命令不再回显,字符’@’在传递给shell前丢弃。典型的用法是只对打印命令有效,比如’echo’命令:<br>
@echo About to make distribution files<br>
当make使用’-n’或’—just-print’选项时,显示要发生的一切,但不执行命令。只有在这种情况下,即使命令以’@’开始,命令行仍然显示出来。这个选项对查看make实际要执行的动作很有用。<br>
‘-s’或’—silent’选项阻止make所有回显,就象所有命令以’@’开始一样;一条没有依赖关系的’.SILENT’规则有相同的作用,但是’@’更加灵活。<br>
4.2.执行<br>
在需要执行命令更新目标时,make为每一行创建一个子shell来执行。这意味着诸如为进程设置局部变量的shell命令’cd’(改变进程的当前目录)不会影响以后的命令。如果需要’cd’影响下一个命令,将它们放在一行上用分号隔开,这样make认为是一条命令传递给shell程序(注意:这需要shell支持):<br>
foo : bar/lose<br>
cd bar; gobble lose > ../foo<br>
另一个形式使用续行符:<br>
foo : bar/lose<br>
cd bar; <br>
gobble lose > ../foo<br>
shell程序的名字是通过’SHELL’变量来取得的。<br>
(*UNIX)不象大多数变量,’SHELL’变量不是通过环境来设置的(即需要在makefile中设置),因为’SHELL’环境是个人选择的,如果不同人的选择会影响makefile的功能的话,这样很糟糕。<br>
4.3.并行执行<br>
GNU make可以一次执行几条命令。通常make一次执行一条命令,等待其返回,再执行下一条。使用’-j’或’—jobs’可以同时执行多条命令。如果’-j’后梗一个正数,表示一次可以执行的命令条数;如果’-j’之后没有参数,则不限制可执行的命令数。缺省的数量是一。<br>
一个讨厌的问题是如果同时执行多条命令,它们的输出会混在一起;另一个问题是两个进程不能从同一个设备获得输入。<br>
4.4.错误<br>
每条shell命令返回时,make会检查其返回状态。如果命令执行成功,则下一条命令被执行,最后一条命令执行完后,规则执行结束。<br>
如果有错误(返回非0状态),make放弃当前规则,也可能是所有规则。<br>
有时候命令执行错误并不是问题,比如使用’mkdir’命令确保目录存在:如果目录一存在,则’mkdir’会报告错误,但仍希望make继续。<br>
要忽略命令的错误,在命令之前使用’-‘字符,’-‘字符在传递给shell之前被丢弃:<br>
clean:<br>
-rm -f *.o<br>
如果使用’-i’或’—ignore-errors’选项,make会忽略所有命令产生的错误;一条没有依赖关系的’.IGNORE’规则有相同的作用,但’-‘更灵活。<br>
在忽略错误时,make将错误也认为是成功,只是通知你命令的退出状态和和错误被忽略。如果make并未告知忽略错误,在错误发生时,表明该目标不能成功更新,直接或间接依赖于此的目标当然也不能成功;这些目标的命令不会被执行,因为其先决条件不满足。<br>
通常make会立即以非0状态退出。然而,如果给定’-k’或’—keep-going’选项,make在退出前会处理其它的依赖关系,进行必要的更新。例如,在编译一个目标文件遇到错误,’make -k’会继续编译其它的目标文件。<br>
通常认为你的目的是更新指定的目标,当make知道这是不可能时,会立即报告失败;’-k’选项指示真正目的是测试更新程序的更多可能性:在编译之前找出更多不相关的问题。<br>
如果命令失败了,假设它更新的目标文件,这个文件是不完整的不能使用-至少不是完全更新的。但文件的最后修改时间表明停已经是最新的,下一次make运行时,不会再更新这个文件。这种情况和命令被kill相同;则通常情况下在命令失败时将目标删除是正确的;当’.DELETE_ON_ERROR’是目标时make帮你做这件事。虽然你总是希望make这么做,但这不是过去的习惯;所以必须显式要求make这样做(其它的make自动这样做)。<br>
4.5.中断make<br>
如果make执行命令时遇到错误,可能会删除命令更新的目标文件: make检查文件的修改时间是否变化。删除目标的目的是确保make下次执行时重新生成它。为什么这样做?假设在编译器运行时按了’Ctrl-c’,此时编译器写生成目标文件’foo.o’。’Ctrl-c’ kill了编译器,留下一个不完整的文件,但它的修改时间比源文件’foo.c’新;此时make也受到’Ctrl-c’信号删除这个不完整的文件,如果make不这样做,下次make运行时认为’foo.o’不需要更新,会在链接时出现奇怪的错误。<br>
可以使用’.PRECIOUS’规则来防止目标文件被删除。在make更新目标时,会检测其是否为’.PRECIOUS’的依赖,决定在命令出错或中断时是否删除该目标。如果你希望目标的更新是原子操作,或是用来记录修改时间,或必须一直存在防止其它类型的错误,这些理由使得你必须这样做。<br>
4.6.递归使用<br>
递归使用make就是在makefile中使用make命令。这种技术在你将一个大系统分解为几个子系统,为每个自系统提供一个makefile时有用处。比如有一个子目录’subdir’中有自己的makefile,希望make在自目录中运行,可以这样做:<br>
subsystem:<br>
cd subdir; $(MAKE)<br>
或者<br>
subsystem:<br>
$(MAKE) -C subdir<br>
可以照抄这个;例子来递归使用make<br>
4.6.1.‘MAKE’变量<br>
递归的make必须使用’MAKE’变量,不是显式的make命令:<br>
subsystem:<br>
cd subdir; $(MAKE)<br>
该变量的值是被调用的make的名字。在命令中使用’MAKE’有特殊的功能:它改变了`-t' (`--touch'), `-n' (`--just-print')和`-q' (`--question')选项的含义。使用上例来考虑’make –t’命令(’-t’选项将目标标记为最新但不运行命令),更加’-t’选项的功能,该命令将创建一个’subsystem’文件,实际希望的操作是运行’cd subdir; make –t’;但这会执行命令,与’-t’的原意不符。<br>
这个特殊功能做了期望的工作。当命令行包含变量’MAKE’时,选项’-t’,’-n’和’-q’并不适用。不管这些导致不会执行命令的标志,包含’MAKE’变量的命令始终会执行。正常的’MAKEFLAGS’机制将这些标志传递到子make,这样打印命令的请求被传播到子系统中。<br>
4.6.2.传递变量到子make<br>
上级(top-level)make中的变量可以显式通过环境传递到子make中。在子make中,这些变量被缺省定义,但不会重载子makefile中的定义除非使用’-e’选项。<br>
为向下传递,或输出变量,make在运行命令时将其加入到环境变量中;子make,可以使用环境变量来初始化变量表。除非显式要求,make只输出初始环境中或命令行设置的变量而且变量名只由字母,数字和下划线组成。一些shell不能处理有其它字符的环境变量。<br>
特殊变量’SHELL’,’MAKEFLAGS’总是输出,如果’MAKEFILE’变量有值,也会输出。Make自动通过’MAKEFLAGS’来输出命令行定义的变量。<br>
如果想要输出特定变量,使用’export’指令:<br>
export VARIABLE ...<br>
如果要阻止输出一个变量,使用’unexport’指令:<br>
unexport VARIABLE ...<br>
为方便起见,可以在定义变量时输出它:<br>
export VARIABLE = value<br>
和<br>
VARIABLE = value<br>
export VARIABLE<br>
作用相同。<br>
如果要输出所有的变量,使用’export’指令本身就可以了。<br>
变量’MAKELEVEL’在一级一级传递时会改变,这个变量的值是表示嵌套层数的字符串,顶级’make’是,变量的值为’0’;子make的值为’1’;子子make的值为’2’,依此类推。<br>
‘MAKELEVEL’的用途是在条件指令中测试它,这样写出在递归运行时和直接运行时表现不同的makefile。<br>
<br>
<br>
以下内容拷贝自GNU Make Manual<br>
5.命令行参数<br>
`-b'<br>
`-m'<br>
These options are ignored for compatibility with other versions of<br>
`make'.<br>
<br>
`-C DIR'<br>
`--directory=DIR'<br>
Change to directory DIR before reading the makefiles. If multiple<br>
`-C' options are specified, each is interpreted relative to the<br>
previous one: `-C / -C etc' is equivalent to `-C /etc'. This is<br>
typically used with recursive invocations of `make' (*note<br>
Recursive Use of `make': Recursion.).<br>
<br>
`-d'<br>
`--debug'<br>
Print debugging information in addition to normal processing. The<br>
debugging information says which files are being considered for<br>
remaking, which file-times are being compared and with what<br>
results, which files actually need to be remade, which implicit<br>
rules are considered and which are applied--everything interesting<br>
about how `make' decides what to do.<br>
<br>
`-e'<br>
`--environment-overrides'<br>
Give variables taken from the environment precedence over<br>
variables from makefiles. *Note Variables from the Environment:<br>
Environment.<br>
<br>
`-f FILE'<br>
`--file=FILE'<br>
`--makefile=FILE'<br>
Read the file named FILE as a makefile. <br>
<br>
`-h'<br>
`--help'<br>
Remind you of the options that `make' understands and then exit.<br>
`-i'<br>
`--ignore-errors'<br>
Ignore all errors in commands executed to remake files. <br>
<br>
`-I DIR'<br>
`--include-dir=DIR'<br>
Specifies a directory DIR to search for included makefiles. If several `-I' options are<br>
used to specify several directories, the directories are searched<br>
in the order specified.<br>
<br>
`-j [JOBS]'<br>
`--jobs=[JOBS]'<br>
Specifies the number of jobs (commands) to run simultaneously.<br>
With no argument, `make' runs as many jobs simultaneously as<br>
possible. If there is more than one `-j' option, the last one is<br>
effective.<br>
`-k'<br>
`--keep-going'<br>
Continue as much as possible after an error. While the target that<br>
failed, and those that depend on it, cannot be remade, the other<br>
dependencies of these targets can be processed all the same.<br>
<br>
`-l [LOAD]'<br>
`--load-average[=LOAD]'<br>
`--max-load[=LOAD]'<br>
Specifies that no new jobs (commands) should be started if there<br>
are other jobs running and the load average is at least LOAD (a<br>
floating-point number). With no argument, removes a previous load<br>
limit. *Note Parallel Execution: Parallel.<br>
<br>
`-n'<br>
`--just-print'<br>
`--dry-run'<br>
`--recon'<br>
Print the commands that would be executed, but do not execute them.<br>
`-o FILE'<br>
`--old-file=FILE'<br>
`--assume-old=FILE'<br>
Do not remake the file FILE even if it is older than its<br>
dependencies, and do not remake anything on account of changes in<br>
FILE. Essentially the file is treated as very old and its rules<br>
are ignored. <br>
<br>
`-p'<br>
`--print-data-base'<br>
Print the data base (rules and variable values) that results from<br>
reading the makefiles; then execute as usual or as otherwise<br>
specified. This also prints the version information given by the<br>
`-v' switch (see below). To print the data base without trying to<br>
remake any files, use `make -p -f /dev/null'.<br>
<br>
`-q'<br>
`--question'<br>
"Question mode". Do not run any commands, or print anything; just<br>
return an exit status that is zero if the specified targets are<br>
already up to date, one if any remaking is required, or two if an<br>
error is encountered. <br>
<br>
`-r'<br>
`--no-builtin-rules'<br>
Eliminate use of the built-in implicit rules.You can still define your own by writing<br>
pattern rules. The `-r' option also clears out the default list<br>
of suffixes for suffix rules .But
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -