Why .SECONDARY does not work with patterns (%) while .PRECIOUS does?
gnu, gnu-make, makefile
Solution
The answer to "Why .SECONDARY does not work with patterns (%) while .PRECIOUS does?" is here: the document says
You can also list the target pattern of an implicit rule (such as ‘%.o’) as a prerequisite file of the special target .PRECIOUS
but does not say this about `.SECONDARY`. But for the few explicit exceptions, none of the special targets accept patterns.
Problem
My question is to understand better what i missed in make process and .SECONDARY purpose vs .PRECIOUS, not to get my script working, since it does work already. I am using make to either open a emacs editor on a file ( java but irrelevant for purpose of this question ) or to create it with a template if not existing. If it works well with existing files, when using generated file it is removed at the end. I added prerequisite in .SECONDARY but didn't help, i had to add it in .PRECIOUS. This is question why wasn't it working in .SECONDARY ? . From what i found on SO .SECONDARY does not work with patterns ( % ), but even with knowing that i wonder if it is by design or if it is a bug in make. ( .SECONDARY for a pattern rule with GNU Make and Makefile pattern rule either ignores phony rule or spontaneously deletes output file ) Here a stripped down content of my Makefile to reproduce my problem ( please create a com/stackoverflow/question directory to test it ). ``` 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 make work/SoTest I understand this is flagged intermediate. then looking in SO i tried to set it in .SECONDARY: target list : does not work either. looking at make source code i spotted that make intermediate files removal is done within this context : ``` if (f->intermediate && (f->dontcare || !f->precious) && !f->secondary && !f->cmd_target) ``` so i set my file in .PRECIOUS: and now it works. it displays to console : com/stackoverflow/question/SoTest.java it run emacs with right template in it so creation is OK here i exit emacs and it removes the file at the end rm com/stackoverflow/question/SoTest.java Removal at end is due to intermediate file, this can be seen with -d option on 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 ``` To have it working i need to uncomment the .PRECIOUS paragraph. 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. ```