作为构建过程的一部分,我需要用m4处理一些文件。这些文件的扩展名为“.in”,不仅位于顶级目录中,还位于子目录中。 我使用find找到它们并在shell循环中处理它们。
是否有一些makefile语法魔术来编写更简单的规则来处理它们将输出保存到与输入文件相同的目录中的文件('。''扩展名剥离)?
这就是我现在在makefile中的内容:
PROCESS_FILES=$(shell find . -name \*.in)
WORK_FILES=$(subst .in,,$(PROCESS_FILES))
$(WORK_FILES): $(PROCESS_FILES)
for file in $(PROCESS_FILES); \
do \
m4 $$file > $${file%.*};\
done
答案 0 :(得分:3)
您可以编写一组规则,将带有后缀.in
的文件转换为不带后缀的文件。
在经典表示法中,这将是:
# Not functional — see discussion
.SUFFIXES: .in # Add .in as a suffix
M4 = m4
M4FLAGS =
M4SCRIPT = xyz.m4
.in:
${M4} ${M4FLAGS} ${M4SCRIPT} $< > $*
这会将.in
添加为已识别的后缀,并表示使用.in
后缀将文件转换为文件而不使用三个宏指定的命令。 $<
是具有.in
扩展名的文件的名称; $*
是没有扩展名的文件的名称。
不幸的是,只有当要转换的文件具有xyz.in
等名称并且需要转换为xyz
时,该符号才有效。对于需要将xyz.h.in
转换为xyz.h
的情况,它不起作用。
可以指定后缀为.h.in
和.h
,但是在.h.in.h:
和make
两个开头之间进行转换的规则会混淆。
但是,GNU make有一个替代符号来定义可以容纳这个的后缀规则:
.SUFFIXES: .h.in .h # Add .h.in and .h as suffixes
M4 = m4
M4FLAGS =
M4SCRIPT = xyz.m4
%.h: %.h.in
${M4} ${M4FLAGS} ${M4SCRIPT} $< > $*.h
%.h: %.h.in
行能够用两个点来处理后缀。唯一令人讨厌的是,对于每个扩展名,例如.c.in
或.y.in
或.mk.in
,您必须提供类似的映射。
(在Mac OS X 10.7.4上测试。如果该makefile为xyz.mk
,您可以创建一个空文件xyz.h.in
,然后运行make -n -f xyz.mk xyz.h
,您将看到构建将运行命令m4 xyz.m4 xyz.h.in > xyz.h
。)
答案 1 :(得分:0)
如果您有源文件path/to/file.in
,从%
获取%.in
的规则,以及对输出文件path/to/file
的依赖,那么您应该只需要它们
也许您想根据find
的输出来表达您的依赖关系。在GNU Make中这很容易;在其他方言中,您可能希望生成并包含find -name '*.in' | sed 's/\.in$//' >make.dep