如何将不同的文件扩展名指定为多个输出文件的目标?

How can I specify different file extensions as targets for multiple output files?

我想从多个输入文件创建一组输出文件,其中输出格式被指定为目标。例如,对于单一格式:

svg: svg/file1.svg svg/file2.svg

svg/file1.svg svg/file2.svg: %.svg: %.dot
    @dot -T svg -o $@ $<

现在如何在不重复规则和先决条件的情况下添加更多格式?我的方法是这样的:

input := file1 file2
formats := svg png
output := $(foreach format, ${formats}, $(foreach name, ${input}, ${format}/${name}.${format}))
# output := svg/file1.svg svg/file2.svg png/file1.png png/file2.png

all: ${formats}

${formats}: [somehow filter ${output} based on chosen format?]

${output}: [somehow filter out just the file name?]: %.dot
    @dot -T svg -o $@ $<

我无法用变量和模式来解决这个问题。我确实找到了一种使用格式变量的方法;例如,make format=svg,但我宁愿使用目标名称。

使用 GNU Make 4.3。

你会想要为此使用 macro/eval -- 但要注意,这样做,你可能会越过你的 makefile 很容易被其他人 understood/maintained 的那条线。 ,

input := file1 file2
formats := svg png
output := $(foreach format, ${formats}, $(foreach name, ${input}, ${name}.${format}))

all: $(foreach file,$(input),$(foreach format,$(foramts),$(file).$(format)))

define dot_rules
# $ is the basenames,
# $ is the input extension,
# $ is the target extension
$(1:=.) : %. : %.
        @echo dot -T  -o /$$@ $$<


endef

# just to be suure you got it right:
$(info $(foreach format,$(formats),\
    $(call dot_rules,$(input),dot,$(format))))

# expand the calls into the makefile
$(eval $(foreach format,$(formats),\
    $(call dot_rules,$(input),dot,$(format))))