Check if a program exists from a Makefile

A Makefile can check if a shell program or executable exists before running recipes.

Check if all programs exist

1
2
3
REQUIRED_BINS := hugo terraform aws exiftool jpegoptim optipng mogrify
$(foreach bin,$(REQUIRED_BINS),\
    $(if $(shell command -v $(bin) 2> /dev/null),,$(error Please install `$(bin)`)))

This method will run before any make <command> is completed. It ensures that each program listed in REQUIRED_BINS is executable. If not, it will output an error quickly.

Check if a specific program exists

If it’s preferred to check a shell program before running a specific command, the syntax below will enable for that use-case:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
tools := hugo terraform aws exiftool jpegoptim optipng mogrify
$(tools):
	@which $@ > /dev/null
	
.PHONY: serve
serve: hugo
	$(HUGO) server -D

.PHONY: validate
validate: terraform
	$(TERRAFORM) validate

This works by using automatic variables with static patterns. All items in tools will become targets. The $@ in the recipe will be be substituted with the target’s name.

In the example above, make serve will first check if the hugo target is completed. That target runs @which hugo > /dev/null.