A while ago I documented a robust-ish way to set up the SHELL
in a Makefile.
Time has moved on and I’ve learned how to:
- Make effective use of parallelism (so I now include
MAKEFLAGS += --jobs=8
most of the time. - Write neater recipes using
.ONESHELL
- Implement some “standard” starter targets for Go projects:
make compile
to quickly check everything compiles correctlymake test
to run the tests, with minimal output.make install
to install binariesmake install
In order to support all this, we now need to switch the shell setup based on the version of GNU Make we’re using. For some reason .ONESHELL
confuses things in this regard otherwise.
You can see the most up-to-date version of this template at samsalisbury/home
Here’s how it looks at the moment:
.ONESHELL:
# Make on macOS is stuck at 3.81
ifeq ($(MAKE_VERSION),3.81)
SHELL := /usr/bin/env bash -euo pipefail -c
else
SHELL := /usr/bin/env
.SHELLFLAGS = -euo pipefail -c
endif
MAKEFLAGS += --silent --jobs=8
QUIET_UNLESS_FAIL = OUT="$$($2 2>&1)" || { CODE="$$?"; printf "$1 failed:\n%s" "$$OUT"; exit $$CODE; }; echo "$1: OK"
default: test
.PHONY: default
# -----
# Section: Go General
# This section should be useful for all go projects.
# -----
ALL_PACKAGES := ./...
compile:
$(call QUIET_UNLESS_FAIL,Compilation, go build $(ALL_PACKAGES))
$(call QUIET_UNLESS_FAIL,Test compilation, go test -exec true $(ALL_PACKAGES))
.PHONY: compile
test: compile
$(call QUIET_UNLESS_FAIL,Running go tests, go test $(ALL_PACKAGES))
.PHONY: test
# -----
# Section: Go Executable.
# This section is useful for go projects creating an executable.
# -----
NAME := hc-gh
# BIN is the binary name.
BIN := ./$(NAME)
# DESTDIR is the absolute path to the install path if running 'make install'
# Default to wherever it's currently installed using which, or /usr/local/bin
# if it's not yet installed.
DESTDIR ?= $(shell $$(dirname $$(which $(NAME)) 2>/dev/null || echo /usr/local/bin)
build: $(BIN)
echo $<
.PHONY: build
$(BIN): test
go build -o "$@"
.PHONY: $(BIN)
install: $(BIN)
mkdir -p "$(DESTDIR)"
install "$(BIN)" "$(DESTDIR)"
.PHONY: install