Make

為什麼我的makefile中沒有規則使另一個目標需要目標

  • June 6, 2019

當我在底部執行 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

當您定義目標時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並且 make 將確定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。

引用自:https://unix.stackexchange.com/questions/523279