我正在经历的Makefile文件,我不明白之间的差别--ignore-errors
和--keep-going
。
有人可以强调两者之间的区别吗?对我来说,两者似乎在发生错误后都会继续。
虽然文档中不清楚,但--ignore-errors
可能具有配方级别的范围,如果一个配方行失败,下一个将继续执行。--keep-going
可能具有目标级范围,如果任何目标配方失败,配方执行将在那里结束,但仍将尝试创建其他先决条件/目标。这只是一种可能的看法,需要对此进行澄清。
https://www.gnu.org/software/make/manual/make.html#Errors
有时,某个配方线的故障并不表示存在问题。例如,您可以使用该
mkdir
命令来确保目录存在。如果目录已经存在,mkdir
会报错,但你可能想make
继续不管。要忽略配方行中的错误
-
,请在行文本的开头(在初始选项卡之后)写入 a 。所述-
的线被传递给外壳以供执行之前被丢弃。例如,
Run Code Online (Sandbox Code Playgroud)clean: -rm -f *.o
make
即使rm
无法删除文件,这也会导致继续。当您
make
使用-i
or--ignore-errors
标志运行时,所有规则的所有配方中的错误都会被忽略。.IGNORE
如果没有先决条件,则特殊目标的 makefile 中的规则具有相同的效果。这些忽略错误的方法已经过时了,因为-
它更灵活。
换句话说,make --ignore-errors
就像-
在所有命令前面都有一个一样。
当错误将被忽略时,由于 a
-
或-i
标志,make
将错误返回视为成功,除了它打印出一条消息,告诉您 shell 退出时的状态代码,并表示错误已被忽略。当发生一个
make
没有被告知忽略的错误时,它意味着当前目标不能被正确地重建,任何其他直接或间接依赖于它的目标也不能。不会为这些目标执行进一步的配方,因为尚未达到它们的先决条件。通常 make 在这种情况下立即放弃,返回非零状态。但是,如果指定了
-k
or--keep-going
标志,则在make
放弃并返回非零状态之前,继续考虑挂起目标的其他先决条件,必要时重新制作它们。例如,在编译一个目标文件出错后,make -k
将继续编译其他目标文件,即使它已经知道链接它们是不可能的。请参阅选项摘要。通常的行为假设您的目的是使指定的目标保持最新;一旦
make
得知这是不可能的,还不如立即报告失败。该-k
选项表示真正的目的是尽可能多地测试程序中所做的更改,也许是为了找到几个独立的问题,以便您可以在下一次尝试编译之前更正它们。这就是 Emacs 的compile
命令-k
默认传递标志的原因。
让我们以这个例子为例:
target: intermediate-1 intermediate-2 intermediate-3
cat intermediate-1 intermediate-2 intermediate-3 > target
intermediate-1:
echo "oh no, I'm failing!"
false
intermediate-2:
echo 'hello' > intermediate-2
intermediate-3:
echo 'world' > intermediate-3
Run Code Online (Sandbox Code Playgroud)
通常当你运行时make target
(并且没有任何文件存在),它会首先尝试 make intermediate-1
。该目标失败,因为相关命令之一 ( false
) 返回非零退出状态。make
然后立即放弃,甚至不看intermediate-2
or intermediate-3
。
但是,使用make --keep-going target
,它会注意到 失败intermediate-1
,但继续执行 makeintermediate-2
和intermediate-3
,它成功(分别创建包含“hello”和“world”的文件)。
最后它仍然放弃并报告 make 失败target
,但它已尝试创建所有中间目标,即使是它知道不会在本次运行中使用的目标,make
因为另一个先决条件已经失败。
如果同时使用两个标志 ( make --ignore-errors --keep-going
),则--keep-going
实际上将被忽略。--keep-going
仅影响make
在中间目标中遇到错误时的行为方式,但--ignore-errors
意味着make
永远不会遇到错误。