他のターゲットに必要なターゲットを作成するためのルールがメイクファイルにない理由は何ですか?

他のターゲットに必要なターゲットを作成するためのルールがメイクファイルにない理由は何ですか?

下の 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/すなわち.htmlxhtml/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.htmlxml/foobar.xmlxml/foobar.xml

%「任意のテキストを許可する」を読み、後で使用できるように、対応するランダムmakeテキストを覚えておくことができます。そのため、実行時に「すべてのテキスト」として認識し、記録したようにmake xhtml/foobar.html目標を覚えて評価します。makefoobarfoobarxhtml/foobar.html: xml/foobar.xml

依存関係を作成すると、xhtml/%.htmlターゲットのすべての部分を参照します。繰り返しますが、定式化するルールが見つからないmake xhtml/hello.htmlため失敗します。makexml/hello.xml

Makefile からmakerecipe に達するとmanifold/${MANUSCRIPTNAME}.zip: xhtml/%.html静的ファイル名なので、ターゲット上のどの部分も見つかりません。だから置き換えるものはなく、%ただのバグだと思います。

何を変更したいのかわかりませんが%(そうしないでください)、次のようにコードを改善できると思います。

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

:今、この行には2つあります。新しい中間コンポーネントは、ファイル名から妥当な値を読み取る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のようです。

makePS:逆参照しているような気がするのは変だと思います${}。一般的に私は$()-constructsを使用したいと思います。

関連情報