makefilefswatch

fswatch-ing a list of files, make-ing only the changed ones


Here's a minimal makefile for using pandoc to compile md to pdf. The make watch command watches for changed md files (using fswatch) and triggers make if so.

SRCS=$(wildcard *.md)
PDFS=$(SRCS:.md=.pdf)

all:    $(PDFS)

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

watch: $(SRCS)
    @fswatch -o $^ | xargs -n1 -I{} make

Currently, watch isn't very selective: even if just one md file is changed, it builds all possible targets (everything in PDFS). I would like a version of this code that watches all the md files for changes, but only builds a pdf for the changed md files. (I realize this is kind of pointless for the present case, but it's useful in another, more complicated use case.)


Solution

  • The following seems to work:

    @fswatch -0 $^ | xargs -0 -n1 sh -c 'ALT=`basename "$$1"`; make $${ALT/.md/.pdf}' _
    

    $$1 ends up identified with /path/to/changed_file.md as returned by fswatch. A couple string manipulations give changed_file.pdf, which is fed to make.