xref: /freebsd/contrib/bmake/mk/warnings.mk (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
1# RCSid:
2#	$Id: warnings.mk,v 1.15 2020/08/19 17:51:53 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# make sure we get the behavior we expect
19.MAKE.SAVE_DOLLARS = no
20
21# Any number of warnings sets can be added.
22.-include <warnings-sets.mk>
23
24# Modest defaults - put more elaborate sets in warnings-sets.mk
25# -Wunused  etc are here so you can set
26# W_unused=-Wno-unused etc.
27MIN_WARNINGS?= -Wall \
28	-Wformat \
29	-Wimplicit \
30	-Wunused \
31	-Wuninitialized
32
33LOW_WARNINGS?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes
34
35MEDIUM_WARNINGS?= ${LOW_WARNINGS} -Werror
36
37HIGH_WARNINGS?= ${MEDIUM_WARNINGS} \
38	-Wcast-align \
39	-Wcast-qual \
40	-Wparentheses \
41	-Wpointer-arith \
42	-Wmissing-declarations \
43	-Wreturn-type \
44	-Wswitch \
45	-Wwrite-strings
46
47EXTRA_WARNINGS?= ${HIGH_WARNINGS} -Wextra
48
49# The two step default makes it easier to test build with different defaults.
50DEFAULT_WARNINGS_SET?= MIN
51WARNINGS_SET?= ${DEFAULT_WARNINGS_SET}
52
53# There is always someone who wants more...
54.if !empty(WARNINGS_XTRAS)
55${WARNINGS_SET}_WARNINGS += ${WARNINGS_XTRAS}
56.endif
57
58# If you add sets, besure to list them (you don't have to touch this list).
59ALL_WARNINGS_SETS+= MIN LOW MEDIUM HIGH EXTRA
60
61.if !empty(WARNINGS_SET)
62.for ws in ${WARNINGS_SET}
63.if empty(${ws}_WARNINGS)
64.if ${MAKE_VERSION:[1]:C/.*-//} >= 20050530
65.BEGIN:	_empty_warnings
66_empty_warnings: .PHONY
67.else
68.BEGIN:
69.endif
70	@echo "ERROR: Invalid: WARNINGS_SET=${ws}"
71	@echo "ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1
72
73.endif
74.endfor
75.endif
76
77# Without -O or if we've set -O0 somewhere - to make debugging more effective,
78# we need to turn off -Wuninitialized as otherwise we get a warning that
79# -Werror turns into an error.  To be safe, set W_uninitialized blank.
80_w_cflags= ${CFLAGS} ${CFLAGS_LAST} ${CPPFLAGS}
81.if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != ""
82W_uninitialized=
83.endif
84
85
86# .for loops have the [dis]advantage of being evaluated when read,
87# so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is
88# read has no effect.
89# Replacing the above .for loops with the WARNINGS+= below solves that
90# but tiggers a double free bug in bmake-20040118 and earlier.
91# Don't try and read this too fast!
92#
93# The first :@ "loop" handles multiple sets in WARNINGS_SET
94#
95# In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc
96# which makes it easy to turn off override individual flags
97# (see W_uninitialized above).
98#
99# The last bit expands to ${W_foo_${.TARGET:T}:U${W_foo}}
100# which is the bit we ultimately want.  It allows W_* to be set on a
101# per target basis.
102#
103# NOTE: that we force the target extension to be .o
104#
105
106# define this once, we use it a couple of times below (hence the doubled $$).
107M_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_/}}}}}@
108
109# first a list of warnings from the chosen set
110_warnings = ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:${M_warnings_list}}
111# now a list of all -Wno-* overrides not just those defined by WARNINGS_SET
112# since things like -Wall imply lots of others.
113# this should be a super-set of the -Wno-* in _warnings, but
114# just in case...
115_no_warnings = ${_warnings:M-Wno-*} ${ALL_WARNINGS_SETS:${M_warnings_list}:M-Wno-*}
116# -Wno-* must follow any others
117WARNINGS += ${_warnings:N-Wno-*} ${_no_warnings:O:u}
118
119.ifndef NO_CFLAGS_WARNINGS
120# Just ${WARNINGS} should do, but this is more flexible?
121CFLAGS+= ${WARNINGS_${.TARGET:T:R}.o:U${WARNINGS}}
122.endif
123
124# it is rather silly that g++ blows up on some warning flags
125NO_CXX_WARNINGS+= \
126	implicit \
127	missing-declarations \
128	missing-prototypes \
129	nested-externs \
130	shadow \
131	strict-prototypes
132
133.for s in ${SRCS:M*.c*:N*.c:N*h}
134.for w in ${NO_CXX_WARNINGS}
135W_$w_${s:T:R}.o=
136.endfor
137.endfor
138
139.endif # _w_cflags
140