GNU make with many target directories

后端 未结 4 814
长情又很酷
长情又很酷 2021-02-10 17:02

I have to integrate the generation of many HTML files in an existing Makefile. The problem is that the HTML files need to reside in many different directories. My i

相关标签:
4条回答
  • 2021-02-10 17:34

    Your active implicit rule makes $(rootdir)/build/doc/2009/06/01/some.html depend on $(rootdir)/build/doc/2009/06/01/some.st. If $(rootdir)/build/doc/2009/06/01/some.st doesn't exist then the rule won't be used/found.

    The commented out rule makes $(rootdir)/build/doc/2009/06/01/some.html depend on some.st.

    One solution is to make you're source layout match your destination/result layout.

    Another option is to create the rules as required with eval. But that will be quite complicated:

    define HTML_template
     $(1) : $(basename $(1))
          cp $< $@
    endef
    
    $(foreach htmlfile,$(html),$(eval $(call HTML_template,$(htmlfile))))
    
    0 讨论(0)
  • 2021-02-10 17:34

    An other possibility is to have the commando make call itself recursively with the argument -C with every output directory. Recursive make is somewhat the standard way to deal with subdirectories, but beware of the implications mentioned in the article "Recursive Make Considered Harmful"

    0 讨论(0)
  • 2021-02-10 17:37

    Like Maria Shalnova I like recursive make (though I disagree with "Recursive Make Considered Harmful"), and in general it's better to make something HERE from a source THERE, not the reverse. But if you must, I suggest a slight improvement: have generateHtml generate only the RULE, not the COMMANDS.

    0 讨论(0)
  • 2021-02-10 17:44

    The best solution I found so far is to generate an implicit rule per target directory via foreach-eval-call, as explained in the GNU make manual. I have no idea how this scales to a few thousand target directories, but we will see...

    If you have a better solution, please post it!

    Here is the code:

    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)
    
    0 讨论(0)
提交回复
热议问题