开发者

Make: make all that fit rule

I’m trying to learn makefiles. I have the following Makefile:

ctx/%.ctx: rst/%.rst
    texlua rst_parser.lua $< $@

pdf: ctx
    mkdir -p pdf
    cd pdf; context ../ctx/main.ctx

ctx: rst
    mkdir -p ctx

.PHONY: clean
clean:
    rm -f pdf/*.log pdf/*.aux pdf/*.pgf pdf/*.top pdf/*.tuc

As you can see, all three prerequisites are directories; rst, ctx and pdf. The prerequisites recurse down to “rst”. I’ll edit files in ctx manually and files in rst, which get converted into files in ctx.

What should I开发者_如何学JAVA do to make make make pdf :) the following way:

  1. Look if something in ctx and/or something in rst has changed.
  2. If only something in ctx was changed, make pdf, else make ctx.
  3. If something in rst has changed, use the first rule to make the corresponding file in ctx, then make ctx and then make pdf.

My problem is now that I don’t know how to tell make “In order to make ctx when files in rst are changed, use the first rule (ctx/%.ctx: ctx/%.rst) to make each matching file in ctx from the corresponding one in rst


Your question is a little unclear (e.g. you're confusing the directory pdf/ with the makefile target pdf), but this should do what I think you want:

TARGETS := $(wildcard rst/*.rst)
TARGETS := $(patsubst rst/%.rst,%,$(TARGETS))

ctx/%.ctx: rst/%.rst    # I assume you didn't mean ctx/%.rst
  texlua rst_parser.lua $< $@

pdf: ctx
  mkdir -p pdf
  cd pdf; context ../ctx/main.ctx

.PHONY:cxt
ctx: $(patsubst %,ctx/%.ctx, $(TARGETS))
  mkdir -p ctx

And the reason a plain make builds pdf is that when you invoke Make without a target it chooses the default target, which is the first target (unless you do some tinkering), which in this case is pdf. (The pattern rule doesn't count.)

EDIT:
Now that I think of it, what I posted above is kind of clunky, and it will always run the pdf rule, even if nothing has changed. This is somewhat better:

# You're right, this is better.        
CTX_TARGETS := $(patsubst rst/%.rst,ctx/%.ctx, $(wildcard rst/*.rst))

pdf: $(CTX_TARGETS)
  mkdir -p pdf
  cd pdf; context ../ctx/main.ctx

$(CTX_TARGETS): ctx/%.ctx: rst/%.rst ctx
  texlua rst_parser.lua $< $@    

ctx:
  mkdir -p ctx

I made ctx PHONY because I was wrestling with the case when the directory exists, but the rule should still be run. It turned out to be unnecessary (as you might guess from the fact that I didn't catch the typo).

And yes, prerequisites are the names of files or dirs (or PHONY targets). My point was that phrases like "make pdf" are a little confusing if pdf is both a directory and a rule which builds it (and does other things).

The problem with using directories as targets is that they don't obey intuitive rules of modification time: if you modify a file in a directory, the directory's mod time doesn't change. It's also tricky to change the mod time deliberately, since touch doesn't do it (don't ask me why it's legal to touch a directory if it does nothing). It can be done, e.g. by adding and deleting a dummy file, but it's ugly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