質問

多くの HTML ファイルの生成を既存のファイルに統合する必要があります。 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では make 手動の場合、ルール検索は次のように機能します。

  1. t を d というディレクトリ部分と、n という残りの部分に分割します。たとえば、tが場合 src/foo.o', then d issrc/'、n は `foo.o' です。
  2. ターゲットの 1 つが t または n に一致するすべてのパターン ルールのリストを作成します。ターゲットパターンにスラッシュが含まれている場合、Tと一致します。それ以外の場合は、n に対して。

暗黙のルールが見つからない理由と、GNU を前提とした場合の最も洗練された解決策は何ですか make 使用されている?

これは私のものを取り除いたバージョンです 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)
役に立ちましたか?

解決

マリアShalnovaのように私は(私は「有害と考えられ再帰メイク」に反対するが)再帰的なメイクが好き、そして一般的にはTHEREソース、逆ではないから、ここで何かを作る方が良いでしょう。あなたがしなければならない場合でも、私は若干の改善が示唆さ:generateHtmlが唯一のルールではなく、コマンドを生成しています。

他のヒント

私がこれまでに見つけた最良の解決策は、ターゲット ディレクトリごとに暗黙的なルールを生成することです。 foreach-eval-call, で説明されているように、 GNU 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)

あなたのアクティブな暗黙のルールが$(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.htmlsome.stに依存になります。

一つの解決策は、あなたが元のレイアウトは、あなたの目的地/結果のレイアウトに合わせているようにすることです。

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

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

$(foreach htmlfile,$(html),$(eval $(call HTML_template,$(htmlfile))))

他の可能性は、すべての出力ディレクトリと引数-Cで自分自身を再帰的に呼び出すmakeコマンドーを持つことです。 再帰makeは、多少のサブディレクトリに対処するための標準的な方法ですが、資料に記載意味合いの用心

「再帰的なメイク有害と考えられ」
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top