我需要帮助削减makefile中的依赖项

我需要帮助削减makefile中的依赖项,makefile,gnu-make,Makefile,Gnu Make,我已经创建了一个生成简单网页的makefile。makefile背后的思想是: 我们正在编译一个网页index.html index.html需要一个必须编译的手写笔cssmain.sty 本页中使用了许多示例 例如,代码one位于lib/examples/one 每个示例包含三个部分 标记(一个.jade模板文件) 一些代码(一个.coffee脚本文件) 描述(一个.md标记文件) 构建脚本必须将每个示例呈现为单个html文件 Jade、Pygments和Markdown用于生成三

我已经创建了一个生成简单网页的makefile。makefile背后的思想是:

  • 我们正在编译一个网页index.html
  • index.html需要一个必须编译的手写笔css
    main.sty
  • 本页中使用了许多示例
    • 例如,代码
      one
      位于
      lib/examples/one
    • 每个示例包含三个部分
      • 标记(一个
        .jade
        模板文件)
      • 一些代码(一个
        .coffee
        脚本文件)
      • 描述(一个
        .md
        标记文件)
  • 构建脚本必须将每个示例呈现为单个html文件
    • Jade、Pygments和Markdown用于生成三个html文件
    • 一个
      example.jade
      模板用于将这些文件合并到一个示例文件中
      • 必须将
        example.jade
        复制到正确的生成示例目录,因为模板语言只能进行相对导入。因此,为了导入
        example/one/code.html
        ,我们必须将模板复制到
        example/one
        ,并使其包含
        code.html
    • 完成后,每个示例
      x
      将编译为
      tbuild/examples/x.html
  • lib/index.jade
    模板移动到
    build
    (以便它可以包含示例文件)
  • 然后使用Jade将
    index.Jade
    模板编译成html
这有点简单,但这样更容易理解。简化的是,每个示例中实际上有两个标记文件(left.html和right.html),代码文件都通过pygments运行并用作脚本,因此code.html和code.coffee都需要将其放入构建中

现在,生成文件如下所示:

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 $< > $@

$(BUILD)/index.jade: $(LIB)/index.jade
    mkdir -p $(@D)
    cp $< $@

$(BUILD)/main.css: $(LIB)/main.sty
    mkdir -p $(@D)
    stylus -u nib < $< > $@

$(BUILDEX)/%.html: $(BUILDEX)/%/template.jade $(BUILDEX)/%/left.html $(BUILDEX)/%/right.html $(BUILDEX)/%/code.html $(BUILDEX)/%/code.coffee $(BUILDEX)/%/text.html
    jade < $< --path $< > $@

$(BUILDEX)/%/template.jade: $(LIBEX)/template.jade
    mkdir -p $(@D)
    cp $< $@

$(BUILDEX)/%/left.html: $(LIBEX)/%/left.jade
    jade < $< --path $< > $@

$(BUILDEX)/%/right.html: $(LIBEX)/%/right.jade
    jade < $< --path $< > $@

$(BUILDEX)/%/code.html: $(LIBEX)/%/code.coffee
    pygmentize -f html -o $@ $<

$(BUILDEX)/%/code.coffee: $(LIBEX)/%/code.coffee
    mkdir -p $(@D)
    cp $< $@

$(BUILDEX)/%/text.html: $(LIBEX)/%/text.md
    markdown < $< > $@

