Warum funktioniert .SECONDARY nicht mit Mustern (%), während .PRECIOUS dies tut?

Meine Frage ist, besser zu verstehen, was ich in make process und .SECONDARY purpose vs .PRECIOUS verpasst habe, und mein Skript nicht zum Laufen zu bringen, da es bereits funktioniert.

Ich verwende make, um entweder einen Emacs-Editor für eine Datei zu öffnen (Java, aber für diese Frage irrelevant) oder um sie mit einer Vorlage zu erstellen, wenn sie nicht vorhanden ist.

Wenn es mit vorhandenen Dateien gut funktioniert,wenn die generierte Datei verwendet wird, wird sie am Ende entfernt.

Ich habe die Voraussetzung in .SECONDARY hinzugefügt, aber es hat nicht geholfen. Ich musste sie in .PRECIOUS hinzufügen.

Dies ist Frage Warum hat es in .SECONDARY nicht funktioniert? .

Von dem, was ich auf SO @ gefunden ha .SECONDARY funktioniert nicht mit Mustern (%), aber auch mit dem Wissen, dass ich mich frage, ob es beabsichtigt ist oder ob es ein Fehler in make ist. .SECONDARY für eine Musterregel mit GNU Make undMakefile-Musterregel ignoriert entweder die falsche Regel oder löscht spontan die Ausgabedatei )

Hier ein abgespeckter Inhalt meines Makefiles, um mein Problem zu reproduzieren (bitte erstelle ein com / stackoverflow / question-Verzeichnis, um es zu testen).

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

Versuche

Arbeit machen / SoTest

ch verstehe, dass dies als Zwischenstufe markiert is

Als ich in SO gesucht habe, habe ich versucht, es in .SECONDARY zu setzen: Zielliste: funktioniert auch nicht.

Blick auf make source code Ich habe festgestellt, dass das Entfernen von make intermediate files in diesem Kontext erfolgt:

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

so habe ich meine Datei in .PRECIOUS gesetzt: und jetzt funktioniert es.

it wird zur Konsole angezeigt:

com / stackoverflow / question / SoTest.java

Es wird Emacs mit der richtigen Vorlage ausgeführt, sodass die Erstellung in Ordnung ist Hier verlasse ich Emacs

und es entfernt die Datei am Ende

rm com / stackoverflow / question / SoTest.java

Entfernung am Ende ist auf eine Zwischendatei zurückzuführen. Dies kann mit der Option -d auf make @ angezeigt werde

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

Damit es funktioniert, muss ich den .PRECIOUS-Absatz auskommentieren.

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.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage