Итерация к следующему обязательному файлу при сопоставлении, когда заданные переменные для оператора

Я пытаюсь сделать что-то подобное с 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 src/2014-04-myfile.md dist/2014/04/myfile/index.html с помощью pandoc

Но когда я использую $< это относится только к первому аргументу в переменной $(SRC).

Я знаю, что мы будем делать что-то вроде:

dist/%.html: src/%.md

но так как я изменил имя файла в выходном файле только на index.html для всех файлов и использовал исходное имя файла для создания нового пути, я не уверен, как идти об итерации по предварительным условиям.

1 ответ

Здесь один из способов сделать это. Как это работает, он выполняет итерацию над $(SRC) чтобы создать одно правило для исходного файла. $$ в MAKE_DEP необходимы для предотвращения make интерпретации функций, когда он сначала считывает содержимое MAKE_DEP. Документация по call и eval также полезна.

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

Это также можно было бы сделать с использованием вторичного расширения, но мне показалось, что это не было проще или приятнее.

licensed under cc by-sa 3.0 with attribution.