1246149Ssjg# RCSid:
2246149Ssjg#	$Id: warnings.mk,v 1.7 2009/12/11 17:06:03 sjg Exp $
3246149Ssjg#
4246149Ssjg#	@(#) Copyright (c) 2002, Simon J. Gerraty
5246149Ssjg#
6246149Ssjg#	This file is provided in the hope that it will
7246149Ssjg#	be of use.  There is absolutely NO WARRANTY.
8246149Ssjg#	Permission to copy, redistribute or otherwise
9246149Ssjg#	use this file is hereby granted provided that 
10246149Ssjg#	the above copyright notice and this notice are
11246149Ssjg#	left intact. 
12246149Ssjg#      
13246149Ssjg#	Please send copies of changes and bug-fixes to:
14246149Ssjg#	sjg@crufty.net
15246149Ssjg#
16246149Ssjg
17246149Ssjg.ifndef _w_cflags
18246149Ssjg
19246149Ssjg# Any number of warnings sets can be added.
20246149Ssjg.-include "warnings-sets.mk"
21246149Ssjg
22246149Ssjg# Modest defaults - put more elaborate sets in warnings-sets.mk
23246149Ssjg# -Wunused  etc are here so you can set
24246149Ssjg# W_unused=-Wno-unused etc.
25246149SsjgMIN_WARNINGS?= -Wall \
26246149Ssjg	-Wformat \
27246149Ssjg	-Wimplicit \
28246149Ssjg	-Wunused \
29246149Ssjg	-Wuninitialized 
30246149Ssjg
31246149SsjgLOW_WARNINGS?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes
32246149Ssjg 
33246149SsjgMEDIUM_WARNINGS?= ${LOW_WARNINGS} -Werror
34246149Ssjg
35246149SsjgHIGH_WARNINGS?= ${MEDIUM_WARNINGS} \
36246149Ssjg	-Wcast-align \
37246149Ssjg	-Wcast-qual \
38246149Ssjg	-Wparentheses \
39246149Ssjg	-Wpointer-arith \
40246149Ssjg	-Wmissing-declarations \
41246149Ssjg	-Wreturn-type \
42246149Ssjg	-Wswitch \
43246149Ssjg	-Wwrite-strings
44246149Ssjg
45246149Ssjg# The two step default makes it easier to test build with different defaults.
46246149SsjgDEFAULT_WARNINGS_SET?= MIN
47246149SsjgWARNINGS_SET?= ${DEFAULT_WARNINGS_SET}
48246149Ssjg
49246149Ssjg# If you add sets, besure to list them (you don't have to touch this list).
50246149SsjgALL_WARNINGS_SETS+= MIN LOW MEDIUM HIGH
51246149Ssjg
52246149Ssjg.if empty(${WARNINGS_SET}_WARNINGS)
53246149Ssjg.if ${MAKE_VERSION:U0:[1]:C/.*-//} >= 20050530
54246149Ssjg.BEGIN:	_empty_warnings
55246149Ssjg_empty_warnings: .PHONY
56246149Ssjg.else
57246149Ssjg.BEGIN:
58246149Ssjg.endif
59246149Ssjg	@echo "ERROR: Invalid: WARNINGS_SET=${WARNINGS_SET}"
60246149Ssjg	@echo "ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1
61246149Ssjg
62246149Ssjg.endif
63246149Ssjg
64246149Ssjg# Without -O or if we've set -O0 somewhere - to make debugging more effective,
65246149Ssjg# we need to turn off -Wuninitialized as otherwise we get a warning that
66246149Ssjg# -Werror turns into an error.  To be safe, set W_uninitialized blank.
67246149Ssjg_w_cflags:= ${CFLAGS} ${CPPFLAGS}
68246149Ssjg.if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != ""
69246149SsjgW_uninitialized=
70246149Ssjg.endif
71246149Ssjg
72246149Ssjg.if ${MAKE_VERSION:U0:[1]:C/.*-//} <= 20040118
73246149Ssjg# This version uses .for loops to avoid a double free bug in old bmake's
74246149Ssjg# but the .for loops are sensitive to when this file is read.
75246149Ssjg
76246149Ssjg# first, make a list of all the warning flags - doesn't matter if
77246149Ssjg# its redundant - we'll sort -u
78246149Ssjg_all_sets= ${WARNINGS_SET_${MACHINE_ARCH}} ${WARNINGS_SET} ${ALL_WARNINGS_SETS}
79246149Ssjg_all_warnings= ${WARNINGS} ${_all_sets:O:u:@s@${$s_WARNINGS}@}
80246149Ssjg
81246149Ssjg# we want to set W_* for each warning so they are easy to turn off.
82246149Ssjg# :O:u does a sort -u
83246149Ssjg# using :C allows us to handle -f* -w* etc as well as -W*
84246149Ssjg.for w in ${_all_warnings:O:u}
85246149Ssjg${w:C/-(.)/\1_/} ?= $w
86246149Ssjg.endfor
87246149Ssjg
88246149Ssjg# Allow for per-target warnings
89246149Ssjg# Warning: the WARNINGS+= line below, 
90246149Ssjg# may make your brain hurt - trust me; it works --sjg
91246149Ssjg# the idea is that you can set WARNINGS_SET[_${MACHINE_ARCH}]=HIGH 
92246149Ssjg# and use one of
93246149Ssjg# W_format_mips_foo.o=
94246149Ssjg# W_format_foo.o=
95246149Ssjg# to turn off -Wformat for foo.o (on mips only in the first case), or
96246149Ssjg# W_format_foo.o=-Wformat=2
97246149Ssjg# for stricter checking.
98246149Ssjg#
99246149Ssjg# NOTE: that we force the target extension to be .o
100246149Ssjg#
101246149Ssjg.for w in ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:@s@${$s_WARNINGS}@:O:u}
102246149SsjgWARNINGS+= ${${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_/}}}}}
103246149Ssjg.endfor
104246149Ssjg
105246149Ssjg.else
106246149Ssjg
107246149Ssjg# .for loops have the [dis]advantage of being evaluated when read,
108246149Ssjg# so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is 
109246149Ssjg# read has no effect.
110246149Ssjg# Replacing the above .for loops with the WARNINGS+= below solves that
111246149Ssjg# but tiggers a double free bug in bmake-20040118 and earlier.
112246149Ssjg# Don't try and read this too fast!
113246149Ssjg#
114246149Ssjg# The first :@ "loop" handles multiple sets in WARNINGS_SET
115246149Ssjg#
116246149Ssjg# In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc
117246149Ssjg# which makes it easy to turn off override individual flags
118246149Ssjg# (see W_uninitialized above).
119246149Ssjg# 
120246149Ssjg# The last bit expands to ${W_foo_${.TARGET:T}:U${W_foo}}
121246149Ssjg# which is the bit we ultimately want.  It allows W_* to be set on a
122246149Ssjg# per target basis.
123246149Ssjg# 
124246149Ssjg# NOTE: that we force the target extension to be .o
125246149Ssjg#
126246149SsjgWARNINGS+= ${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_/}}}}}@}
127246149Ssjg
128246149Ssjg.endif
129246149Ssjg
130246149Ssjg.ifndef NO_CFLAGS_WARNINGS
131246149Ssjg# Just ${WARNINGS} should do, but this is more flexible?
132246149SsjgCFLAGS+= ${WARNINGS_${.TARGET:T:R}.o:U${WARNINGS}}
133246149Ssjg.endif
134246149Ssjg
135246149Ssjg# it is rather silly that g++ blows up on some warning flags
136246149SsjgNO_CXX_WARNINGS+= \
137246149Ssjg	missing-declarations \
138246149Ssjg	missing-prototypes \
139246149Ssjg	nested-externs \
140246149Ssjg	strict-prototypes
141246149Ssjg
142246149Ssjg.for s in ${SRCS:M*.cc}
143246149Ssjg.for w in ${NO_CXX_WARNINGS}
144246149SsjgW_$w_${s:T:R}.o=
145246149Ssjg.endfor
146246149Ssjg.endfor
147246149Ssjg
148246149Ssjg.endif # _w_cflags
149