Search code examples
makefilegnu-make

Run a Make pattern rule on all matching files


I have a Makefile which, once simplified, looks like this:

%.pdf: %.md
    pandoc $< -o $@

How can I create a rule which runs this rule for all the *.md file present in the folder?

For instance I would like to be able to add new markdown files x.md, y.md and z.md, and then run

make pdf

... to produce x.pdf, y.pdf and z.pdf, without having change the Makefile or run make x.pdf y.pdf z.pdf manually.

At the moment, my workaround is to touch x.pdf y.pdf z.pdf, touch *.md, and make *.pdf.


Solution

  • MDS  := $(wildcard *.md)
    PDFS := $(patsubst %.md,%.pdf,$(MDS))
    
    .PHONY: pdf clean
    
    pdf: $(PDFS)
    
    %.pdf: %.md
        pandoc $< -o $@
    
    clean:
        rm -f $(PDFS)
    

    The clean phony target is a bonus.

    pdf and clean must be declared as phony because they are not real files. This is done by adding them as prerequisites of the .PHONY special target.