diff options
-rw-r--r-- | configure.ac | 71 | ||||
-rw-r--r-- | gphoto-m4/gp-pedantic-compiler-flags.m4 | 108 |
2 files changed, 159 insertions, 20 deletions
diff --git a/configure.ac b/configure.ac index c7b73f050..20a6a0045 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,10 @@ dnl Determine the most pedantic compiler flags we can find for both dnl C and C++, so that we can test that the libgphoto2 headers compile dnl with those flags. dnl -------------------------------------------------------------------- +dnl +dnl +GP_WITH_EMPTY_CONFDEFS_H([dnl +dnl GP_PEDANTIC_COMPILER_FLAGS([C90], [C], [-std=c90]) GP_PEDANTIC_COMPILER_FLAGS([C99], [C], [-std=c99]) GP_PEDANTIC_COMPILER_FLAGS([C11], [C], [-std=c11]) @@ -113,13 +117,65 @@ GP_PEDANTIC_COMPILER_FLAGS([CXX11], [C++], [-std=c++11]) GP_PEDANTIC_COMPILER_FLAGS([CXX14], [C++], [-std=c++14]) GP_PEDANTIC_COMPILER_FLAGS([CXX17], [C++], [-std=c++17]) GP_PEDANTIC_COMPILER_FLAGS([CXX20], [C++], [-std=c++20]) +dnl + +dnl -------------------------------------------------------------------- +dnl The goals here are twofold: +dnl +dnl * Produce as many compiler warnings as possible to find +dnl potential problems in our own code. +dnl +dnl * Make sure our API header files are as broadly compatible as +dnl possible. +dnl +dnl We want our library and driver code to compile with the lowest +dnl possible number of warnings, and the pedantic compilation tests to +dnl compile with zero warnings (-Werror) so we do not limit the users +dnl of our API in their use of compiler warnings. +dnl +dnl If, for some reason, you need to build without all these compiler +dnl warnings, run the build while setting CFLAGS to an empty string: +dnl +dnl $ make all check CFLAGS= +dnl -------------------------------------------------------------------- -GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS],[-Wall]) -GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS],[-Wextra]) -GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS],[-Wno-unused-parameter]) -GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS],[-Wno-format-overflow]) -GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS],[-Wno-format-truncation]) -GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS],[-Wno-stringop-truncation]) +dnl * gcc exits non-zero when it encounters an unknown warning option +dnl * clang by default ignores unknown warning option +dnl * clang with -Werror=unknown-warning-option will exit non-zero +dnl when it encounters an unknown warning option +GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Werror=unknown-warning-option]) + +GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wall]) +GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wextra]) +GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Weverything]) + +dnl We used to have these two defined for GCC instead of the whole -Wextra +dnl GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wmissing-declarations]) +dnl GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wmissing-prototypes]) + +dnl clang finds the underscores in all the "struct _Foo" definitions +dnl which means they fall into the reserved category. Before we can +dnl think about renaming those idenifiers, we need to verify they are +dnl not part of our public API. +GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-error=reserved-identifier]) + +dnl clang finds "/** comments using \deprecated */" without a +dnl corresponding __attribute__(( deprecated )). We need a good header +dnl file defining such compiler and standard library specific +dnl attributes purely as C preprocessor macros without configure +dnl involvement before we can change anything about this in the public +dnl API's include files. +GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-error=documentation-deprecated-sync]) + +dnl We used to have these four... no idea why, though. Stop reporting +dnl unused parameters for now, as those are VERY numerous and not much +dnl of a security risk, unlike the format and string warnings. +GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-unused-parameter]) +dnl GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-format-overflow]) +dnl GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-format-truncation]) +dnl GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-stringop-truncation]) + +])dnl GP_WITH_EMPTY_CONFDEFS_H dnl Every compile example after here will be using the C language AC_LANG([C]) @@ -129,9 +185,6 @@ dnl --------------------------------------------------------------------------- dnl Turn on (almost) all warnings when using gcc dnl --------------------------------------------------------------------------- if test "x$GCC" = "xyes"; then - # CFLAGS="$CFLAGS --std=c99 -Wall -Wextra -Werror -pedantic" - CFLAGS="$CFLAGS -Wall -Wmissing-declarations -Wmissing-prototypes" - LDFLAGS="$LDFLAGS" AC_SUBST([NO_UNUSED_CFLAGS], [-Wno-unused]) fi AM_CONDITIONAL([HAVE_GCC], [test "x$GCC" = "xyes"]) diff --git a/gphoto-m4/gp-pedantic-compiler-flags.m4 b/gphoto-m4/gp-pedantic-compiler-flags.m4 index b84aa0b51..1b690428c 100644 --- a/gphoto-m4/gp-pedantic-compiler-flags.m4 +++ b/gphoto-m4/gp-pedantic-compiler-flags.m4 @@ -7,14 +7,30 @@ dnl #################################################################### dnl GP_CONDITIONAL_COMPILE_FLAGS(FLAG_VAR, FLAGS) dnl #################################################################### AC_DEFUN([GP_CONDITIONAL_COMPILE_FLAGS], [dnl +dnl # BEGIN $0($@) -AS_VAR_IF([$1], [], [dnl - $1="$2" -], [dnl - $1="[$]{$1} $2" -]) -AC_MSG_CHECKING([whether $1="[$]$1" compiles]) -AC_COMPILE_IFELSE([m4_case([$1], [CFLAGS], [dnl +dnl +m4_pushdef([the_lang], + [m4_case([$1], + [CFLAGS], [C], + [CXXFLAGS], [C++], + [m4_fatal([unhandled compiler flags variable: ][$1])])])dnl +dnl +AC_LANG_PUSH(the_lang)dnl +dnl +dnl If $2 is a warning option, normalize it, as -Wno-foo will compile +dnl successfully, regardless of whether the compiler even knows the +dnl -Wfoo warning. FIXME: Split $2 and operate on each part? +m4_pushdef([normalized_option], + [m4_bpatsubst([$2], + [^-W\(no-\)?\(error=\)?\([-_0-9a-zA-Z=]+\)$], + [-W\3])])dnl +dnl +saved_$1="${$1}" +$1="${saved_$1} normalized_option -Werror" +AC_MSG_CHECKING([whether $1 can append $2]) +AC_COMPILE_IFELSE([dnl +m4_case(the_lang, [C], [dnl AC_LANG_SOURCE([[ #include <stdio.h> int main(int argc, char *argv[]) @@ -27,7 +43,7 @@ int main(int argc, char *argv[]) return 0; } ]])dnl -], [CXXFLAGS], [dnl +], [C++], [dnl AC_LANG_SOURCE([[ #include <iostream> int main(int argc, char *argv[]) @@ -40,14 +56,18 @@ int main(int argc, char *argv[]) return 0; } ]])dnl -], [m4_fatal([wrong compiler flag])])], [dnl - : "Added flag $2 to $1 and it works" +], [m4_fatal([unhandled language ]the_lang)])dnl +], [dnl AC_MSG_RESULT([yes]) + $1="${saved_$1} $2" ], [dnl - : "Added flag $2 to $1 and it does not work" AC_MSG_RESULT([no]) gp_have_pedantic_compiler=no + $1="$saved_$1" ]) +m4_popdef([normalized_option])dnl +AC_LANG_POP(the_lang)dnl +m4_popdef([the_lang])dnl # END $0($@) ])dnl dnl @@ -117,6 +137,72 @@ dnl dnl dnl #################################################################### dnl +dnl GP_WITH_EMPTY_CONFDEFS_H +dnl +dnl Usage: +dnl GP_WITH_EMPTY_CONFDEFS_H([ +dnl GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-foo]) +dnl GP_CONDITIONAL_COMPILE_FLAGS([CFLAGS], [-Wno-bar]) +dnl ])dnl +dnl +dnl Since autoconf 2.63b, the macros defined by AC_DEFINE so far +dnl (mostly PACKAGE, VERSION, etc.) are in confdefs.h by now and are +dnl included using AC_LANG_SOURCE or AC_LANG_PROGRAM. +dnl +dnl We cannot use a confdefs.h with macro definitions for the pedantic +dnl compilation tests as that pedantic compilation might complain +dnl about macros being defined but not used. +dnl +dnl We also cannot just put AC_LANG_DEFINES_PROVIDED inside the +dnl program, as that will make sure the program starts with the +dnl current content of confdefs.h. +dnl +dnl In order to be able to test compile programs without any macro +dnl definitions from confdefs.ht, we save the original confdefs.h file +dnl and use an empty confdefs.h for our checks, then restore the +dnl original confdefs.h after our checks are done. +dnl +dnl Of course, we must not append to confdefs.h by e.g. calling +dnl AC_DEFINE or AC_DEFINE_UNQUOTED until the original confdefs.h has +dnl been restored, as those definitions would then be lost. +dnl +dnl #################################################################### +AC_DEFUN([GP_WITH_EMPTY_CONFDEFS_H], [dnl +m4_pushdef([AC_DEFINE], + [m4_fatal([Must not use AC_DEFINE inside $0])])dnl +m4_pushdef([AC_DEFINE_UNQUOTED], + [m4_fatal([Must not use AC_DEFINE_UNQUOTED inside $0])])dnl +cat confdefs.h +AC_MSG_NOTICE([saving original confdefs.h and creating empty confdefs.h]) +rm -f confdefs.h.saved +mv confdefs.h confdefs.h.saved +cat <<EOF >confdefs.h +/* confdefs.h forced empty for the pedantic compile tests */ +EOF +dnl +AC_MSG_CHECKING([CFLAGS value before]) +AC_MSG_RESULT([$CFLAGS]) +AC_MSG_CHECKING([CXXFLAGS value before]) +AC_MSG_RESULT([$CXXFLAGS]) +dnl +$1 +dnl +AC_MSG_CHECKING([CFLAGS value after]) +AC_MSG_RESULT([$CFLAGS]) +AC_MSG_CHECKING([CXXFLAGS value after]) +AC_MSG_RESULT([$CXXFLAGS]) +dnl +AC_MSG_NOTICE([restoring original confdefs.h]) +rm -f confdefs.h +mv confdefs.h.saved confdefs.h +cat confdefs.h +m4_popdef([AC_DEFINE_UNQUOTED])dnl +m4_popdef([AC_DEFINE])dnl +])dnl +dnl +dnl +dnl #################################################################### +dnl dnl Local Variables: dnl mode: autoconf dnl End: |