2012-08-09 201 views
1

作为构建过程的一部分我需要使用m4处理一些文件。这些文件以'.in'为扩展名,不仅位于顶级目录中,而且位于子目录中。 我使用find找到它们并在shell循环中处理它们。在makefile中使用m4处理文件

是否有一些makefile语法魔术来编写更简单的规则来处理它们将输出保存到与输入文件相同的目录中的文件(剥离'.in'扩展名)?

这是我在我的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

答案可能是的,但我们中的一些人对m4并不熟悉。你可以显示你现在使用的(最小)makefile吗? – Beta 2012-08-09 11:12:42

+0

嗨,我添加了我当前生成文件的相关部分 – jira 2012-08-09 12:03:45

回答

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使具有用于限定可容纳该后缀规则的替代符号:

.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。)

+0

感谢Jonathan,这对我非常有用。 – jira 2012-08-09 12:14:11

0

如果你有一个源文件path/to/file.in,从%.in使%的规则,并在输出文件path/to/file的依赖,这应该是所有你需要。

也许你想用find的输出来表达你的依赖关系。在GNU中这很容易;在其他方言,也许你想生成和包括像find -name '*.in' | sed 's/\.in$//' >make.dep