
При запуске makefile внизу я получаю ошибку:
make: *** No rule to make target 'xhtml/%.html', needed by 'manifold/01_doehmer_syntax_pre.zip'. Stop.
Я не понимаю эту ошибку, потому что есть правило с целью xhtml/%.html
. Почему это правило не учитывается?
Я запускаю это в папке, содержащей файл 01_doehmer_aspekte.docx
.
BINDIR:=~/TEIC-XSLT/bin
PROFDIR:=/mnt/c/Users/niels-oliver.walkows/OneDrive/Dokumente/Luxemburg/Melusinapress/Transformationen/xslt/TEIC/profiles
MANUSCRIPTFILE:=$(shell ls *.docx)
MANUSCRIPTNAME:=$(shell basename ${MANUSCRIPTFILE} .docx)
.PHONY : all clean
all: manifold/${MANUSCRIPTNAME}.zip
tei/%.xml: %.docx
mkdir -p tei
${BINDIR}/docxtotei --profiledir=${PROFDIR} --profile=melusina $< $@
xhtml/%.html: tei/%.xml
mkdir -p xhtml
${BINDIR}/teitohtml --profiledir=${PROFDIR} --profile=melusina $< $@
cp -r tei/media xhtml/
manifold/${MANUSCRIPTNAME}.zip: xhtml/%.html
mkdir -p manifold
touch manifold/manifest.yml
cp -r tei/media manifold/
cp -r xhtml/*.html manifold/
cd manifold && zip -r ${MANUSCRIPTNAME}.zip manifest.yml media *.html
rm -rf manifold/media manifold/${MANUSCRIPTNAME}.html
test:
echo "${MANUSCRIPTFILE}"
echo "${MANUSCRIPTNAME}"
clean:
rm -rf tei xhtml manifold
решение1
Когда вы определяете цель, xhtml/%.html
вы создаете рецепт не для одного файла, а длявсе файлы, соответствующие этому шаблону, т. е. все файлы xhtml/
с .html
суффиксом, например xhtml/foobar.html
.
Например, когда мы ставим следующие цели:
xhtml/%.html: xml/%.xml
xsltproc magic.xsl $< > $@
xml/foobar.xml:
echo '<?xml version="1.0"?><a><b><c some="attr">Lorep Ipsum</c><c some="other">Dorlor si amet</c></b></a></xml>' >$@
теперь мы можем запустить make xhtml/foobar.html
и сделать определите, что xhtml/foobar.html
зависит от xml/foobar.xml
и поэтому сначала попробуем создать xml/foobar.xml
то, для чего у нас есть рецепт под рукой.
Можно %
прочитать как «разрешить произвольный текст» и make
запомнить этот произвольный текст для дальнейшего использования. Поэтому, когда мы запускаем make xhtml/foobar.html
, make
распознает foobar
как «произвольный текст», запоминает foobar
и оценивает цель, как если бы мы написали xhtml/foobar.html: xml/foobar.xml
.
Когда вы ставите xhtml/%.html
как зависимость, вы ссылаетесь на произвольную часть цели. Аналогично, make xhtml/hello.html
не получится, потому что make
не будет возможности найти правило, чтобы сделать xml/hello.xml
.
В вашем Makefile, когда make
он достигает рецепта, manifold/${MANUSCRIPTNAME}.zip: xhtml/%.html
он не может найти произвольную часть в цели, потому что это статическое имя файла. В результате ему нечем заменить, %
и я думаю, что это просто считается ошибкой.
Я не знаю, что вы хотите заменить %
(и поэтому не делает), но я думаю, что вы можете улучшить свой код с помощью этого:
manifold/$(MANUSCRIPTNAME).zip: manifold/%.zip: xhtml/%.html
Обратите внимание, что теперь в этой строке их два :
. Новый средний компонент сообщает, make
как считывать разумное значение %
из вашего имени файла.
В качестве альтернативы вы можете указать:
# as your first recipe
default: manifold/$(MANUSCRIPTNAME).zip
# and then
manifold/%.zip: xhtml/%.html
[...your recipe...]
Или даже:
.DEFAULT_GOAL: manifold/$(MANUSCRIPTNAME).zip
manifold/%.zip: xhtml/%.html
[...your recipe...]
Но я думаю, что последний доступен только GNU Make.
PS: Я думаю, что это очень странно, что, make
кажется, (можно) разыменовывать ${}
. Обычно я ожидаю, что мы используем $()
-конструкции.