makefile - 为什么 .SECONDARY 不适用于模式 (%) 而 .PRECIOUS 可以?

标签 makefile gnu gnu-make

我的问题是更好地理解我在 make 过程和 .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: target list : 中也不起作用。

查看 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 work/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 段落。

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

最佳答案

“为什么 .SECONDARY 不适用于模式 (%) 而 .PRECIOUS 可以?”的答案是 here : 文件说

You can also list the target pattern of an implicit rule (such as ‘%.o’) as a prerequisite file of the special target .PRECIOUS



但没有说这关于.SECONDARY .但是对于少数明确的异常(exception),没有一个特殊目标接受模式。

关于makefile - 为什么 .SECONDARY 不适用于模式 (%) 而 .PRECIOUS 可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27090032/

相关文章:

java - 使用 java gnu 串行端口类

c++ - 相当于 gnu 中 windows stdint.h 的 u_int16_t?

c - 试图粉碎堆栈

makefile - 我们可以在 makefile 中取消定义/取消设置变量吗

Makefile 通用模式规则 -- 来自 xyzzy.ext0 的 xyzzy-en_US.ext2

c - GCC 链接器问题与 -lm 标志

c - 是否可以在 makefile 中定义 C 宏?

build-process - 多个规则指定同一个假依赖,依赖只执行一次

c++ - g++ 不产生调试符号

linux - eval 创建规则时 Makefile 中目标的顺序