2011-10-30 57 views
4

我已經創建了生成簡單網頁的生成文件。 makefile文件背後的想法是這樣的: 我需要幫助修改生成文件中的依賴項

  • 有使用

    • 我們正在編制一個網頁,index.html的
    • index.html的需要手寫筆的CSS main.sty必須編制了大量的實例在頁面
      • 例如代碼one生活lib/examples/one
      • 每個示例包含三個部分
    • 構建腳本必須呈現每個例子成單個的標記(一個.jade模板文件)
    • 某些代碼(一個.coffee腳本文件)
    • 說明(一個.md降價文件) HTML文件
      • 玉,Pygments來做,和降價來生成三個HTML文件
      • example.jade模板用於將這些文件合併爲一個示例文件
        • example.jade必須複製到正確的生成示例目錄,因爲模板語言只能執行相對導入。因此,要導入example/one/code.html,我們必須將模板複製到example/one,並使其包含code.html
      • 完成時,每個實施例x將已編譯爲tbuild/examples/x.html
    • lib/index.jade模板移動到build(以便它可以包括例如文件)然後
    • 翡翠用於編譯index.jade將模板轉換爲html

    這是一個簡化的過程,但這樣更容易理解。簡化是在每個示例中實際上有兩個標記文件(left.html和right.html),並且代碼文件都通過作爲腳本的運行,因此code.html和代碼。咖啡需要使它成爲構建。

    眼下,生成文件看起來是這樣的:

    LIB = lib 
    BUILD = build 
    LIBEX = $(LIB)/examples 
    BUILDEX = $(BUILD)/examples 
    EXAMPLES = $(addsuffix .html,$(addprefix $(BUILDEX)/,$(shell ls $(LIBEX) | grep -v '.jade'))) 
    
    all: $(BUILD)/main.css index.html 
    
    index.html: $(BUILD)/index.jade $(EXAMPLES) 
        jade < $< --path $< > [email protected] 
    
    $(BUILD)/index.jade: $(LIB)/index.jade 
        mkdir -p $(@D) 
        cp $< [email protected] 
    
    $(BUILD)/main.css: $(LIB)/main.sty 
        mkdir -p $(@D) 
        stylus -u nib < $< > [email protected] 
    
    $(BUILDEX)/%.html: $(BUILDEX)/%/template.jade $(BUILDEX)/%/left.html $(BUILDEX)/%/right.html $(BUILDEX)/%/code.html $(BUILDEX)/%/code.coffee $(BUILDEX)/%/text.html 
        jade < $< --path $< > [email protected] 
    
    $(BUILDEX)/%/template.jade: $(LIBEX)/template.jade 
        mkdir -p $(@D) 
        cp $< [email protected] 
    
    $(BUILDEX)/%/left.html: $(LIBEX)/%/left.jade 
        jade < $< --path $< > [email protected] 
    
    $(BUILDEX)/%/right.html: $(LIBEX)/%/right.jade 
        jade < $< --path $< > [email protected] 
    
    $(BUILDEX)/%/code.html: $(LIBEX)/%/code.coffee 
        pygmentize -f html -o [email protected] $< 
    
    $(BUILDEX)/%/code.coffee: $(LIBEX)/%/code.coffee 
        mkdir -p $(@D) 
        cp $< [email protected] 
    
    $(BUILDEX)/%/text.html: $(LIBEX)/%/text.md 
        markdown < $< > [email protected] 
    
    clean: 
        rm index.html -f 
        rm $(BUILD) -rf 
    

    這工作,但問題是,當我觸摸「的lib /例子/前奏/ code.coffee」並重新運行make,我得到以下內容:

    mkdir -p build/examples/intro 
    cp lib/examples/template.jade build/examples/intro/template.jade 
    jade < lib/examples/intro/left.jade --path lib/examples/intro/left.jade > build/examples/intro/left.html 
    jade < lib/examples/intro/right.jade --path lib/examples/intro/right.jade > build/examples/intro/right.html 
    pygmentize -f html -o build/examples/intro/code.html lib/examples/intro/code.coffee 
    mkdir -p build/examples/intro 
    cp lib/examples/intro/code.coffee build/examples/intro/code.coffee 
    markdown <lib/examples/intro/text.md> build/examples/intro/text.html 
    jade < build/examples/intro/template.jade --path build/examples/intro/template.jade > build/examples/intro.html 
    jade < build/index.jade --path build/index.jade > index.html 
    rm build/examples/intro/right.html build/examples/intro/code.coffee build/examples/intro/code.html build/examples/intro/left.html build/examples/intro/text.html build/examples/intro/template.jade 
    

    哪像你會發現,是遠遠超過做需要再生的例子。我所期待的是像這樣的東西更多:

    mkdir -p build/examples/intro 
    pygmentize -f html -o build/examples/intro/code.html lib/examples/intro/code.coffee 
    cp lib/examples/intro/code.coffee build/examples/intro/code.coffee 
    jade < build/examples/intro/template.jade --path build/examples/intro/template.jade > build/examples/intro.html 
    jade < build/index.jade --path build/index.jade > index.html 
    

    換句話說,就是我要問的是:

    1. 什麼我需要做的,使生成文件不重建時太多我改變一些小事?
      • 在上述例子中,left.html,right.html,和text.html都是重修時我觸摸code.coffee。我怎樣才能防止這一點?
    2. 爲什麼讓在輸出端把rm命令?這似乎可能會導致一些不必要的重建。

    感謝您在此獸問題的閱讀一路走好!我知道我的make-fu缺乏,所以關於如何清理makefile並減少冗餘的任何提示都值得歡迎!

  • 回答

    4

    此版本系統過於龐大和複雜重現容易 - 我恨後我還沒有測試的解決方案 - 但嘗試加入這一行:

    .SECONDARY: 
    

    編輯:
    我一直沒有能夠重現你描述的行爲,但我可以提供一些指示。

    .SECONDARY:是一個規則;它可以在makefile中的任何位置。基本上,如果Make檢測到一條隱含規則鏈,A-> B-> C,其中A是存在的文件,C是目標文件,則它認爲B是中間文件,並且在作業完成後將刪除它完成。 .SECONDARY:規則會阻止刪除。

    您可以組合具有相同命令的規則。這:

    foo: bar 
        do something $< [email protected] 
    
    baz: quartz 
        do something $< [email protected] 
    
    quince: geef 
        do something $< [email protected] 
    

    可以改寫成這樣:

    foo: bar 
    
    baz: quartz 
    
    quince: geef 
    
    foo baz quince: 
        do something $< [email protected] 
    

    這將在你的makefile免去很多冗餘的,也許讓事情更清晰。

    +0

    我知道它很複雜,但我找不到一種方法來簡化它,仍然存在依賴性問題。 :/我的牛努使技能缺乏。 SECONDARY行應該添加在哪裏?它做什麼,爲什麼它會有幫助?謝謝! – So8res

    +0

    謝謝!這些是我正在尋找的技巧。 – So8res

    2

    像@Beta提到的,你正在運行到這裏與中間文件的麻煩。

    在Makefile中沒有明確提到但是通過模式規則(與%相關的規則)推斷的每個文件都是中間文件,並在make運行後立即刪除。然後在下一次運行中重新制作。

    這就是你的「問題」的核心:left.html和right.html文件被馬上刪除。 Beta已經提到,聲明他們爲.SECONDARY修復了這個問題,如the make manual tells you

    通過在Makefile中的任何位置聲明目標.SECONDARY而沒有任何先決條件(真的:在任何地方),您將所有目標聲明爲輔助 - 因此不會自動刪除。