Treat warnings as errors in a (Gnu) Makefile

April 22, 2015 [Programming, Tech]

I got hit again last night by a bug in my Makefile that meant I effectively ran rm -rf /*, which was not fun.

Today I have been looking for how to make Make stop if a variable is undefined.

Here's my solution. This Makefile contains a bug ("SRCS" instead of "SRC"):

# Turn on the warning we want
MAKEFLAGS += --warn-undefined-variables

# Make sure MAKECMDGOALS is defined, so it doesn't cause an error itself
ifndef MAKECMDGOALS
MAKECMDGOALS = all
endif

SRC=hello.c

all: compile

# Fails if the Makefile contains any warnings.
# Run this Makefile with the same goals, but with the -n flag.
# Grep for warnings, and fail if any are found.
no-make-warnings:
    ! make -n $(MAKECMDGOALS) 2>&1 >/dev/null | grep warning

# Targets you want to check must depend on no-make-warnings
compile: no-make-warnings
    gcc -o hello $(SRCS)

When I run it I get:

$ make
! make -n all 2>&1 >/dev/null | grep warning
Makefile:17: warning: undefined variable `SRCS'
make: *** [no-make-warnings] Error 1

When I correct the bug I get:

$ make
! make -n all 2>&1 >/dev/null | grep warning
gcc -o hello hello.c

As expected.

To make a target warnings-resistant, you have to make it depend on the target no-make-warnings. If anyone has suggestions for how to avoid needing this, please comment.

I also posted this as a StackOverflow answer: How to treat a warning as an error in a Makefile?.