为什么我的 makefile 中没有规则来创建另一个目标所需的目标

为什么我的 makefile 中没有规则来创建另一个目标所需的目标

当我运行底部的 makefile 时,收到错误:

make: *** No rule to make target 'xhtml/%.html', needed by 'manifold/01_doehmer_syntax_pre.zip'.  Stop.

我不明白这个错误,因为 target 有一个规则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.htmlmake识别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似乎(能够)取消引用${}。通常我希望我们使用$()-constructs。

相关内容