diff --git a/Makefile b/Makefile index 7f40f76739..9ea2e50bb8 100644 --- a/Makefile +++ b/Makefile @@ -431,6 +431,10 @@ all:: # # When cross-compiling, define HOST_CPU as the canonical name of the CPU on # which the built Git will run (for instance "x86_64"). +# +# Define DEVELOPER to enable more compiler warnings. Compiler version +# and family are auto detected, but could be overridden by defining +# COMPILER_FEATURES (see config.mak.dev) GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN @@ -439,15 +443,6 @@ GIT-VERSION-FILE: FORCE # CFLAGS and LDFLAGS are for the users to override from the command line. CFLAGS = -g -O2 -Wall -DEVELOPER_CFLAGS = -Werror \ - -Wdeclaration-after-statement \ - -Wno-format-zero-length \ - -Wold-style-definition \ - -Woverflow \ - -Wpointer-arith \ - -Wstrict-prototypes \ - -Wunused \ - -Wvla LDFLAGS = ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS) ALL_LDFLAGS = $(LDFLAGS) @@ -1047,7 +1042,7 @@ include config.mak.uname -include config.mak ifdef DEVELOPER -CFLAGS += $(DEVELOPER_CFLAGS) +include config.mak.dev endif comma := , diff --git a/config.mak.dev b/config.mak.dev new file mode 100644 index 0000000000..716a14ecc7 --- /dev/null +++ b/config.mak.dev @@ -0,0 +1,38 @@ +CFLAGS += -Werror +CFLAGS += -Wdeclaration-after-statement +CFLAGS += -Wno-format-zero-length +CFLAGS += -Wold-style-definition +CFLAGS += -Woverflow +CFLAGS += -Wpointer-arith +CFLAGS += -Wstrict-prototypes +CFLAGS += -Wunused +CFLAGS += -Wvla + +ifndef COMPILER_FEATURES +COMPILER_FEATURES := $(shell ./detect-compiler $(CC)) +endif + +ifneq ($(filter clang4,$(COMPILER_FEATURES)),) +CFLAGS += -Wtautological-constant-out-of-range-compare +endif + +ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter clang4,$(COMPILER_FEATURES))),) +CFLAGS += -Wextra +# if a function is public, there should be a prototype and the right +# header file should be included. If not, it should be static. +CFLAGS += -Wmissing-prototypes +# These are disabled because we have these all over the place. +CFLAGS += -Wno-empty-body +CFLAGS += -Wno-missing-field-initializers +CFLAGS += -Wno-sign-compare +CFLAGS += -Wno-unused-function +CFLAGS += -Wno-unused-parameter +endif + +# uninitialized warnings on gcc 4.9.2 in xdiff/xdiffi.c and config.c +# not worth fixing since newer compilers correctly stop complaining +ifneq ($(filter gcc4,$(COMPILER_FEATURES)),) +ifeq ($(filter gcc5,$(COMPILER_FEATURES)),) +CFLAGS += -Wno-uninitialized +endif +endif diff --git a/detect-compiler b/detect-compiler new file mode 100755 index 0000000000..70b754481c --- /dev/null +++ b/detect-compiler @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Probe the compiler for vintage, version, etc. This is used for setting +# optional make knobs under the DEVELOPER knob. + +CC="$*" + +# we get something like (this is at least true for gcc and clang) +# +# FreeBSD clang version 3.4.1 (tags/RELEASE...) +get_version_line() { + $CC -v 2>&1 | grep ' version ' +} + +get_family() { + get_version_line | sed 's/^\(.*\) version [0-9][^ ]* .*/\1/' +} + +get_version() { + get_version_line | sed 's/^.* version \([0-9][^ ]*\) .*/\1/' +} + +print_flags() { + family=$1 + version=$(get_version | cut -f 1 -d .) + + # Print a feature flag not only for the current version, but also + # for any prior versions we encompass. This avoids needing to do + # numeric comparisons in make, which are awkward. + while test "$version" -gt 0 + do + echo $family$version + version=$((version - 1)) + done +} + +case "$(get_family)" in +gcc) + print_flags gcc + ;; +clang) + print_flags clang + ;; +"FreeBSD clang") + print_flags clang + ;; +"Apple LLVM") + print_flags clang + ;; +*) + : unknown compiler family + ;; +esac