制作:做出所有合适的规则

时间:2011-08-15 15:42:31

标签: makefile

我正在尝试学习makefile。 我有以下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

如您所见,所有三个先决条件都是目录; rstctxpdf。先决条件递归到“rst”。我将手动编辑ctx中的文件和rst中的文件,这些文件将转换为ctx中的文件。

我应该如何通过以下方式使make成为pdf :):

  1. 查看ctx中的某些内容和/或rst中的内容是否已更改。
  2. 如果只更改了ctx中的内容,请创建pdf,否则生成ctx
  3. 如果rst中的内容发生了变化,请使用第一条规则在ctx中制作相应的文件,然后制作ctx,然后制作pdf
  4. 现在我的问题是我不知道如何告诉make“为了在ctx中的文件发生更改时rst,请使用第一条规则({{1 } {}使ctx/%.ctx: ctx/%.rst中的每个匹配文件来自ctx

    中的相应文件

1 个答案:

答案 0 :(得分:1)

您的问题有点不清楚(例如,您将目录pdf/与makefile目标pdf混淆),但这应该是我认为您想要的:

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

普通make构建pdf的原因是,当你调用没有目标的Make时,它选择默认目标,这是第一个目标(除非你做一些修补),在此案例是pdf。 (模式规则不计算在内。)

修改:
现在我想到了,我上面发布的内容有点笨拙,即使没有任何改变,也会始终运行pdf规则。这有点好:

# 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

我做了ctx PHONY,因为当目录存在时,我正在努力解决这个问题,但仍应运行规则。事实证明这是不必要的(正如你可能从我没有发现错字的事实中猜到的那样)。

是的,先决条件是文件或目录(或PHONY目标)的名称。我的观点是,如果pdf既是目录又是构建它的规则(以及做其他事情),那么像“make pdf”这样的短语会有点混乱。

使用目录作为目标的问题是它们不遵守修改时间的直观规则:如果修改目录中的文件,目录的mod时间不会改变。故意改变模拟时间也很棘手,因为touch没有这样做(如果它什么也没做的话,不要问我为什么touch目录是合法的。它可以完成,例如,通过添加和删除虚拟文件,但它很难看。