当涉及生成的标头时如何让 make 正确创建依赖项
我试图让 make 自动构建一些生成的标头,然后自动创建依赖项 (.d
) 文件。但是我不确定如何让 make 正确并按正确的顺序完成两个目标。
这是我到目前为止所拥有的:
all: test
test: test.o
g++ test.o -o test
test.o: test.cc test.d external-headers
g++ test.cc -c -o test.o
test.d: test.cc external-headers
g++ -MM -MT $@ $< -o $@
external/some_header.hh:
mkdir -p external
touch external/some_header.hh
.PHONY: external-headers
-include test.d
external-headers: external/some_header.hh
查看依赖项,这看起来是正确的,因为我必须先创建外部标头,然后才能创建任何 .d
文件。此外,如果外部标头丢失,则必须重新生成它们。然而这个小 Makefile 会导致 GNU make 进入无限循环。我使用调试选项来找出它为什么这样做。
我所看到的是,每次重新创建任何包含的文件时, make 都会不断重新启动。这很好,也是我所期望的。然而,每次重新启动时,它都会重新创建 external-headers
目标,因为它是虚假的。然而,尽管它不必在后续目标中创建任何内容,但这意味着自上次调用以来已重建了包含的依赖目标,因此它重建了包含的目标,然后重新启动。
这个问题有好的解决办法吗?我最简单的想法是使 .d
文件直接依赖于标头 external/some_header.hh
并跳过其间的目标。经过测试,这工作正常。然而在实际情况下,我有一大堆生成的标头,我希望能够轻松地立即重建所有标头。
我的另一个想法是在某处添加一个实际上称为external-headers的文件,并在每次调用该目标时触摸该文件。这样,make 可以存储上次重建目标的时间,并且实际上注意到它不必执行任何操作。
有没有更好的方法来处理这样的事情?
I am trying to get make to automatically build some generated headers and then create the depency (.d
) files automatically. However I am not sure how to get make to do both targets correctly and in the right order.
Here is what I have so far:
all: test
test: test.o
g++ test.o -o test
test.o: test.cc test.d external-headers
g++ test.cc -c -o test.o
test.d: test.cc external-headers
g++ -MM -MT $@ lt; -o $@
external/some_header.hh:
mkdir -p external
touch external/some_header.hh
.PHONY: external-headers
-include test.d
external-headers: external/some_header.hh
Looking at the dependencies this looks correct, because I have to make the external header before I can create any .d
file. Also if the external-headers are missing they will have to be regenerated. However this small Makefile causes GNU make to go into an endless loop. I used the debugging option, to find out, why it does this.
What I could see was, that make keeps restarting itself each time it recreates any included file. This is ok and what I would expect. However upon each restart, it recreates the external-headers
target because it is phony. However although it does not have to create anything in the subsequent targets, this means a dependent target for the inclues has been rebuilt since the last invocation, so it rebuilds it's includes and then restarts.
Is there a good solution to this problem? The simplest idea I had was to make the .d
files dependent on the header external/some_header.hh
directly and skip the target in between. When tested this works fine. However in the real situation, i have a whole bunch of generated headers, and I want to easily be able to rebuild all of them at once.
Another Idea I had, was to add a file somewhere which is actually called external-headers
and touch this file each time this target is called. This way make could store when it last rebuilt the target and actually notice it won't have to do anything.
Is there a better way to handle something like this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
围绕此问题的解决方案是将文件生成为
file.tmp
,如果它们不同,则将file
替换为file.tmp
。这样make
不会看到新文件,也不会重新启动所有内容。看看Makefile
的自动工具使用./configure
舞蹈创建的,它广泛使用了它。The kludge around this is to generate the file as
file.tmp
, and replacefile
withfile.tmp
if they differ. That waymake
doesn't see a new file, and doesn't restart everything. Look at theMakefile
s autotools creates with the./configure
dance, it uses that extensively.