Não há uma solução geral - cada sistema operacional tem sua própria API de monitoramento de arquivos. No Mac OS X são FSEvents, no Linux - inotify ou fanotify, em BSDs - kqueue.
No Linux, você pode usar incron ou escrever um script usando inotifywait :
#!/usr/bin/env bash
inotifywait -r -m -q -e close_write ~/project \
| while read path event file; do
if case $file in
autogenerated.h) false;; # ignore a specific file to avoid loops
*.c|*.h|Makefile) true;; # watch all .c, .h files, the Makefile
*) false;; # ignore all other files to avoid loops
esac; then # (specifically, you MUST ignore auto-
(cd ~/project && make) # -generated files)
fi
done