1# RCSid: 2# $Id: warnings.mk,v 1.7 2009/12/11 17:06:03 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 19# Any number of warnings sets can be added. 20.-include "warnings-sets.mk" 21 22# Modest defaults - put more elaborate sets in warnings-sets.mk 23# -Wunused etc are here so you can set 24# W_unused=-Wno-unused etc. 25MIN_WARNINGS?= -Wall \ 26 -Wformat \ 27 -Wimplicit \ 28 -Wunused \ 29 -Wuninitialized 30 31LOW_WARNINGS?= ${MIN_WARNINGS} -W -Wstrict-prototypes -Wmissing-prototypes 32 33MEDIUM_WARNINGS?= ${LOW_WARNINGS} -Werror 34 35HIGH_WARNINGS?= ${MEDIUM_WARNINGS} \ 36 -Wcast-align \ 37 -Wcast-qual \ 38 -Wparentheses \ 39 -Wpointer-arith \ 40 -Wmissing-declarations \ 41 -Wreturn-type \ 42 -Wswitch \ 43 -Wwrite-strings 44 45# The two step default makes it easier to test build with different defaults. 46DEFAULT_WARNINGS_SET?= MIN 47WARNINGS_SET?= ${DEFAULT_WARNINGS_SET} 48 49# If you add sets, besure to list them (you don't have to touch this list). 50ALL_WARNINGS_SETS+= MIN LOW MEDIUM HIGH 51 52.if empty(${WARNINGS_SET}_WARNINGS) 53.if ${MAKE_VERSION:U0:[1]:C/.*-//} >= 20050530 54.BEGIN: _empty_warnings 55_empty_warnings: .PHONY 56.else 57.BEGIN: 58.endif 59 @echo "ERROR: Invalid: WARNINGS_SET=${WARNINGS_SET}" 60 @echo "ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1 61 62.endif 63 64# Without -O or if we've set -O0 somewhere - to make debugging more effective, 65# we need to turn off -Wuninitialized as otherwise we get a warning that 66# -Werror turns into an error. To be safe, set W_uninitialized blank. 67_w_cflags:= ${CFLAGS} ${CPPFLAGS} 68.if ${_w_cflags:M-O*} == "" || ${_w_cflags:M-O0} != "" 69W_uninitialized= 70.endif 71 72.if ${MAKE_VERSION:U0:[1]:C/.*-//} <= 20040118 73# This version uses .for loops to avoid a double free bug in old bmake's 74# but the .for loops are sensitive to when this file is read. 75 76# first, make a list of all the warning flags - doesn't matter if 77# its redundant - we'll sort -u 78_all_sets= ${WARNINGS_SET_${MACHINE_ARCH}} ${WARNINGS_SET} ${ALL_WARNINGS_SETS} 79_all_warnings= ${WARNINGS} ${_all_sets:O:u:@s@${$s_WARNINGS}@} 80 81# we want to set W_* for each warning so they are easy to turn off. 82# :O:u does a sort -u 83# using :C allows us to handle -f* -w* etc as well as -W* 84.for w in ${_all_warnings:O:u} 85${w:C/-(.)/\1_/} ?= $w 86.endfor 87 88# Allow for per-target warnings 89# Warning: the WARNINGS+= line below, 90# may make your brain hurt - trust me; it works --sjg 91# the idea is that you can set WARNINGS_SET[_${MACHINE_ARCH}]=HIGH 92# and use one of 93# W_format_mips_foo.o= 94# W_format_foo.o= 95# to turn off -Wformat for foo.o (on mips only in the first case), or 96# W_format_foo.o=-Wformat=2 97# for stricter checking. 98# 99# NOTE: that we force the target extension to be .o 100# 101.for w in ${WARNINGS_SET_${MACHINE_ARCH}:U${WARNINGS_SET}:@s@${$s_WARNINGS}@:O:u} 102WARNINGS+= ${${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_/}}}}} 103.endfor 104 105.else 106 107# .for loops have the [dis]advantage of being evaluated when read, 108# so adding to WARNINGS_SET[_${MACHINE_ARCH}] after this file is 109# read has no effect. 110# Replacing the above .for loops with the WARNINGS+= below solves that 111# but tiggers a double free bug in bmake-20040118 and earlier. 112# Don't try and read this too fast! 113# 114# The first :@ "loop" handles multiple sets in WARNINGS_SET 115# 116# In the second :@ "loop", the ::?= noise sets W_foo?=-Wfoo etc 117# which makes it easy to turn off override individual flags 118# (see W_uninitialized above). 119# 120# The last bit expands to ${W_foo_${.TARGET:T}:U${W_foo}} 121# which is the bit we ultimately want. It allows W_* to be set on a 122# per target basis. 123# 124# NOTE: that we force the target extension to be .o 125# 126WARNINGS+= ${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_/}}}}}@} 127 128.endif 129 130.ifndef NO_CFLAGS_WARNINGS 131# Just ${WARNINGS} should do, but this is more flexible? 132CFLAGS+= ${WARNINGS_${.TARGET:T:R}.o:U${WARNINGS}} 133.endif 134 135# it is rather silly that g++ blows up on some warning flags 136NO_CXX_WARNINGS+= \ 137 missing-declarations \ 138 missing-prototypes \ 139 nested-externs \ 140 strict-prototypes 141 142.for s in ${SRCS:M*.cc} 143.for w in ${NO_CXX_WARNINGS} 144W_$w_${s:T:R}.o= 145.endfor 146.endfor 147 148.endif # _w_cflags 149