Search code examples
filemakefilegenerated

make clean: Only remove files that have been generated


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

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.

Example: I have following files in my folder:

pdfsource.pdf and donotharm.txt

Running my makefile would create following file:

pdfsource.txt

For now, my clean looks like this:

rm -f *.txt

Using make clean would not only delete pdfsource.txt, which is desired, but also 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.

Thanks in advance!


Solution

  • 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.

    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)