clean:
    rm index.html -f
    rm $(BUILD) -rf
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
LIB=LIB
建造
LIBEX=$(LIB)/示例
BUILDEX=$(构建)/示例
示例=$(addsuffix.html,$(addprefix$(BUILDEX)/,$(shell ls$(LIBEX)| grep-v'.jade'))
全部:$(构建)/main.css index.html
index.html:$(构建)/index.jade$(示例)
jade<$<--path$<>$@
$(构建)/index.jade:$(库)/index.jade
mkdir-p$(@D)
cp$<$@
$(BUILD)/main.css:$(LIB)/main.sty
mkdir-p$(@D)
手写笔-u形笔尖<$<>$@
$(BUILDEX)/%.html:$(BUILDEX)/%/template.jade$(BUILDEX)/%/left.html$(BUILDEX)/%/right.html$(BUILDEX)/%/code.html$(BUILDEX)/%/code.coffee$(BUILDEX)/%/text.html
jade<$<--path$<>$@
$(BUILDEX)/%/template.jade:$(LIBEX)/template.jade
mkdir-p$(@D)
cp$<$@
$(BUILDEX)/%/left.html:$(LIBEX)/%/left.jade
jade<$<--path$<>$@
$(BUILDEX)/%/right.html:$(LIBEX)/%/right.jade
jade<$<--path$<>$@
$(BUILDEX)/%/code.html:$(LIBEX)/%/code.coffee
pygmentize-f html-o$@$<
$(BUILDEX)/%/code.coffee:$(LIBEX)/%/code.coffee
mkdir-p$(@D)
cp$<$@
$(BUILDEX)/%/text.html:$(LIBEX)/%/text.md
降价<$<>$@
清洁:
rm index.html-f
rm$(构建)-rf
这是可行的,但问题是当我触摸“lib/examples/intro/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构建/示例/介绍
cp lib/examples/template.jade build/examples/intro/template.jade
jadebuild/examples/intro/left.html
jadebuild/examples/intro/right.html
pygmentize-f html-o build/examples/intro/code.html lib/examples/intro/code.coffee
mkdir-p构建/示例/介绍
cp lib/examples/intro/code.coffee构建/examples/intro/code.coffee
markdownbuild/examples/intro/text.html
jadebuild/examples/intro.html
jadeindex.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
正如您所注意到的,这远远超出了重新生成示例所需的步骤。我所希望的是更像这样的东西:

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 $< > $@

$(BUILD)/index.jade: $(LIB)/index.jade
    mkdir -p $(@D)
    cp $< $@

$(BUILD)/main.css: $(LIB)/main.sty
    mkdir -p $(@D)
    stylus -u nib < $< > $@

$(BUILDEX)/%.html: $(BUILDEX)/%/template.jade $(BUILDEX)/%/left.html $(BUILDEX)/%/right.html $(BUILDEX)/%/code.html $(BUILDEX)/%/code.coffee $(BUILDEX)/%/text.html
    jade < $< --path $< > $@

$(BUILDEX)/%/template.jade: $(LIBEX)/template.jade
    mkdir -p $(@D)
    cp $< $@

$(BUILDEX)/%/left.html: $(LIBEX)/%/left.jade
    jade < $< --path $< > $@

$(BUILDEX)/%/right.html: $(LIBEX)/%/right.jade
    jade < $< --path $< > $@

$(BUILDEX)/%/code.html: $(LIBEX)/%/code.coffee
    pygmentize -f html -o $@ $<

$(BUILDEX)/%/code.coffee: $(LIBEX)/%/code.coffee
    mkdir -p $(@D)
    cp $< $@

$(BUILDEX)/%/text.html: $(LIBEX)/%/text.md
    markdown < $< > $@

clean:
    rm index.html -f
    rm $(BUILD) -rf
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
mkdir-p构建/示例/介绍
pygmentize-f html-o build/examples/intro/code.html lib/examples/intro/code.coffee
cp lib/examples/intro/code.coffee构建/examples/intro/code.coffee
jadebuild/examples/intro.html
jadeindex.html
换句话说,我要问的是:

  • 当我更改一些小的内容时,我需要做什么才能使makefile不重建太多?
    • 在上面的示例中,当我触摸code.coffee时,left.html、right.html和text.html都会重新生成。我怎样才能防止这种情况
  • 为什么make将rm命令放在输出的末尾?这似乎会导致一些不必要的重建

  • 感谢您一路阅读这个问题!我知道我的makefu是缺乏的,所以任何关于如何清理makefile和减少冗余的提示都是非常受欢迎的

    这个构建系统太大、太复杂,无法轻松复制——我讨厌发布我没有测试过的解决方案——但请尝试添加以下内容:

    .SECONDARY:
    
    编辑:
    我无法重现您描述的行为,但我可以提供一些提示

    .SECONDARY:
    是一条规则;它可以放在makefile中的任何地方。基本上,如果Make检测到一系列隐式规则,a->B->C,其中a是一个存在的文件,C是目标,它会将B视为一个中间文件,并在作业完成后将其删除。
    .SECONDARY:
    规则阻止删除

    可以组合具有相同命令的规则。这:

    foo: bar
        do something $< $@
    
    baz: quartz
        do something $< $@
    
    quince: geef
        do something $< $@
    
    foo:bar
    做一些