制作是否应始终重新制作具有先决条件的目标,但不指向文件但没有配方?或者,如果需要重新制作一个或多个先决条件,制作是否只重新制作此类目标?
例如,在下面显示的Makefile中,我添加了一个名为objects
的目标,它具有先决条件,但不指向文件。
主要目标称为program
,它取决于objects
(以及可能的其他先决条件)。
file1 file2 file3: ; touch $@
objects: file1 file2
program: objects file3 ; @echo 'Making $@'
我的期望是,当运行make program
并且不需要重新制作文件先决条件(即file1,file2和file3都存在)时,不应重新构建program
。
然而,实际的GNU Make 行为是program
的配方始终运行(无论先决条件文件如何)。这是因为objects
始终被视为重制,这会强制重新构建任何依赖项(即program
)。
您可以通过运行make --trace -d --no-builtin-rules program
来验证这一点,并且您会看到制作始终输出" 必须重新制作目标'对象&#39 ; "
所以objects
总是"重拍" (即使它没有食谱),它总是被认为是新更新的。
这很可能是因为objects
未指向真实文件。但是我期待它,因为它没有配方,只要不需要重新制作任何先决条件,它就不会被重新制作。
这是预期的行为还是错误?
如果规则没有先决条件或配方,并且规则的目标 是一个不存在的文件,然后想象这个目标 每当其规则运行时更新。这意味着所有目标 根据这一点,他们的食谱总会运行。
但该说明并不适用于上述情况,因为objects
目标确实具有先决条件。但也许行为是相同的,只需要更新制作手册以澄清这一点。
一些补充说明:
我使用上面的分页后配方格式来使其更容易 读者复制并粘贴代码。否则,从a复制时 网页,标签将通常转换为空格 tab-indented-recipe格式。
当然我知道我可以创建一个变量$(OBJECTS)
将指向文件列表并使用它代替objects
目标在上面。这不是重点。
This question似乎也涉及相同的行为,但是不会讨论预期的行为或错误。
我使用的是GNU Make 4.2.1
答案 0 :(得分:4)
我认为您引用的段落仅仅是重新披露了其他地方已经指定的特定行为案例,以便为FORCE
的工作方式设置场景。
确实在previous section:
中做了一个更简单但更一般的陈述如果您编写的配方不会创建目标文件的规则,则每次目标进行重建时都会执行配方。
再次here:
如果目标不存在或者比任何先决条件旧,则目标已过期。
所以你完全可以预见到你所观察到的行为。