summaryrefslogtreecommitdiff
path: root/mk/warnings.mk
diff options
context:
space:
mode:
Diffstat (limited to 'mk/warnings.mk')
-rw-r--r--mk/warnings.mk148
1 files changed, 148 insertions, 0 deletions
diff --git a/mk/warnings.mk b/mk/warnings.mk
new file mode 100644
index 0000000..9143e42
--- /dev/null
+++ b/mk/warnings.mk
@@ -0,0 +1,148 @@
+# RCSid:
+# $Id: warnings.mk,v 1.7 2009/12/11 17:06:03 sjg Exp $
+#
+# @(#) Copyright (c) 2002, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+.ifndef _w_cflags
+
+# Any number of warnings sets can be added.
+.-include "warnings-sets.mk"
+
+# Modest defaults - put more elaborate sets in warnings-sets.mk
+# -Wunused etc are here so you can set
+# W_unused=-Wno-unused etc.
+MIN_WARNINGS?= -Wall \
+ -Wformat \
+ -Wimplicit \
+ -Wunused \
+ -Wuninitialized
+
+LOW_WARNINGS?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes
+
+MEDIUM_WARNINGS?= ${LOW_WARNINGS} -Werror
+
+HIGH_WARNINGS?= ${MEDIUM_WARNINGS} \
+ -Wcast-align \
+ -Wcast-qual \
+ -Wparentheses \
+ -Wpointer-arith \
+ -Wmissing-declarations \
+ -Wreturn-type \
+ -Wswitch \
+ -Wwrite-strings
+
+# The two step default makes it easier to test build with different defaults.
+DEFAULT_WARNINGS_SET?= MIN
+WARNINGS_SET?= ${DEFAULT_WARNINGS_SET}
+
+# If you add sets, besure to list them (you don't have to touch this list).
+ALL_WARNINGS_SETS+= MIN LOW MEDIUM HIGH
+
+.if empty(${WARNINGS_SET}_WARNINGS)
+.if ${MAKE_VERSION:U0:[1]:C/.*-//} >= 20050530
+.BEGIN: _empty_warnings
+_empty_warnings: .PHONY
+.else
+.BEGIN:
+.endif
+ @echo "ERROR: Invalid: WARNINGS_SET=${WARNINGS_SET}"
+ @echo "ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1
+
+.endif
+
+# Without -O or if we've set -O0 somewhere - to make debugging more effective,
+# we need to turn off -Wuninitialized as otherwise we get a warning that
+# -Werror turns into an error. To be safe, set W_uninitialized blank.
+_w_cflags:= ${CFLAGS} ${CPPFLAGS}
+.if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != ""
+W_uninitialized=
+.endif
+
+.if ${MAKE_VERSION:U0:[1]:C/.*-//} <= 20040118
+# This version uses .for loops to avoid a double free bug in old bmake's
+# but the .for loops are sensitive to when this file is read.
+
+# first, make a list of all the warning flags - doesn't matter if
+# its redundant - we'll sort -u
+_all_sets= ${WARNINGS_SET_${MACHINE_ARCH}} ${WARNINGS_SET} ${ALL_WARNINGS_SETS}
+_all_warnings= ${WARNINGS} ${_all_sets:O:u:@s@${$s_WARNINGS}@}
+
+# we want to set W_* for each warning so they are easy to turn off.
+# :O:u does a sort -u
+# using :C allows us to handle -f* -w* etc as well as -W*
+.for w in ${_all_warnings:O:u}
+${w:C/-(.)/\1_/} ?= $w
+.endfor
+
+# Allow for per-target warnings
+# Warning: the WARNINGS+= line below,
+# may make your brain hurt - trust me; it works --sjg
+# the idea is that you can set WARNINGS_SET[_${MACHINE_ARCH}]=HIGH
+# and use one of
+# W_format_mips_foo.o=
+# W_format_foo.o=
+# to turn off -Wformat for foo.o (on mips only in the first case), or
+# W_format_foo.o=-Wformat=2
+# for stricter checking.
+#
+# NOTE: that we force the target extension to be .o
+#
+.for w in ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:@s@${$s_WARNINGS}@:O:u}
+WARNINGS+= ${${w:C/-(.)/\1_/}_${MACHINE_ARCH}_${.TARGET:T:R}.o:U${${w:C/-(.)/\1_/}_${.TARGET:T:R}.o:U${${w:C/-(.)/\1_/}_${MACHINE_ARCH}:U${${w:C/-(.)/\1_/}}}}}
+.endfor
+
+.else
+
+# .for loops have the [dis]advantage of being evaluated when read,
+# so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is
+# read has no effect.
+# Replacing the above .for loops with the WARNINGS+= below solves that
+# but tiggers a double free bug in bmake-20040118 and earlier.
+# Don't try and read this too fast!
+#
+# The first :@ "loop" handles multiple sets in WARNINGS_SET
+#
+# In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc
+# which makes it easy to turn off override individual flags
+# (see W_uninitialized above).
+#
+# The last bit expands to ${W_foo_${.TARGET:T}:U${W_foo}}
+# which is the bit we ultimately want. It allows W_* to be set on a
+# per target basis.
+#
+# NOTE: that we force the target extension to be .o
+#
+WARNINGS+= ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:@s@${$s_WARNINGS}@:O:u:@w@${${w:C/-(.)/\1_/}::?=$w} ${${w:C/-(.)/\1_/}_${MACHINE_ARCH}_${.TARGET:T:R}.o:U${${w:C/-(.)/\1_/}_${.TARGET:T:R}.o:U${${w:C/-(.)/\1_/}_${MACHINE_ARCH}:U${${w:C/-(.)/\1_/}}}}}@}
+
+.endif
+
+.ifndef NO_CFLAGS_WARNINGS
+# Just ${WARNINGS} should do, but this is more flexible?
+CFLAGS+= ${WARNINGS_${.TARGET:T:R}.o:U${WARNINGS}}
+.endif
+
+# it is rather silly that g++ blows up on some warning flags
+NO_CXX_WARNINGS+= \
+ missing-declarations \
+ missing-prototypes \
+ nested-externs \
+ strict-prototypes
+
+.for s in ${SRCS:M*.cc}
+.for w in ${NO_CXX_WARNINGS}
+W_$w_${s:T:R}.o=
+.endfor
+.endfor
+
+.endif # _w_cflags