2

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

是否有一些 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
4

2 回答 2

4

您可以编写一组规则来将带有后缀.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.inand .h,但是在两者之间进行转换的规则会以.h.in.h:and开头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.inor.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。)

于 2012-08-09T11:32:11.763 回答
0

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

也许您想根据find. 在 GNU Make 中,这很容易;在其他方言中,也许您想生成并包含类似find -name '*.in' | sed 's/\.in$//' >make.dep

于 2012-08-09T11:18:41.973 回答