xref: /freebsd/contrib/bmake/mk/warnings.mk (revision b1f9167f94059fd55c630891d359bcff987bd7eb)
1# RCSid:
2#	$Id: warnings.mk,v 1.7 2009/12/11 17:06:03 sjg Exp $
3#
4#	@(#) Copyright (c) 2002, Simon J. Gerraty
5#
6#	This file is provided in the hope that it will
7#	be of use.  There is absolutely NO WARRANTY.
8#	Permission to copy, redistribute or otherwise
9#	use this file is hereby granted provided that
10#	the above copyright notice and this notice are
11#	left intact.
12#
13#	Please send copies of changes and bug-fixes to:
14#	sjg@crufty.net
15#
16
17.ifndef _w_cflags
18
19# Any number of warnings sets can be added.
20.-include "warnings-sets.mk"
21
22# Modest defaults - put more elaborate sets in warnings-sets.mk
23# -Wunused  etc are here so you can set
24# W_unused=-Wno-unused etc.
25MIN_WARNINGS?= -Wall \
26	-Wformat \
27	-Wimplicit \
28	-Wunused \
29	-Wuninitialized
30
31LOW_WARNINGS?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes
32
33MEDIUM_WARNINGS?= ${LOW_WARNINGS} -Werror
34
35HIGH_WARNINGS?= ${MEDIUM_WARNINGS} \
36	-Wcast-align \
37	-Wcast-qual \
38	-Wparentheses \
39	-Wpointer-arith \
40	-Wmissing-declarations \
41	-Wreturn-type \
42	-Wswitch \
43	-Wwrite-strings
44
45# The two step default makes it easier to test build with different defaults.
46DEFAULT_WARNINGS_SET?= MIN
47WARNINGS_SET?= ${DEFAULT_WARNINGS_SET}
48
49# If you add sets, besure to list them (you don't have to touch this list).
50ALL_WARNINGS_SETS+= MIN LOW MEDIUM HIGH
51
52.if empty(${WARNINGS_SET}_WARNINGS)
53.if ${MAKE_VERSION:U0:[1]:C/.*-//} >= 20050530
54.BEGIN:	_empty_warnings
55_empty_warnings: .PHONY
56.else
57.BEGIN:
58.endif
59	@echo "ERROR: Invalid: WARNINGS_SET=${WARNINGS_SET}"
60	@echo "ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1
61
62.endif
63
64# Without -O or if we've set -O0 somewhere - to make debugging more effective,
65# we need to turn off -Wuninitialized as otherwise we get a warning that
66# -Werror turns into an error.  To be safe, set W_uninitialized blank.
67_w_cflags:= ${CFLAGS} ${CPPFLAGS}
68.if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != ""
69W_uninitialized=
70.endif
71
72.if ${MAKE_VERSION:U0:[1]:C/.*-//} <= 20040118
73# This version uses .for loops to avoid a double free bug in old bmake's
74# but the .for loops are sensitive to when this file is read.
75
76# first, make a list of all the warning flags - doesn't matter if
77# its redundant - we'll sort -u
78_all_sets= ${WARNINGS_SET_${MACHINE_ARCH}} ${WARNINGS_SET} ${ALL_WARNINGS_SETS}
79_all_warnings= ${WARNINGS} ${_all_sets:O:u:@s@${$s_WARNINGS}@}
80
81# we want to set W_* for each warning so they are easy to turn off.
82# :O:u does a sort -u
83# using :C allows us to handle -f* -w* etc as well as -W*
84.for w in ${_all_warnings:O:u}
85${w:C/-(.)/\1_/} ?= $w
86.endfor
87
88# Allow for per-target warnings
89# Warning: the WARNINGS+= line below,
90# may make your brain hurt - trust me; it works --sjg
91# the idea is that you can set WARNINGS_SET[_${MACHINE_ARCH}]=HIGH
92# and use one of
93# W_format_mips_foo.o=
94# W_format_foo.o=
95# to turn off -Wformat for foo.o (on mips only in the first case), or
96# W_format_foo.o=-Wformat=2
97# for stricter checking.
98#
99# NOTE: that we force the target extension to be .o
100#
101.for w in ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:@s@${$s_WARNINGS}@:O:u}
102WARNINGS+= ${${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_/}}}}}
103.endfor
104
105.else
106
107# .for loops have the [dis]advantage of being evaluated when read,
108# so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is
109# read has no effect.
110# Replacing the above .for loops with the WARNINGS+= below solves that
111# but tiggers a double free bug in bmake-20040118 and earlier.
112# Don't try and read this too fast!
113#
114# The first :@ "loop" handles multiple sets in WARNINGS_SET
115#
116# In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc
117# which makes it easy to turn off override individual flags
118# (see W_uninitialized above).
119#
120# The last bit expands to ${W_foo_${.TARGET:T}:U${W_foo}}
121# which is the bit we ultimately want.  It allows W_* to be set on a
122# per target basis.
123#
124# NOTE: that we force the target extension to be .o
125#
126WARNINGS+= ${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_/}}}}}@}
127
128.endif
129
130.ifndef NO_CFLAGS_WARNINGS
131# Just ${WARNINGS} should do, but this is more flexible?
132CFLAGS+= ${WARNINGS_${.TARGET:T:R}.o:U${WARNINGS}}
133.endif
134
135# it is rather silly that g++ blows up on some warning flags
136NO_CXX_WARNINGS+= \
137	missing-declarations \
138	missing-prototypes \
139	nested-externs \
140	strict-prototypes
141
142.for s in ${SRCS:M*.cc}
143.for w in ${NO_CXX_WARNINGS}
144W_$w_${s:T:R}.o=
145.endfor
146.endfor
147
148.endif # _w_cflags
149