为什么.SECONDARY不能用于模式(%)而.PRECIOUS呢?

phi*_*rdy 10 gnu makefile gnu-make

我的问题是更好地理解我在制作过程中错过的内容和.SECONDARY目的与.PRECIOUS,而不是让我的脚本工作,因为它确实有效.

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

如果它适用于现有文件,则在使用生成的文件时,最后会将其删除.

我在.SECONDARY中添加了先决条件但没有帮助,我不得不将其添加到.PRECIOUS中.

这就是为什么不在它工作的问题.SECONDARY?.

从我在SO上找到的 .SECONDARY不能用于模式(%),但即使知道它是否是设计或是否是make中的错误.(.SECONDARY用于GNU MakeMakefile模式规则的模式规则要么忽略虚假规则,要么自发删除输出文件)

这里是我的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 
Run Code Online (Sandbox Code Playgroud)

尝试

做工作/ SoTest

我明白这是标记为中间的.

然后看着我试图将它设置为.SECONDARY:目标列表:也不起作用.

看看make源代码我发现在这个上下文中完成了中间文件的删除:

if (f->intermediate && (f->dontcare || !f->precious)
    && !f->secondary && !f->cmd_target)
Run Code Online (Sandbox Code Playgroud)

所以我将文件设置为.PRECIOUS:现在它可以工作了.

它显示到控制台:

COM /计算器/问题/ 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
Run Code Online (Sandbox Code Playgroud)

为了让它工作,我需要取消注释.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.
Run Code Online (Sandbox Code Playgroud)

phi*_*rdy 16

感谢Alex(见答案)我进一步搜索.

我发现它是在制作项目的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.
Run Code Online (Sandbox Code Playgroud)

只要有意义,这些都应该都是一样的.但没有编码.


Ale*_*ohn 7

回答"为什么.SECONDARY不适用于模式(%),而.PRECIOUS呢?" 在这里:文件说

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

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

  • 这不回答"为什么"; 它回答"这是记录在案的,如果有的话,在哪里?" (3认同)