4

多くの HTML ファイルの生成を既存の .xml ファイルに統合する必要がありますMakefile。問題は、HTML ファイルが多くの異なるディレクトリに存在する必要があることです。私の考えは、ソース ファイル (*.st) を対応する html ファイルに変換する暗黙のルールを作成することです。

%.html: %.st
    $(HPC) -o $@ $<

およびすべての html ファイルに依存するルール

all: $(html)

HTML ファイルが builddir にない場合、makeは暗黙のルールを検出しません: *** No rule to make target. 暗黙のルールをそのように変更すると

$(rootdir)/build/doc/2009/06/01/%.html: %.st  
    $(HPC) -o $@ $<

見つかりましたが、プロジェクト内のほぼすべてのファイルに対して暗黙のルールを設定する必要があります。GNUマニュアルのImplicit Rule Search Algorithmによると、ルール検索は次のように機能します。make

  1. ターゲット名t全体をdと呼ばれるディレクトリ部分とnと呼ばれる残りの部分に分割します。たとえば、tsrc/foo.oの場合、dsrc/であり、nfoo.oです。
  2. ターゲットの 1 つがtまたはnに一致するすべてのパターン ルールのリストを作成します。ターゲット パターンにスラッシュが含まれている場合は、 tと照合されます。それ以外の場合は、n に対して

暗黙のルールが見つからないのはなぜですか? また、GNUmakeが使用されていると仮定すると、最も洗練されたソリューションは何でしょうか?

これは my の簡略版ですMakefile:

rootdir  = /home/user/project/doc
HPC      = /usr/local/bin/hpc

html = $(rootdir)/build/doc/2009/06/01/some.html

%.html: %.st
    $(HPC) -o $@ $<

#This works, but requires a rule for every output dir
#$(rootdir)/build/doc/2009/06/01/%.html: %.st  
#   $(HPC) -o $@ $<

.PHONY: all
all: $(html)
4

4 に答える 4

5

これまでに見つけた最善の解決策は、 GNU manualで説明されているように、foreach-eval-callを介してターゲット ディレクトリごとに暗黙のルールを生成することです。これが数千のターゲットディレクトリにどのようにスケーリングされるかはわかりませんが、わかります...make

より良い解決策がある場合は、投稿してください。

コードは次のとおりです。

rootdir  = /home/user/project/doc
HPC      = /usr/local/bin/hpc

html = $(rootdir)/build/doc/2009/06/01/some.html \
       $(rootdir)/build/doc/2009/06/02/some.html

targetdirs = $(rootdir)/build/doc/2009/06/01 \
             $(rootdir)/build/doc/2009/06/02

define generateHtml
 $(1)/%.html: %.st
    -mkdir -p $(1)
    $(HPC) -o $$@ $$<
endef   

$(foreach targetdir, $(targetdirs), $(eval $(call generateHtml, $(targetdir))))

.PHONY: all
all: $(html)
于 2009-06-01T12:25:17.630 に答える
4

Maria Shalnova のように、私は再帰的な make が好きです (ただし、「再帰的な Make を有害と見なす」には同意しません)。ただし、必要に応じて、少し改善することをお勧めします。generateHtml でコマンドではなく RULE のみを生成するようにします。

于 2009-06-19T00:39:00.177 に答える
4

アクティブな暗黙のルールは$(rootdir)/build/doc/2009/06/01/some.htmlに依存し$(rootdir)/build/doc/2009/06/01/some.stます。$(rootdir)/build/doc/2009/06/01/some.st存在しない場合、ルールは使用/検出されません。

コメントアウトされたルールは$(rootdir)/build/doc/2009/06/01/some.html依存しsome.stます。

1 つの解決策は、ソース レイアウトを宛先/結果レイアウトと一致させることです。

もう 1 つのオプションは、必要に応じて でルールを作成することですeval。しかし、それは非常に複雑になります。

define HTML_template
 $(1) : $(basename $(1))
      cp $< $@
endef

$(foreach htmlfile,$(html),$(eval $(call HTML_template,$(htmlfile))))
于 2009-06-01T09:36:27.130 に答える
3

もう 1 つの可能性はmake、すべての出力ディレクトリで引数 -C を使用してコマンド自体を再帰的に呼び出すことです。再帰makeは、サブディレクトリを処理するための標準的な方法ですが、「再帰は有害であると見なす」という記事で言及されている影響に注意してください。

于 2009-06-01T12:45:32.443 に答える