带有许多目标目录的 GNU make

Lud*_*erl 4 makefile gnu-make release-management build-management

我必须在现有的 .html 文件中集成许多 HTML 文件的生成Makefile。问题是 HTML 文件需要驻留在许多不同的目录中。我的想法是写一个隐式规则,将源文件(*.st)转换成对应的html文件

%.html: %.st
    $(HPC) -o $@ $<
Run Code Online (Sandbox Code Playgroud)

以及依赖于所有 html 文件的规则

all: $(html)
Run Code Online (Sandbox Code Playgroud)

如果 HTML 文件不在 builddir 中,则make找不到隐式规则:*** No rule to make target. 如果我像这样更改隐式规则

$(rootdir)/build/doc/2009/06/01/%.html: %.st  
    $(HPC) -o $@ $<
Run Code Online (Sandbox Code Playgroud)

它找到了,但是我必须对项目中的几乎每个文件都有一个隐式规则。根据GNU手册中的隐式规则搜索算法make,规则搜索的工作方式如下:

  1. 将整个目标名称t拆分为目录部分,称为d,其余部分称为n。例如,如果tsrc/foo.o,则dsrc/,而nfoo.o
  2. 列出其中一个目标与tn匹配的所有模式规则。如果目标模式包含斜杠,则与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 $@ $<

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

.PHONY: all
all: $(html)
Run Code Online (Sandbox Code Playgroud)

Lud*_*erl 5

到目前为止,我发现的最佳解决方案是通过foreach-eval-call为每个目标目录生成一个隐式规则,如GNUmake手册中所述。我不知道这如何扩展到几千个目标目录,但我们会看到......

如果您有更好的解决方案,请发布!

这是代码:

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)
Run Code Online (Sandbox Code Playgroud)