為什麼我的 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。

相關內容