我目前正在开发一个项目,该项目需要将目录中的文件列表转换为c ++标头,以存储有关资源的信息。例如:
/
update.py
resources.h
Makefile
/resources
resource1.png
/sub1
/sub2
resource2.png
我想要的是,只有当目录树中任何一个资源发生变化时,Makefile才能运行update.py。没有其他makefile会触及资源,只有资源.h。我需要做什么样的makefile?
PS 根据我的阅读,使用make递归搜索是一个坏主意,但如果没有其他内容触及同一个文件,那会不会有问题?
答案 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 $^
这里$*
获得值resources1
和resources2
,然后$^
保留在相应目录中找到的依赖项列表。