]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - mk/warnings.mk
Import bmake-20230909
[FreeBSD/FreeBSD.git] / mk / warnings.mk
1 # RCSid:
2 #       $Id: warnings.mk,v 1.17 2023/02/16 17:55:52 sjg Exp $
3 #
4 #       @(#) Copyright (c) 2002-2023, 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 # This is more in keeping with our current practice
24 .-include <local.warnings.mk>
25
26 # Modest defaults - put more elaborate sets in warnings-sets.mk
27 # -Wunused  etc are here so you can set
28 # W_unused=-Wno-unused etc.
29 MIN_WARNINGS ?= -Wall \
30         -Wformat \
31         -Wimplicit \
32         -Wunused \
33         -Wuninitialized
34
35 LOW_WARNINGS ?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes
36
37 MEDIUM_WARNINGS ?= ${LOW_WARNINGS}
38
39 HIGH_WARNINGS ?= ${MEDIUM_WARNINGS} \
40         -Wcast-align \
41         -Wcast-qual \
42         -Wparentheses \
43         -Wpointer-arith \
44         -Wmissing-declarations \
45         -Wreturn-type \
46         -Wswitch \
47         -Wwrite-strings
48
49 EXTRA_WARNINGS ?= ${HIGH_WARNINGS} -Wextra
50
51 # The two step default makes it easier to test build with different defaults.
52 DEFAULT_WARNINGS_SET ?= MIN
53 WARNINGS_SET ?= ${DEFAULT_WARNINGS_SET}
54
55 # There is always someone who wants more...
56 .if !empty(WARNINGS_XTRAS)
57 ${WARNINGS_SET}_WARNINGS += ${WARNINGS_XTRAS}
58 .endif
59
60 # Keep this list ordered!
61 WARNINGS_SET_LIST ?= MIN LOW MEDIUM HIGH EXTRA
62
63 # We assume WARNINGS_SET_LIST is an ordered list.
64 # if WARNINGS_SET is < WERROR_SET we add WARNINGS_NO_ERROR
65 # otherwise we add WARNINGS_ERROR
66 DEFAULT_WERROR_SET ?= MEDIUM
67 WERROR_SET ?= ${DEFAULT_WERROR_SET}
68 WARNINGS_ERROR ?= -Werror
69 WARNINGS_NO_ERROR ?=
70
71 .if ${MAKE_VERSION} >= 20170130
72 .for i in ${WARNINGS_SET_LIST:range}
73 .if ${WARNINGS_SET_LIST:[$i]} == ${WARNINGS_SET}
74 WARNINGS_SETx = $i
75 .endif
76 .if ${WARNINGS_SET_LIST:[$i]} == ${WERROR_SET}
77 WERROR_SETx = $i
78 .if ${MAKE_VERSION} >= 20220924
79 .break
80 .endif
81 .endif
82 .endfor
83 .if ${WARNINGS_SETx:U${WERROR_SETx:U0}} < ${WERROR_SETx:U0}
84 ${WARNINGS_SET}_WARNINGS += ${WARNINGS_NO_ERROR:U}
85 .else
86 ${WARNINGS_SET}_WARNINGS += ${WARNINGS_ERROR}
87 .endif
88 .endif
89
90 .if !empty(WARNINGS_SET)
91 .for ws in ${WARNINGS_SET}
92 .if empty(${ws}_WARNINGS)
93 .if ${MAKE_VERSION:[1]:C/.*-//} >= 20050530
94 .BEGIN: _empty_warnings
95 _empty_warnings: .PHONY
96 .else
97 .BEGIN:
98 .endif
99         @echo "ERROR: Invalid: WARNINGS_SET=${ws}"
100         @echo "ERROR: Try one of: ${WARNINGS_SET_LIST}"; exit 1
101
102 .endif
103 .endfor
104 .endif
105
106 # Without -O or if we've set -O0 somewhere - to make debugging more effective,
107 # we need to turn off -Wuninitialized as otherwise we get a warning that
108 # -Werror turns into an error.  To be safe, set W_uninitialized blank.
109 _w_cflags= ${CFLAGS} ${CFLAGS_LAST} ${CPPFLAGS}
110 .if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != ""
111 W_uninitialized=
112 .endif
113
114
115 # .for loops have the [dis]advantage of being evaluated when read,
116 # so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is
117 # read has no effect.
118 # Replacing the above .for loops with the WARNINGS+= below solves that
119 # but tiggers a double free bug in bmake-20040118 and earlier.
120 # Don't try and read this too fast!
121 #
122 # The first :@ "loop" handles multiple sets in WARNINGS_SET
123 #
124 # In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc
125 # which makes it easy to turn off override individual flags
126 # (see W_uninitialized above).
127 #
128 # The last bit expands to
129 # ${W_foo_${.TARGET:T:${TARGET_PREFIX_FILTER:ts:}}:U${W_foo}}
130 # which is the bit we ultimately want.  It allows W_* to be set on a
131 # per target basis.
132 #
133 # NOTE: that we force the target extension to be .o
134 # TARGET_PREFIX_FILTER defaults to R
135 #
136
137 TARGET_PREFIX_FILTER ?= R
138
139 # define this once, we use it a couple of times below (hence the doubled $$).
140 M_warnings_list = @s@$${$$s_WARNINGS} $${$$s_WARNINGS.${COMPILER_TYPE}:U}@:O:u:@w@$${$${w:C/-(.)/\1_/}::?=$$w} $${$${w:C/-(.)/\1_/}_${MACHINE_ARCH}_${.TARGET:T:${TARGET_PREFIX_FILTER:ts:}}.o:U$${$${w:C/-(.)/\1_/}_${.TARGET:T:${TARGET_PREFIX_FILTER:ts:}}.o:U$${$${w:C/-(.)/\1_/}_${MACHINE_ARCH}:U$${$${w:C/-(.)/\1_/}}}}}@
141
142 # first a list of warnings from the chosen set
143 _warnings = ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:${M_warnings_list}}
144 # now a list of all -Wno-* overrides not just those defined by WARNINGS_SET
145 # since things like -Wall imply lots of others.
146 # this should be a super-set of the -Wno-* in _warnings, but
147 # just in case...
148 _no_warnings = ${_warnings:M-Wno-*} ${WARNINGS_SET_LIST:${M_warnings_list}:M-Wno-*}
149 # -Wno-* must follow any others
150 WARNINGS += ${_warnings:N-Wno-*} ${_no_warnings:O:u}
151
152 .ifndef NO_CFLAGS_WARNINGS
153 # Just ${WARNINGS} should do, but this is more flexible?
154 CFLAGS+= ${WARNINGS_${.TARGET:T:${TARGET_PREFIX_FILTER:ts:}}.o:U${WARNINGS}}
155 .endif
156
157 # it is rather silly that g++ blows up on some warning flags
158 NO_CXX_WARNINGS+= \
159         implicit \
160         missing-declarations \
161         missing-prototypes \
162         nested-externs \
163         shadow \
164         strict-prototypes
165
166 WARNINGS_CXX_SRCS += ${SRCS:M*.c*:N*.c:N*h}
167 .for s in ${WARNINGS_CXX_SRCS:O:u}
168 .for w in ${NO_CXX_WARNINGS}
169 W_$w_${s:T:${TARGET_PREFIX_FILTER:ts:}}.o=
170 .endfor
171 .endfor
172
173 .endif # _w_cflags