Often I find myself using third-party software like Caffeine or Amphetamine to
keep my Mac awake while running some specific commands. Sometimes it is because
I am running backups. Sometimes it is because I am compiling something.
I found out that macOS comes pre-installed with caffeinete command… this
post is about how to integrate it in your Makefile so that running any command
there will prevent your Mac from sleeping!
The command: caffeinate
This command comes pre-installed in any mac 🤯 This makes my life way easier because I would not have to brew anything. This is how I am going to use it:
caffeinate -i ${COMMAND}
This will prevent the system from sleeping while the ${COMMAND} runs.
I prefer to allow the display to sleep so that I can save some energy.
I am using the -i flag to prevent the system from idle sleeping, while I could
also use -d to prevent the display from sleeping. You can get more options
from a quick check in the manual (man caffeinate).

Using it with Make
When writing a Makefile, I usually writhe commands directly. Like so:
%.out:
command $*
other-command $*
What we could do to prevent sleep or hibernation is to use caffeinate before
every command, like so:
%.out:
caffeinate -i command $*
caffeinate -i other-command $*
But this might not be good-looking… and the senior gods of the
DRY religion might
cause your next live demo to fail! To make it better, I decided to use SHELL
variable so that every command will be passed to caffeinate and bash.
It will look something like this:
SHELL := caffeinate -i bash
%.out:
command $*
other-command $*
Sadly, this Makefile will not be portable, as caffeinate is available on macOS but not necessarily everywhere. So here is a simple condition to check if the binary is available and then overwrite the default shell used by Make:
# Prevent the system from idle sleeping, only on macOS
ifeq ($(shell uname -s),Darwin)
SHELL := caffeinate -i bash
endif
%.out:
command $*
other-command $*
There is a catch, though: caffeinate on macOS works differently than the
package available here,
and that might cause issues as the flags are different. 🤔
Therefore, instead of checking if caffeinate command is available like this:
ifneq (,$(shell which caffeinate))
I have decided to check if the kernel/OS is Darwin/macOS. There is space for improvements here to support different GNU/Linux distros.
I have implemented this in my Ansible Playbooks, as I was always finding myself struggling with having to restart commands just because I forgot to prevent my Mac from sleeping. Now I got it fixed with just three lines of code! 🥰