Makefile替换模式如何为每个输入产生多个输出?

时间:2018-10-01 16:03:21

标签: gnu-make

在我们的代码库中,我们有一个代码生成器,它使用foo.xyz并生成两个源文件foo-in.cfoo-out.c

在应用程序的Makefile中,我想将来源列出为:

SOURCES=main.c gadget.c foo.xyz

然后相应的OBJECTS变量应扩展为:

OBJECTS=main.o gadget.o foo-in.o foo-out.o

但是我无法找到是否可以使用GNU Make一般进行此扩展。常见的$(SOURCES:.c=.o)替换模式将单个源文件替换为单个目标文件。

如何编写替换模式,每个输入文件会产生多个输出文件?

1 个答案:

答案 0 :(得分:0)

好吧,在写问题时,我找到了一个可用的解决方案。

SOURCES=main.c gadget.c foo.xyz
OBJECTS=$(patsubst %.c,%.o,$(filter %.c,$(SOURCES))) \
    $(patsubst %.xyz,%-in.o,$(filter %.xyz,$(SOURCES))) \
    $(patsubst %.xyz,%-out.o,$(filter %.xyz,$(SOURCES)))

app: $(OBJECTS)
    $(LD) -o $@ $(LDFLAGS) $(OBJECTS)

%-in.c %-out.c: %.xyz
    # Very special codegen rule
    touch $(patsubst %.xyz,%-in.c,$<)
    touch $(patsubst %.xyz,%-out.c,$<)

$(SOURCES)转换为$(OBJECTS)时,请使用两个单独的patsubst调用来筛选出.xyz文件。这样,%-in.o%-out.o文件都位于对象列表中。

另一种解决方案是使用相同的技巧创建中间来源列表,但用相应的xyz-in.c模式替换-out.c。然后可以以传统方式创建对象列表。这种方法的另一个好处是,创建生成所有源代码文件的规则很简单。