在给定的语句变量匹配时,迭代到下一个必备文件

时间:2014-12-31 22:39:27

标签: makefile

我正在尝试用make做这样的事情:

SRC := $(src/*.md)
DIST := $(subst -,/,$(patsubst src/%.md, dist/%/index.html, $(SRC)))

all: $(DIST)

$(DIST): $(SRC)
  mkdir -p $(@D) && pandoc $< -o $@

例如,先决条件src/2014-04-myfile.md与变换dist/2014/04/myfile/index.html

一起放入目标pandoc

但是当我使用$<时,它只引用$(SRC)变量中的第一个参数。

我通常知道我们会这样做:

dist/%.html: src/%.md

但是由于我将输出中的文件名更改为仅index.html所有文件,并使用原始文件名创建新路径,我不知道如何迭代先决条件。

1 个答案:

答案 0 :(得分:2)

这是可以做到的一种方式。这种方式的工作方式是迭代$(SRC)为每个源文件创建一个规则。 $$中的MAKE_DEP是阻止make在首次读取MAKE_DEP内容时解释函数所必需的。 calleval上的文档也很有用。

SRC := $(wildcard src/*.md)

# Set the default goal if no goal has been specified...
.DEFAULT_GOAL:=all

#
# This is a macro that we use to create the rules.
#
define MAKE_DEP
# _target is a temporary "internal" variable used to avoid recomputing
# the current target multiple times.
_target:=$$(subst -,/,$$(patsubst src/%.md, dist/%/index.html, $1))

# Add the current target to the list of targets.
TARGETS:=$$(TARGETS) $$(_target)

# Create the rule proper.
$$(_target):$1
    mkdir -p $$(@D) && pandoc $$< -o $$@

endef # MAKE_DEP

# Iterate over $(SRC) to create each rule.
$(foreach x,$(SRC),$(eval $(call MAKE_DEP,$x)))

.PHONY: all
all: $(TARGETS)

如果我创建:

src/2000-01-bar.md
src/2014-04-foo.md

并运行$ make -n,我得到:

mkdir -p dist/2000/01/bar && pandoc src/2000-01-bar.md -o dist/2000/01/bar/index.html
mkdir -p dist/2014/04/foo && pandoc src/2014-04-foo.md -o dist/2014/04/foo/index.html

这也可以使用secondary expansion完成,但在我看来并不简单或更好。