Warum gibt es in meinem Makefile keine Regel, um ein Ziel für ein anderes Ziel erforderlich zu machen?

Warum gibt es in meinem Makefile keine Regel, um ein Ziel für ein anderes Ziel erforderlich zu machen?

Wenn ich das Makefile unten ausführe, erhalte ich die folgende Fehlermeldung:

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

Ich verstehe diesen Fehler nicht, da es eine Regel mit Ziel gibt xhtml/%.html. Warum zählt diese Regel nicht?

Ich führe dies in einem Ordner aus, der die Datei enthält 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

Antwort1

Wenn Sie das Ziel definieren, xhtml/%.htmlerstellen Sie kein Rezept für eine einzelne Datei, sondern ein Rezept füralle Dateien, die diesem Muster entsprechen, also alle Dateien xhtml/mit der .htmlEndung xhtml/foobar.html.

Zum Beispiel, wenn wir die folgenden Ziele setzen:

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>' >$@

wir können es jetzt ausprobieren make xhtml/foobar.htmlund werden feststellen, was xhtml/foobar.htmldavon abhängt xml/foobar.xmlund werden daher zuerst schauen, xml/foobar.xmlwofür wir ein Rezept zur Hand haben.

Das %kann als „beliebigen Text zulassen“ gelesen werden und makemerkt sich diesen beliebigen Text für die weitere Verwendung. Wenn wir also ausführen make xhtml/foobar.html, makeerkennt es foobarals „beliebigen Text“, merkt sich foobardas Ziel und wertet es aus, als hätten wir geschrieben xhtml/foobar.html: xml/foobar.xml.

Wenn Sie xhtml/%.htmlals Abhängigkeit angeben, beziehen Sie sich auf den beliebigen Teil des Ziels. Ebenso make xhtml/hello.htmlwird fehlschlagen, weil makekeine Regel zum Erstellen gefunden werden kann xml/hello.xml.

Wenn Ihr Makefile makedas Rezept erreicht , manifold/${MANUSCRIPTNAME}.zip: xhtml/%.htmlkann es keinen beliebigen Teil im Ziel finden, da es sich um einen statischen Dateinamen handelt. Daher gibt es nichts, womit es ersetzt werden könnte, %und ich denke, das wird einfach als Fehler angesehen.

Ich weiß nicht, was Du da ersetzen willst %(und so auch nicht machst), aber ich denke, Du kannst Deinen Code hiermit verbessern:

manifold/$(MANUSCRIPTNAME).zip: manifold/%.zip: xhtml/%.html

:Beachten Sie, dass diese Zeile jetzt zwei enthält . Die neue mittlere Komponente gibt an, wie aus Ihrem Dateinamen makeein sinnvoller Wert gelesen werden soll .%

Alternativ können Sie Folgendes eingeben:

# as your first recipe
default: manifold/$(MANUSCRIPTNAME).zip

# and then
manifold/%.zip: xhtml/%.html
    [...your recipe...]

Oder auch:

.DEFAULT_GOAL: manifold/$(MANUSCRIPTNAME).zip
manifold/%.zip: xhtml/%.html
    [...your recipe...]

Aber ich glaube, Letzteres ist nur GNU Make.

PS: Ich finde es sehr seltsam, dass makeanscheinend dereferenziert werden kann ${}. Normalerweise würde ich erwarten, dass wir -Konstrukte verwenden $().

verwandte Informationen