¿Por qué .SECONDARY no funciona con patrones (%) mientras que .PRECIOUS sí?

Mi pregunta es comprender mejor lo que me perdí en el proceso de creación y el propósito SECUNDARIO frente a. PRECIOSO, no hacer que mi script funcione, ya que ya funciona.

Estoy usando make para abrir un editor de emacs en un archivo (java pero irrelevante para el propósito de esta pregunta) o para crearlo con una plantilla si no existe.

Si funciona bien con archivos existentes,cuando se utiliza el archivo generado, se elimina al final.

Agregué el requisito previo en .SECONDARY pero no lo ayudé, tuve que agregarlo en .PRECIOUS.

Esta es una pregunta¿Por qué no funcionaba en SECUNDARIO? .

Por lo que encontré en SOSECUNDARIO no funciona con patrones (%), pero incluso sabiendo que me pregunto si es por diseño o si es un error en la fabricación. (SECUNDARIO para una regla de patrón con GNU Make yLa regla de patrón Makefile ignora la regla falsa o elimina espontáneamente el archivo de salida )

Aquí un contenido reducido de mi Makefile para reproducir mi problema (cree un directorio com / stackoverflow / question para probarlo).

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 
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 
lt; .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

tratar

hacer trabajo / SoTest

Entiendo que esto está marcado como intermedio.

luego buscando en SO intenté configurarlo en .SECONDARY: lista de objetivos: tampoco funciona.

mirando el código fuente de make que vi que la eliminación de archivos intermedios se realiza dentro de este contexto:

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

así que configuré mi archivo en .PRECIOUS: y ahora funciona.

se muestra a la consola:

com / stackoverflow / question / SoTest.java

ejecuta emacs con la plantilla correcta, por lo que la creación está bien aqui salgo de emacs

y elimina el archivo al final

rm com / stackoverflow / question / SoTest.java

La eliminación al final se debe al archivo intermedio, esto se puede ver con la opción -d en make

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

Para que funcione, necesito descomentar el párrafo PRECIOSO.

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.

Respuestas a la pregunta(2)

Su respuesta a la pregunta