做出递归依赖

时间:2013-06-24 15:26:43

标签: makefile

我目前正在开发一个项目,该项目需要将目录中的文件列表转换为c ++标头,以存储有关资源的信息。例如:

/
update.py
resources.h
Makefile
/resources
  resource1.png
  /sub1
    /sub2
      resource2.png

我想要的是,只有当目录树中任何一个资源发生变化时,Makefile才能运行update.py。没有其他makefile会触及资源,只有资源.h。我需要做什么样的makefile?

PS 根据我的阅读,使用make递归搜索是一个坏主意,但如果没有其他内容触及同一个文件,那会不会有问题?

3 个答案:

答案 0 :(得分:15)

我不确定你读过什么,但是在make中编写这样的规则没有问题:

RESOURCES := $(shell find . -name resource\*.png -print)
resources.h: update.py $(RESOURCES)
        ./update.py $(RESOURCES)

或其他什么。

答案 1 :(得分:2)

我认为你错了:Recursive Make Considered Harmful解释说你不应该从另一个中调用一个make,因为它们都没有完整的依赖概述。这迟早会导致错误的构建,您只能使用make clean进行整理。

makepp是一种可以帮助您避免陷阱的替代方案。它还通过递归(与上面的递归无关)通配符解决了你的问题:

RESOURCES := **/resource\*.png
resources.h: $(RESOURCES)
    .$/update.py $(inputs)

如果文件还没有,这甚至可以工作,因为makepp的通配符会考虑根据您的规则构建的内容。请注意它如何自动注意程序依赖性。有趣的$/将依赖于它运行的系统,因此它更加便携。

makepp还有很多。除了做几乎所有GNU make之外,还有更多有用的东西,你甚至可以通过一些Perl编程扩展你的makefile。

答案 2 :(得分:1)

请注意,您也可以使用$(shell find)命令来处理不带变量的依赖项:

resources.h: $(shell find . -name 'resource*.png')
    ./update.py $^

这样,就像@MadScientist的回答一样,但是您会在$^自动变量中获得依赖项列表。 (不过,在这种情况下,不能轻易将update.py包含在依赖项中。)

之所以强大,是因为您可以使用模式,例如,如果需要从多个匹配目录(resourcesN.h)编译为多个目标文件(resourcesN/):

targets: resources1.h resources2.h
%.h: $(shell find $*/ -name 'resource*.png')
    ./update.py $^

这里$*获得值resources1resources2,然后$^保留在相应目录中找到的依赖项列表。