120253Sjoerg# SPDX-License-Identifier: BSD-2-Clause 220302Sjoerg# 320302Sjoerg# RCSid: 420253Sjoerg# $Id: warnings.mk,v 1.18 2024/02/17 17:26:57 sjg Exp $ 520253Sjoerg# 620253Sjoerg# @(#) Copyright (c) 2002-2023, Simon J. Gerraty 720253Sjoerg# 820253Sjoerg# This file is provided in the hope that it will 920302Sjoerg# be of use. There is absolutely NO WARRANTY. 1020253Sjoerg# Permission to copy, redistribute or otherwise 1120253Sjoerg# use this file is hereby granted provided that 1220253Sjoerg# the above copyright notice and this notice are 1320253Sjoerg# left intact. 1420302Sjoerg# 1520253Sjoerg# Please send copies of changes and bug-fixes to: 1620253Sjoerg# sjg@crufty.net 1720302Sjoerg# 1820253Sjoerg 1920253Sjoerg.ifndef _w_cflags 2020253Sjoerg# make sure we get the behavior we expect 2120253Sjoerg.MAKE.SAVE_DOLLARS = no 2220253Sjoerg 2320253Sjoerg# Any number of warnings sets can be added. 2420253Sjoerg.-include <warnings-sets.mk> 2520253Sjoerg# This is more in keeping with our current practice 2620253Sjoerg.-include <local.warnings.mk> 2730259Scharnier 2830259Scharnier# Modest defaults - put more elaborate sets in warnings-sets.mk 2950479Speter# -Wunused etc are here so you can set 3030259Scharnier# W_unused=-Wno-unused etc. 3130259ScharnierMIN_WARNINGS ?= -Wall \ 3220253Sjoerg -Wformat \ 3320253Sjoerg -Wimplicit \ 3420253Sjoerg -Wunused \ 3520253Sjoerg -Wuninitialized 3620253Sjoerg 3720253SjoergLOW_WARNINGS ?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes 3820253Sjoerg 3920253SjoergMEDIUM_WARNINGS ?= ${LOW_WARNINGS} 4020253Sjoerg 4120253SjoergHIGH_WARNINGS ?= ${MEDIUM_WARNINGS} \ 4220253Sjoerg -Wcast-align \ 4320253Sjoerg -Wcast-qual \ 4420253Sjoerg -Wparentheses \ 4520253Sjoerg -Wpointer-arith \ 4620253Sjoerg -Wmissing-declarations \ 4720253Sjoerg -Wreturn-type \ 4820253Sjoerg -Wswitch \ 4920253Sjoerg -Wwrite-strings 5020253Sjoerg 5120253SjoergEXTRA_WARNINGS ?= ${HIGH_WARNINGS} -Wextra 5220253Sjoerg 53243894Seadler# The two step default makes it easier to test build with different defaults. 5420253SjoergDEFAULT_WARNINGS_SET ?= MIN 5520253SjoergWARNINGS_SET ?= ${DEFAULT_WARNINGS_SET} 5620253Sjoerg 5720253Sjoerg# There is always someone who wants more... 5820253Sjoerg.if !empty(WARNINGS_XTRAS) 5920253Sjoerg${WARNINGS_SET}_WARNINGS += ${WARNINGS_XTRAS} 6020253Sjoerg.endif 6120253Sjoerg 6220253Sjoerg# Keep this list ordered! 6320253SjoergWARNINGS_SET_LIST ?= MIN LOW MEDIUM HIGH EXTRA 6420253Sjoerg 6520253Sjoerg# We assume WARNINGS_SET_LIST is an ordered list. 6620253Sjoerg# if WARNINGS_SET is < WERROR_SET we add WARNINGS_NO_ERROR 6720253Sjoerg# otherwise we add WARNINGS_ERROR 6820253SjoergDEFAULT_WERROR_SET ?= MEDIUM 6920253SjoergWERROR_SET ?= ${DEFAULT_WERROR_SET} 7020253SjoergWARNINGS_ERROR ?= -Werror 7120253SjoergWARNINGS_NO_ERROR ?= 7220253Sjoerg 7320253Sjoerg.if ${MAKE_VERSION} >= 20170130 7420253Sjoerg.for i in ${WARNINGS_SET_LIST:range} 7520253Sjoerg.if ${WARNINGS_SET_LIST:[$i]} == ${WARNINGS_SET} 7620253SjoergWARNINGS_SETx = $i 7720253Sjoerg.endif 7820253Sjoerg.if ${WARNINGS_SET_LIST:[$i]} == ${WERROR_SET} 7920253SjoergWERROR_SETx = $i 8020253Sjoerg.if ${MAKE_VERSION} >= 20220924 8120253Sjoerg.break 8220253Sjoerg.endif 8320253Sjoerg.endif 8420253Sjoerg.endfor 8520253Sjoerg.if ${WARNINGS_SETx:U${WERROR_SETx:U0}} < ${WERROR_SETx:U0} 8620253Sjoerg${WARNINGS_SET}_WARNINGS += ${WARNINGS_NO_ERROR:U} 8720253Sjoerg.else 8820253Sjoerg${WARNINGS_SET}_WARNINGS += ${WARNINGS_ERROR} 8920253Sjoerg.endif 9020253Sjoerg.endif 9120253Sjoerg 9220253Sjoerg.if !empty(WARNINGS_SET) 9320253Sjoerg.for ws in ${WARNINGS_SET} 9420253Sjoerg.if empty(${ws}_WARNINGS) 9520253Sjoerg.if ${MAKE_VERSION:[1]:C/.*-//} >= 20050530 9620253Sjoerg.BEGIN: _empty_warnings 9720253Sjoerg_empty_warnings: .PHONY 9820253Sjoerg.else 9920253Sjoerg.BEGIN: 10020253Sjoerg.endif 10120253Sjoerg @echo "ERROR: Invalid: WARNINGS_SET=${ws}" 10220253Sjoerg @echo "ERROR: Try one of: ${WARNINGS_SET_LIST}"; exit 1 10320253Sjoerg 10420253Sjoerg.endif 10520253Sjoerg.endfor 10620253Sjoerg.endif 10720253Sjoerg 10820253Sjoerg# Without -O or if we've set -O0 somewhere - to make debugging more effective, 10920253Sjoerg# we need to turn off -Wuninitialized as otherwise we get a warning that 11020253Sjoerg# -Werror turns into an error. To be safe, set W_uninitialized blank. 11120253Sjoerg_w_cflags= ${CFLAGS} ${CFLAGS_LAST} ${CPPFLAGS} 11220253Sjoerg.if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != "" 11320253SjoergW_uninitialized= 11420253Sjoerg.endif 11520253Sjoerg 11620253Sjoerg 11720253Sjoerg# .for loops have the [dis]advantage of being evaluated when read, 11820253Sjoerg# so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is 11920253Sjoerg# read has no effect. 12020253Sjoerg# Replacing the above .for loops with the WARNINGS+= below solves that 12120253Sjoerg# but tiggers a double free bug in bmake-20040118 and earlier. 12220253Sjoerg# Don't try and read this too fast! 12320253Sjoerg# 12420253Sjoerg# The first :@ "loop" handles multiple sets in WARNINGS_SET 12520253Sjoerg# 12620253Sjoerg# In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc 12720253Sjoerg# which makes it easy to turn off override individual flags 12820253Sjoerg# (see W_uninitialized above). 12920253Sjoerg# 13020253Sjoerg# The last bit expands to 13120253Sjoerg# ${W_foo_${.TARGET:T:${TARGET_PREFIX_FILTER:ts:}}:U${W_foo}} 132# which is the bit we ultimately want. It allows W_* to be set on a 133# per target basis. 134# 135# NOTE: that we force the target extension to be .o 136# TARGET_PREFIX_FILTER defaults to R 137# 138 139TARGET_PREFIX_FILTER ?= R 140 141# define this once, we use it a couple of times below (hence the doubled $$). 142M_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_/}}}}}@ 143 144# first a list of warnings from the chosen set 145_warnings = ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:${M_warnings_list}} 146# now a list of all -Wno-* overrides not just those defined by WARNINGS_SET 147# since things like -Wall imply lots of others. 148# this should be a super-set of the -Wno-* in _warnings, but 149# just in case... 150_no_warnings = ${_warnings:M-Wno-*} ${WARNINGS_SET_LIST:${M_warnings_list}:M-Wno-*} 151# -Wno-* must follow any others 152WARNINGS += ${_warnings:N-Wno-*} ${_no_warnings:O:u} 153 154.ifndef NO_CFLAGS_WARNINGS 155# Just ${WARNINGS} should do, but this is more flexible? 156CFLAGS+= ${WARNINGS_${.TARGET:T:${TARGET_PREFIX_FILTER:ts:}}.o:U${WARNINGS}} 157.endif 158 159# it is rather silly that g++ blows up on some warning flags 160NO_CXX_WARNINGS+= \ 161 implicit \ 162 missing-declarations \ 163 missing-prototypes \ 164 nested-externs \ 165 shadow \ 166 strict-prototypes 167 168WARNINGS_CXX_SRCS += ${SRCS:M*.c*:N*.c:N*h} 169.for s in ${WARNINGS_CXX_SRCS:O:u} 170.for w in ${NO_CXX_WARNINGS} 171W_$w_${s:T:${TARGET_PREFIX_FILTER:ts:}}.o= 172.endfor 173.endfor 174 175.endif # _w_cflags 176