Makefile tricks

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the unix category.

Last Updated: 2022-05-26

How to use an .env file for secrets

Add an .env file to the same directory, then use the following code.

include .env
export $(shell sed 's/=.*//' .env)

How to use subshells

This make command did not work because it interfered with make's own syntax:

upload_push_notifications:
  expo push:android:upload --api-key $(jq ".client[0].api_key[0].current_key" ./firebase-google-services.json)

Instead we needed to wrap in $(shell x)

upload_push_notifications:
  expo push:android:upload --api-key $(shell jq ".client[0].api_key[0].current_key" ./firebase-google-services.json)

How to get inline help

Adopt a convention where every command has double hashes for comments

help: ## Show this help
    @egrep -h '\s##\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'


build: ## Install the various dependencies to get up and running
    cp ./githooks/* .git/hooks/
    npm install

How to pass arguments in

The word function takes the nth word (2 below) out of the list. $(MAKECMDGOALS) contains all args to make except the word make itself. E.g. make echo hello would populate it with $(MAKECMDGOALS)

echo:
    @echo $(word 2, $(MAKECMDGOALS))

# Running `make echo hello` here would return `hello`

How to avoid repetition of commands

By default a Makefile echoes the commands to be run as they are run. But this be wordy or can leak personal information. Avoid by prefacing the command with @

echom:
    echo "hi"
    @echo "bye"

This prints

echo "hi"
"hi"
"bye"