我正在经历Makefile documentation,我不清楚--ignore-errors
和--keep-going
之间的区别。
有人可以强调一下两者之间的区别吗?对我来说,发生错误后,两者似乎都继续存在。
尽管从文档中尚不清楚,但是--ignore-errors
可能具有配方级作用域,并且如果一个配方行失败,下一个将继续执行。 --keep-going
可能具有目标级别的作用域,如果任何目标配方失败,则配方执行到此结束,但仍将尝试执行其他先决条件/目标。这只是一种可能的看法,需要对此进行澄清。
请帮助。
答案 0 :(得分:1)
https://www.gnu.org/software/make/manual/make.html#Errors
有时某个配方行的失败并不表示有问题。例如,您可以使用
mkdir
命令来确保目录存在。如果目录已经存在,mkdir
将报告错误,但是无论如何您可能希望make
继续。要忽略配方行中的错误,请在该行文本的开头(初始标签之后)写一个
-
。-
在将行传递到外壳程序之前被丢弃。例如,
clean: -rm -f *.o
即使
make
无法删除文件,这也会导致rm
继续。使用
make
或-i
标志运行--ignore-errors
时,所有规则的所有配方中的错误都将被忽略。如果没有先决条件,则makefile中用于特殊目标.IGNORE
的规则具有相同的效果。因为-
更灵活,所以这些忽略错误的方法已经过时。
换句话说,make --ignore-errors
的行为就像所有命令前面都有一个-
。
当由于
-
或-i
标志而导致错误被忽略时,make
将错误返回与成功一样对待,不同之处在于它会打印出一条消息,告诉您您会收到外壳退出的状态代码,并说错误已被忽略。当发生错误而未告知
make
的错误时,表明不能正确地重制当前目标,并且任何直接或间接依赖它的目标也不能正确地进行重造。由于尚未达到其前提条件,因此将不再针对这些目标执行任何配方。在这种情况下,通常make会立即放弃,返回非零状态。但是,如果指定了
-k
或--keep-going
标志,make
会继续考虑挂起目标的其他先决条件,并在必要时对其进行重新制作,然后放弃并返回非零状态。例如,在编译一个目标文件时出错后,make -k
将继续编译其他目标文件,即使它已经知道不可能链接它们。参见Summary of Options。通常的行为是假设您的目的是使指定的目标保持最新。
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
通常,当您运行make target
(并且文件尚不存在)时,它将首先尝试制作intermediate-1
。该目标失败,因为关联的命令之一(false
)返回非零退出状态。 make
然后立即放弃,甚至不看intermediate-2
或intermediate-3
。
但是,对于make --keep-going target
,它将注意到intermediate-1
的失败,但是继续使intermediate-2
和intermediate-3
成功,(创建包含“ hello”的文件”和“世界”)。
最后,它仍然放弃并报告制作target
失败,但是它尝试创建所有中间目标,即使它知道不会在make
的这次运行中使用因为另一个先决条件已经失败。
如果同时使用两个标志(make --ignore-errors --keep-going
),则--keep-going
将被有效忽略。 --keep-going
仅影响make
在中间目标中遇到错误时的行为方式,但是--ignore-errors
意味着make
永远不会遇到错误。