Makefile - 仅当文件不存在时才建立依赖关系
Posted
技术标签:
【中文标题】Makefile - 仅当文件不存在时才建立依赖关系【英文标题】:Makefile - Make dependency only if file doesn't exist 【发布时间】:2014-03-11 20:01:09 【问题描述】:正如标题所说,我只想在某个文件不存在时建立依赖关系,而不是每次更新时。
我有一个根目录(带有 makefile 的那个),其中有一个名为“example”的子目录。在我的根目录中有四个 .h 文件(functions.h、parser.h、node.h 和 exception.h),如果这些 .h 文件不存在,我想将它们复制到“example”子目录在“示例”中。
不幸的是,我不能只创建一个标准依赖项来检查“example”中的头文件,因为每次我将头文件从根目录复制到“example”时,“example”中的头文件都会被认为是更新的,并且会每次运行 make 时都会触发该依赖项。我想要一种方法让我的 makefile 将头文件从根目录复制到“example”,前提是它们不存在于“example”中。
【问题讨论】:
手册非常非常清楚,自动变量(例如$@
)在配方中仅有效。您不能在目标、先决条件或 make 条件语句中使用它们(因为在读入 makefile 时它们会被扩展)。在这些情况下,$@
扩展为空字符串。
我明白了,但是因为我附加了“example/”,所以 ifeq() 仍然评估为假。感谢您清除它。我已经编辑了我的帖子以专注于剩余的问题。
【参考方案1】:
这就是order-only prerequisites/dependencies 的用途:
但是,有时您会遇到这样的情况,即您希望对要调用的规则施加特定的顺序,而不是在执行这些规则之一时强制更新目标。在这种情况下,您想要定义仅订单的先决条件。可以通过在先决条件列表中放置管道符号 (
|
) 来指定仅订单先决条件:管道符号左侧的任何先决条件都是正常的;右侧的任何先决条件都是仅订购的。
在你的情况下:
examples/%.h : | %.h
cp $| $@
另见:Order-only prerequisites do not show up in $^
or $+
.
【讨论】:
如果您使用的是 GNU make(而且您可能是),这是一个很好的答案。 @reinierpost 我不确定为什么要使用任何其他品牌。 过去,我一直被其他make
s 困住,但事实上,那是很久以前的事了。
谢谢,这个例子有效,但我不确定我是否理解它。我认为 order-only 意味着如果依赖项“%.h”不存在或被更新,它不会触发目标“examples/%.h”。此外,“examples/%.h”是它自己的依赖项,只要将“root”中的文件复制到“examples”,就应该触发它,因为它会更新文件“examples/%.h”。然而,这不是行为意味着它会按照我的意愿去做,但不是我所期望的。您能否详细说明您的解决方案中发生了什么?
@Daniel make
不检查仅订单依赖项的时间戳。这意味着它会创建examples/%.h
,但不会在其先决条件%.h
更改时对其进行更新。【参考方案2】:
您必须根据相对文件年龄来表达依赖关系。
一种常用的解决方法是使用一个标记操作完成的虚拟(“哨兵”)文件:
examples/%.h.hasbeencopied: %.h
if [ -f example/$@.h ] || cp -p $< examples/$@.h; \
then touch $@; \
else rm -f $@; \
fi
并使任何规则依赖于example/foo.h
也依赖于example/foo.h.hasbeencopied
。
【讨论】:
以上是关于Makefile - 仅当文件不存在时才建立依赖关系的主要内容,如果未能解决你的问题,请参考以下文章
php Wordpress - 仅当帖子内容中存在短代码时才加载短代码插件(CF7)依赖项