【问题标题】:Why .SECONDARY does not work with patterns (%) while .PRECIOUS does?为什么 .SECONDARY 不适用于模式 (%) 而 .PRECIOUS 可以?
【发布时间】:2014-11-23 14:31:46
【问题描述】:

我的问题是更好地了解我在制作过程中错过了什么以及 .SECONDARY 目的与 .PRECIOUS,而不是让我的脚本工作,因为它已经工作了。

我正在使用 make 在文件上打开 emacs 编辑器(java 但与此问题无关)或使用模板创建它(如果不存在)。

如果它适用于现有文件,当使用生成的文件时,它会在最后被删除

我在 .SECONDARY 中添加了先决条件,但没有帮助,我必须在 .PRECIOUS 中添加它。

这是一个问题为什么它在 .SECONDARY 中不起作用?

根据我在 SO 上找到的内容 .SECONDARY 不适用于模式 (%),但即使知道我想知道它是设计使然还是制造中的错误。 (.SECONDARY for a pattern rule with GNU MakeMakefile pattern rule either ignores phony rule or spontaneously deletes output file

这里是我的 Makefile 的精简内容以重现我的问题(请创建一个 com/stackoverflow/question 目录来测试它)。

PACKAGE=com.stackoverflow.question
PACKAGE_DIR=$(subst .,/,$(PACKAGE))
OUT=out

clean:
    find $(OUT) -name "*.class" -type f -print0|xargs -0 rm

# does not work : deleted at end due to intermediate file removal.
$(PACKAGE_DIR)/%.java:
    @echo "package com.stackoverflow.question;\npublic class $(subst .java,,$(subst $(PACKAGE_DIR)/,,$@))\n{\n /** TODO */ \n}" >$@ 

work/%: $(PACKAGE_DIR)/$(subst work/,,%).java
    emacs $<

.PHONY: clean work/%

# tried to avoid intermediate file removal : does not work
.SECONDARY: $(PACKAGE_DIR)/%.java 

# if not commented this does work : once precious intermediate file is not removed.
#.PRECIOUS: $(PACKAGE_DIR)/%.java 

试试

开始工作/SoTest

我知道这是标记为中间的。

然后查看 SO,我尝试将其设置为 .SECONDARY:目标列表:也不起作用。

查看 make 源代码,我发现 make 中间文件的删除是在此上下文中完成的:

if (f->intermediate && (f->dontcare || !f->precious)
    && !f->secondary && !f->cmd_target)

所以我在 .PRECIOUS: 中设置了我的文件,现在它可以工作了。

显示到控制台:

com/stackoverflow/question/SoTest.java

它运行带有正确模板的 emacs,因此可以创建 这里我退出 emacs

它会在最后删除文件

rm com/stackoverflow/question/SoTest.java

最后删除是由于中间文件,这可以通过 make 上的 -d 选项看到

LANG=C make -d 工作/SoTest

...
Must remake target 'work/SoTest'.
emacs com/stackoverflow/question/SoTest.java
Putting child 0xc3b580 (work/SoTest) PID 20681 on the chain.
Live child 0xc3b580 (work/SoTest) PID 20681 
Reaping winning child 0xc3b580 PID 20681 
Removing child 0xc3b580 PID 20681 from chain.
Successfully remade target file 'work/SoTest'.
Removing intermediate files...
rm com/stackoverflow/question/SoTest.java

要让它工作,我需要取消注释 .PRECIOUS 段落。

制作 --version

GNU Make 4.0
Construit pour x86_64-pc-linux-gnu
Copyright (C) 1988-2013 Free Software Foundation, Inc.
Licence GPLv3+ : GNU GPL version 3 ou ultérieure <http://gnu.org/licenses/gpl.html>
Ceci est un logiciel libre : vous êtes autorisé à le modifier et à la redistribuer.
Il ne comporte AUCUNE GARANTIE, dans la mesure de ce que permet la loi.

【问题讨论】:

  • stackoverflow.com/questions/17625394/… 表示 .PRECIOUS 适用于模式,但奇怪的是,不是 .SECONDARY。 可以解释这种行为。
  • 我们显然不能使用 %.out 作为 .SECONDARY 的目标。 似乎是stackoverflow.com/questions/19883282/…的另一个确认
  • 请注意,.PRECIOUS 在用作 .SECONDARY 的替代品时有一个缺点:make 不会因为信号而在中断时删除文件,这打开了部分写入的目标文件到达链接器的可能性( source).

标签: makefile gnu gnu-make


【解决方案1】:

感谢 Alex(查看答案),我在搜索中走得更远。

我发现是在make project的TODO.private中记录了15年......

使用 git://git.savannah.gnu.org/make.git 你可以看到 TODO.private 内容的历史:

 6) Right now the .PRECIOUS, .INTERMEDIATE, and .SECONDARY
    pseudo-targets have different capabilities.  For example, .PRECIOUS
    can take a "%", the others can't.  Etc.  These should all work the
    same, insofar as that makes sense.

只要有意义,这些都应该工作相同。但没有编码。

【讨论】:

    【解决方案2】:
    “为什么 .SECONDARY 不适用于模式 (%) 而 .PRECIOUS 可以?” 的答案是 here:文档说

    您还可以将隐式规则的目标模式(例如'%.o')列为特殊目标.PRECIOUS的必备文件

    但没有提到.SECONDARY。但是对于少数明确的例外,没有一个特殊目标接受模式。

    【讨论】:

    • 这没有回答“为什么”;它回答“这是记录在案的,如果是,在哪里?”
    • @Kaz,我同意 Phillippe 终于找到了对 why 问题的更深层次的答案(尚未编码)。尽管如此,我的“但对于少数明确的例外,没有一个特殊目标接受模式”完全回答了这个问题。比如,为什么为什么猕猴有尾巴?:“除了猿和极少数其他哺乳动物,所有哺乳动物都有尾巴,所以猕猴跟风”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    相关资源
    最近更新 更多