2011-10-30 56 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而没有任何先决条件(真的:在任何地方),您将所有目标声明为辅助 - 因此不会自动删除。