Make:制定所有符合规则的内容

发布于 2024-11-29 19:14:26 字数 1003 浏览 0 评论 0原文

我正在尝试学习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。先决条件递归到“第一”。我将手动编辑 ctx 中的文件和 rst 中的文件,这些文件将转换为 ctx 中的文件。

我应该怎么做才能使 make 制作 pdf :) 按以下方式:

  1. 查看 ctx 中的内容和/或 rst 中的内容已更改。
  2. 如果仅更改了 ctx 中的某些内容,则制作 pdf,否则制作 ctx
  3. 如果rst中的内容发生了变化,则使用第一条规则在ctx中制作相应的文件,然后制作ctx,然后制作pdf

我现在的问题是我不知道如何告诉 make “为了在 rst 中的文件发生更改时生成 ctx,请使用第一条规则 (ctx/%.ctx: ctx/%.rst) 使 ctx 中的每个匹配文件与 rst 中的相应文件相匹配”

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

ctx/%.ctx: rst/%.rst
    texlua rst_parser.lua 
lt; $@

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 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉宸 2024-12-06 19:14:26

你的问题有点不清楚(例如,你将目录 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 
lt; $@

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 
lt; $@    

ctx:
  mkdir -p ctx

我制作了 ctx PHONY,因为当目录存在时,我正在努力解决这种情况,但规则仍然应该运行。事实证明这是不必要的(正如你可能从我没有发现拼写错误的事实中猜到的那样)。

是的,先决条件是文件或目录的名称(或 PHONY 目标)。我的观点是,如果 pdf 既是目录又是构建它(并执行其他操作)的规则,那么像“make pdf”这样的短语会有点令人困惑。

使用目录作为目标的问题在于它们不遵守修改时间的直观规则:如果修改目录中的文件,该目录的修改时间不会改变。故意更改 mod 时间也很棘手,因为 touch 不会执行此操作(不要问我为什么 touch 目录在不执行任何操作的情况下是合法的)。例如,可以通过添加和删除虚拟文件来完成,但它很难看。

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 
lt; $@

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 
lt; $@    

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文