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:
- Look if something in
ctxand/or something inrsthas changed. - If only something in
ctxwas changed, makepdf, else makectx. - If something in
rsthas changed, use the first rule to make the corresponding file inctx, then makectxand then makepdf.
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.
加载中,请稍侯......
精彩评论