سؤال

I have a bunch of text files in the help_pages/ directory, all formatted in reST. I'm trying to add to my GNU make Makefile a couple of rules that:

  1. Run each file in the help_pages directory (and sub-directories) with the extension '.rst' through an app that spits out a valid html file (right now I'm just using rst2html).
  2. Copy those output html files to a target directory, reproducing the directory structure that existed in the help_pages directory.

So, for example, help_pages/some/dir/foo.rst would first get translated to help_pages/some/dir/foo.html, and then copied to public/help/some/dir/foo.html.

I've spent all day trying to learn the intracacies of Makefiles, but in the end I gave up. Here's what I have already:

# Directory that the .rst files reside in:
HELP_DIR=help_pages
# use 'find' to locate all such files:
HELP_SRCS=$(shell find $(HELP_DIR) -name "*.rst")
# work out what path the intermediate files would be
HELP_TARGETS=$(HELP_SRCS:.rst=.html)

# do the translation.   
$(HELP_TARGETS): %.html: %.rst
        rst2html $< $@

help: $(HELP_TARGETS) 

.phony:
        help

This kind-of works - the .rst files get translated to .html files, but I have no idea how to install them into the final, target directory. If I add a cp command to the main build recipe, the files are not re-installed if they don't exist in the target directory.

Ideally I'd like a target to make the help files, and one to install them, and a third (called 'help') that depends on these two. I think this will give me the greatest flexibility.

Can anyone give me some tips on how to achieve this?

Cheers,

هل كانت مفيدة؟

المحلول

"I've spent all day trying to learn the intracacies of Makefiles, but in the end I gave up." You don't know how funny that is.

This should do it:

HELP_DIR=help_pages
# use 'find' to locate all such files:
HELP_SRCS=$(shell find $(HELP_DIR) -name "*.rst")
# work out what path the intermediate files would be
HELP_TARGETS=$(HELP_SRCS:.rst=.html)
# and the destinations
HELP_INSTALL = $(patsubst help_pages%,public%,$(HELP_TARGETS))

# do the translation.
$(HELP_TARGETS): %.html: %.rst
    rst2html $< $@          

# do the installation
$(HELP_INSTALL):public/%:help_pages/%
    cp $< $@

.PHONY: help install

help: $(HELP_TARGETS)

install:$(HELP_INSTALL)

Now if you want to do everything, just make install. Or if you want to create the html files without copying them into public/, just make help. You'll find that the dependencies work correctly.

نصائح أخرى

make has "smart" treatment of pathnames with directory separators which makes it a royal pain to write rules that do things across different directories.

One workaround is to do the copying as a side effect of the conversion, e.g. adding something this as a second command might work:

echo $@ | cpio -pdl public/html

BTW, .PHONY is in capitals.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top