我的问题是更好地理解我在制作过程和 .SECONDARY 目的与 .PRECIOUS 中错过的内容,而不是让我的脚本工作,因为它已经工作了。
我正在使用 make 打开文件上的 emacs 编辑器( java 但与此问题的目的无关),或者使用模板创建它(如果不存在)。
如果它适用于现有文件,使用生成的文件时,它在最后被删除.
我在 .SECONDARY 中添加了先决条件,但没有帮助,我必须将其添加到 .PRECIOUS 中。
这是问题为什么它在 .SECONDARY 中不起作用? .
从我在SO上发现的.SECONDARY 不适用于模式 ( % ),但即使知道我想知道这是设计使然还是 make 中的错误。 (.SECONDARY 用于 GNU Make 的模式规则 https://stackoverflow.com/questions/17625394/secondary-for-a-pattern-rule-with-gnu-make and Makefile 模式规则要么忽略虚假规则,要么自发删除输出文件 https://stackoverflow.com/questions/19883282/makefile-pattern-rule-either-ignores-phony-rule-or-spontaneously-deletes-output/19892035#19892035 )
这里是我的 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
try
制作工作/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 段落。
制作--版本
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.