2009-06-01 98 views
4

我必須在現有的Makefile中集成許多HTML文件的生成。 問題是HTML文件需要駐留在許多不同的目錄中。 我的想法是寫的源文件(* .ST)轉換爲相應的HTML文件GNU make有許多目標目錄

%.html: %.st 
    $(HPC) -o [email protected] $< 

,並依賴於所有的HTML文件

all: $(html) 

如果HTML規則的隱含規則文件不在builddir中make未找到隱含規則:*** No rule to make target。 如果我改變,像這樣

$(rootdir)/build/doc/2009/06/01/%.html: %.st 
    $(HPC) -o [email protected] $< 

它的發現隱含的規則,但我必須有一個隱含的規則在項目幾乎每一個文件。 根據在GNU make手動Implicit Rule Search Algorithm,規則搜索的工作原理是這樣的:

  1. t分裂成目錄部分,稱爲d,其餘的,所謂的ñ。例如,對於 示例,如果t是src/foo.o', then d is src /'且n是`foo.o'。
  2. 列出其中一個目標匹配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 [email protected] $< 

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

.PHONY: all 
all: $(html) 

回答

4

像瑪麗亞Shalnova我喜歡遞歸make(雖然我不同意「遞歸製作有害」 ),一般情況下,最好從某個來源製造某種東西,而不是相反。但是,如果你必須,我建議稍微改進一下:有generateHtml只生成規則,而不是命令。

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

一個解決方案是讓你的源代碼佈局匹配你的目標/結果佈局。

另一種選擇是按照eval的要求創建規則。但是,這將是相當複雜:

define HTML_template 
$(1) : $(basename $(1)) 
     cp $< [email protected] 
endef 

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

這可行,但不幸的是源佈局是固定的,真正的Makefile使用VPATH。 – 2009-06-01 09:44:50

4

我迄今發現的最好的解決辦法是通過foreach-eval-call生成每個目標目錄中的隱含規則,如GNU make manual解釋。我不知道這是如何擴展到幾千個目標目錄,但我們會看到...

如果您有更好的解決方案,請發佈它!

下面是代碼:

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 [email protected] $$< 
endef 

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

.PHONY: all 
all: $(html) 
+0

我看不到任何其他解決方案,而不是使用某種形式的call-foreach-eval。 GNU make不能很好地處理這種目錄佈局。 (實際上,原作或多或少地假設你將所有源代碼放在一個目錄中。) – JesperE 2009-06-01 12:33:01

3

的另一種可能是有突擊隊make與每一個輸出目錄參數-C遞歸調用本身。 遞歸make有點對付子目錄,但文章中提到的含義提防的標準方法「遞歸製作有害」

+1

好的,遞歸make並沒有出現在我的腦海中。您的解決方案將非常便於攜帶。 – 2009-06-01 13:03:02