GNU make有许多目标目录

时间:2009-06-01 09:30:17

标签: makefile release-management gnu-make build-management

我必须在现有Makefile中集成许多HTML文件的生成。 问题是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手册中的Implicit Rule Search Algorithm,规则搜索的工作方式如下:

  
      
  1. 拆分为名为d的目录部分,其余部分称为n。对于   例如,如果t是src/foo.o', then d is src /'且n是`foo.o'。
  2.   
  3. 列出其目标与t或n匹配的所有模式规则。   如果目标模式包含a   斜线,与t匹配;   否则,反对n。
  4.   

为什么没有找到隐式规则,假设使用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)

4 个答案:

答案 0 :(得分: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 $< $@
endef

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

答案 1 :(得分: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 $$@ $$<
endef   

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

.PHONY: all
all: $(html)

答案 2 :(得分:4)

像Maria Shalnova一样,我喜欢递归制作(尽管我不同意“Recursive Make Considered Harmful”),而且一般来说,最好是从某个地方做一些东西,而不是反过来。但如果你必须,我建议稍微改进一下:让generateHtml只生成RULE,而不是COMMANDS。

答案 3 :(得分:3)

另一种可能性是让commando make以每个输出目录的参数-C递归调用自身。 递归make在某种程度上是处理子目录的标准方法,但要注意“Recursive Make Considered Harmful”一文中提到的含义