make clean: Only remove files that have been generated

Multi tool use
Multi tool use


make clean: Only remove files that have been generated



With the Makefile I'm working on, I convert pdf files into txt files.


Makefile



I've implemented a clean target that would remove all .txt files. However, I do not wish to delete the source files, only those that have been generated.


clean



Example:
I have following files in my folder:



pdfsource.pdf and donotharm.txt


pdfsource.pdf


donotharm.txt



Running my makefile would create following file:



pdfsource.txt


pdfsource.txt



For now, my clean looks like this:


clean


rm -f *.txt



Using make clean would not only delete pdfsource.txt, which is desired, but also donotharm.txt.


make clean


pdfsource.txt


donotharm.txt



I think I could use: .PRECIOUS: donotharm.txt, but this is really specific. I'd like to have a general solution to this.


.PRECIOUS: donotharm.txt



Thanks in advance!





Be aware: .PRECIOUS won't help you if you run rm -f *.txt. That's a whole different program: nothing in the rm command knows or cares what you files you may have marked .PRECIOUS in your makefile. That only has meaning to make itself, so that it won't delete those files for you. If you specifically write a rule (like clean) that deletes them .PRECIOUS has no impact on that.
– MadScientist
Jul 2 at 10:48


.PRECIOUS


rm -f *.txt


rm


.PRECIOUS


make


clean


.PRECIOUS




2 Answers
2



You can list the generated files in a make variable and use it to clean only these:


PDF := $(wildcard *.pdf)
TEXT := $(patsubst %.pdf,%.txt,$(PDF))
...
clean:
rm -f $(TEXT)



Or, if you prefer a more compact (but a bit less readable) form:


clean:
rm -f $(patsubst %.pdf,%.txt,$(wildcard *.pdf))



Of course, this works only if there is no {foo.pdf,foo.txt} pair for which you want to preserve foo.txt from deletion by make clean.


{foo.pdf,foo.txt}


foo.txt


make clean



Note: using make variables, in such a case, is usually a good idea because they can be shared among various rules. Example:


PDF := $(wildcard *.pdf)
TEXT := $(patsubst %.pdf,%.txt,$(PDF))

.PHONY: all clean

all: $(TEXT)

$(TEXT): %.txt: %.pdf
pdftotext $< $@

clean:
rm -f $(TEXT)



Another approach: "make -nps" gives you all make's metadata about dependencies. For any intermediate file, it prints


filename: ...



So you can exactly delete such files with a generic "clean" rule:


clean:; MAKEFLAGS= ${MAKE} -j1 -spinf $(word 1,${MAKEFILE_LIST})
| sed -n '/^# I/,$${/^[^#[%.][^ %]*: /s/:.*//p;}; 1s|.*|${clean}|p' | xargs rm -rf



The first line handles use of makefiles other than the defaults (makefile, GNUmakefile, Makefile)
In the "sed" command:


/^# I/,$



... selects the zone of make metadata with dependencies.


/^[^#[%.][^ %]*: /



... filters out comments, implicit rules, and files with no dependencies (the trailing space). It doesn't filter out phony targets; oh well.
Finally:


1s|.*|${clean}|p



adds any explicit targets for "clean" -- what you know that make does not; e.g.


clean += tmpdir/* *.gcda






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

MCG7,VDis3m,o,4qrCR3jzvJWe,dNs,j2 0HknyYu,UYXcFyT2gfmCMPpi DWi7 PstIF7JmemB4MWn2j6aV,T4qD
ij3l Iq Admbp6 aOQdBzzBN,MtgUw5dFx3

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications