1246149Ssjg# RCSid:
2300313Ssjg#	$Id: warnings.mk,v 1.14 2016/04/05 15:58:37 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
18296637Ssjg# make sure we get the behavior we expect
19296637Ssjg.MAKE.SAVE_DOLLARS = no
20246149Ssjg
21246149Ssjg# Any number of warnings sets can be added.
22300313Ssjg.-include <warnings-sets.mk>
23246149Ssjg
24246149Ssjg# Modest defaults - put more elaborate sets in warnings-sets.mk
25246149Ssjg# -Wunused  etc are here so you can set
26246149Ssjg# W_unused=-Wno-unused etc.
27246149SsjgMIN_WARNINGS?= -Wall \
28246149Ssjg	-Wformat \
29246149Ssjg	-Wimplicit \
30246149Ssjg	-Wunused \
31246149Ssjg	-Wuninitialized 
32246149Ssjg
33246149SsjgLOW_WARNINGS?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes
34246149Ssjg 
35246149SsjgMEDIUM_WARNINGS?= ${LOW_WARNINGS} -Werror
36246149Ssjg
37246149SsjgHIGH_WARNINGS?= ${MEDIUM_WARNINGS} \
38246149Ssjg	-Wcast-align \
39246149Ssjg	-Wcast-qual \
40246149Ssjg	-Wparentheses \
41246149Ssjg	-Wpointer-arith \
42246149Ssjg	-Wmissing-declarations \
43246149Ssjg	-Wreturn-type \
44246149Ssjg	-Wswitch \
45246149Ssjg	-Wwrite-strings
46246149Ssjg
47268437SsjgEXTRA_WARNINGS?= ${HIGH_WARNINGS} -Wextra
48268437Ssjg
49246149Ssjg# The two step default makes it easier to test build with different defaults.
50246149SsjgDEFAULT_WARNINGS_SET?= MIN
51246149SsjgWARNINGS_SET?= ${DEFAULT_WARNINGS_SET}
52246149Ssjg
53300313Ssjg# There is always someone who wants more...
54300313Ssjg.if !empty(WARNINGS_XTRAS)
55300313Ssjg${WARNINGS_SET}_WARNINGS += ${WARNINGS_XTRAS}
56300313Ssjg.endif
57300313Ssjg
58246149Ssjg# If you add sets, besure to list them (you don't have to touch this list).
59268437SsjgALL_WARNINGS_SETS+= MIN LOW MEDIUM HIGH EXTRA
60246149Ssjg
61268437Ssjg.if !empty(WARNINGS_SET)
62268437Ssjg.for ws in ${WARNINGS_SET}
63268437Ssjg.if empty(${ws}_WARNINGS)
64268437Ssjg.if ${MAKE_VERSION:[1]:C/.*-//} >= 20050530
65246149Ssjg.BEGIN:	_empty_warnings
66246149Ssjg_empty_warnings: .PHONY
67246149Ssjg.else
68246149Ssjg.BEGIN:
69246149Ssjg.endif
70268437Ssjg	@echo "ERROR: Invalid: WARNINGS_SET=${ws}"
71246149Ssjg	@echo "ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1
72246149Ssjg
73246149Ssjg.endif
74268437Ssjg.endfor
75268437Ssjg.endif
76246149Ssjg
77246149Ssjg# Without -O or if we've set -O0 somewhere - to make debugging more effective,
78246149Ssjg# we need to turn off -Wuninitialized as otherwise we get a warning that
79246149Ssjg# -Werror turns into an error.  To be safe, set W_uninitialized blank.
80300313Ssjg_w_cflags= ${CFLAGS} ${CFLAGS_LAST} ${CPPFLAGS}
81246149Ssjg.if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != ""
82246149SsjgW_uninitialized=
83246149Ssjg.endif
84246149Ssjg
85246149Ssjg
86246149Ssjg# .for loops have the [dis]advantage of being evaluated when read,
87246149Ssjg# so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is 
88246149Ssjg# read has no effect.
89246149Ssjg# Replacing the above .for loops with the WARNINGS+= below solves that
90246149Ssjg# but tiggers a double free bug in bmake-20040118 and earlier.
91246149Ssjg# Don't try and read this too fast!
92246149Ssjg#
93246149Ssjg# The first :@ "loop" handles multiple sets in WARNINGS_SET
94246149Ssjg#
95246149Ssjg# In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc
96246149Ssjg# which makes it easy to turn off override individual flags
97246149Ssjg# (see W_uninitialized above).
98246149Ssjg# 
99246149Ssjg# The last bit expands to ${W_foo_${.TARGET:T}:U${W_foo}}
100246149Ssjg# which is the bit we ultimately want.  It allows W_* to be set on a
101246149Ssjg# per target basis.
102246149Ssjg# 
103246149Ssjg# NOTE: that we force the target extension to be .o
104246149Ssjg#
105246149Ssjg
106268437Ssjg# define this once, we use it a couple of times below (hence the doubled $$).
107268437SsjgM_warnings_list = @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_/}}}}}@
108246149Ssjg
109268437Ssjg# first a list of warnings from the chosen set
110268437Ssjg_warnings = ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:${M_warnings_list}}
111268437Ssjg# now a list of all -Wno-* overrides not just those defined by WARNINGS_SET
112268437Ssjg# since things like -Wall imply lots of others.
113268437Ssjg# this should be a super-set of the -Wno-* in _warnings, but 
114268437Ssjg# just in case...
115268437Ssjg_no_warnings = ${_warnings:M-Wno-*} ${ALL_WARNINGS_SETS:${M_warnings_list}:M-Wno-*}
116268437Ssjg# -Wno-* must follow any others
117268437SsjgWARNINGS += ${_warnings:N-Wno-*} ${_no_warnings:O:u}
118268437Ssjg
119246149Ssjg.ifndef NO_CFLAGS_WARNINGS
120246149Ssjg# Just ${WARNINGS} should do, but this is more flexible?
121246149SsjgCFLAGS+= ${WARNINGS_${.TARGET:T:R}.o:U${WARNINGS}}
122246149Ssjg.endif
123246149Ssjg
124246149Ssjg# it is rather silly that g++ blows up on some warning flags
125246149SsjgNO_CXX_WARNINGS+= \
126300313Ssjg	implicit \
127246149Ssjg	missing-declarations \
128246149Ssjg	missing-prototypes \
129246149Ssjg	nested-externs \
130268437Ssjg	shadow \
131246149Ssjg	strict-prototypes
132246149Ssjg
133268437Ssjg.for s in ${SRCS:M*.c*:N*.c:N*h}
134246149Ssjg.for w in ${NO_CXX_WARNINGS}
135246149SsjgW_$w_${s:T:R}.o=
136246149Ssjg.endfor
137246149Ssjg.endfor
138246149Ssjg
139246149Ssjg.endif # _w_cflags
140