From: Stefano Lattarini Date: Tue, 5 Jun 2012 11:49:04 +0000 (+0200) Subject: [ng] warns: typos in _SOURCES etc. reported at make runtime X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=67d61020ff23f630bfa47bf6eec5036ecad5de74;p=thirdparty%2Fautomake.git [ng] warns: typos in _SOURCES etc. reported at make runtime For example, on an input: bin_PROGRAMS = frob forb_SOURCES = main.c a proper warning should be given, since either 'forb' or 'frob' is likely a typo. Mainline Automake gives the warning at automake runtime, while with this change, the warnings will be moved at make runtime. This will allow us to warn about variables like '_DEPENDENCIES', whose definitions can be unavailable (or unanalyzable) at automake runtime (check about those variables had to be disabled in commit 'v1.12-295-g9a5f837' of 2012-05-22, "[ng] warns: don't report possible issues with '_DEPENDENCIES' variables", to avoid spurious errors). * automake.in (generate_makefile): Emit code to perform make runtime checks, in particular those moved out from ... (check_typos): ... this now-deleted function ... * lib/am/check-typos.am: ... into this new Makefile fragment. * Makefile.am (dist_am_DATA): Add the new file. * lib/am/header-vars.am (am__error): New internal function, declares an error without immediately terminating the make process. Allows us to diagnose more issues at once, rather than stopping at the first one. * t/spell.sh: Adjust and extend. * t/spell2.sh: Likewise. * t/warnopts.sh: Adjust. * t/vartypo2.sh: Remove, its content adjusted and merged ... * t/vartypos.sh: ... into this test, adjusted and extended as well. Signed-off-by: Stefano Lattarini --- diff --git a/Makefile.am b/Makefile.am index 4f95e11bf..a08a3e539 100644 --- a/Makefile.am +++ b/Makefile.am @@ -187,6 +187,7 @@ EXTRA_DIST += lib/Automake/Config.in dist_am_DATA = \ lib/am/serial-tests.am \ lib/am/parallel-tests.am \ + lib/am/check-typos.am \ lib/am/color-tests.am \ lib/am/clean-hdr.am \ lib/am/clean.am \ diff --git a/automake.in b/automake.in index ca30da7b3..d65ebf69f 100644 --- a/automake.in +++ b/automake.in @@ -2748,32 +2748,6 @@ sub handle_ltlibraries } } -# See if any _SOURCES variable were misspelled. -sub check_typos () -{ - # It is ok if the user sets this particular variable. - set_seen 'AM_LDFLAGS'; - - foreach my $primary ('SOURCES', 'LIBADD', 'LDADD', 'LDFLAGS') - { - foreach my $var (variables $primary) - { - my $varname = $var->name; - # A configure variable is always legitimate. - next if exists $configure_vars{$varname}; - - for my $cond ($var->conditions->conds) - { - $varname =~ /^(?:EXTRA_)?(?:nobase_)?(?:dist_|nodist_)?(.*)_[[:alnum:]]+$/; - msg_var ('syntax', $var, "variable '$varname' is defined but no" - . " program or\nlibrary has '$1' as canonical name" - . " (possible typo)") - unless $var->rdef ($cond)->seen; - } - } - } -} - # Handle scripts. sub handle_scripts @@ -7524,7 +7498,13 @@ sub generate_makefile ($$) # defined or overridden variables. $output_vars .= output_variables; - check_typos; + my $output_checks = ''; + # See if any _SOURCES (or _LIBADD, or ...) variable were misspelled. + $output_checks .= preprocess_file ("$libdir/am/check-typos.am"); + # Report errors (if any) seen at make runtime. + $output_checks .= '$(if $(am__seen_error),' . + '$(error Some Automake-NG error occurred))' . + "\n"; if ($exit_code != 0) { @@ -7538,6 +7518,7 @@ sub generate_makefile ($$) my $output = $output_vars . $output_header . $output_verbatim . + $output_checks . $output_rules . $output_trailer; diff --git a/lib/am/check-typos.am b/lib/am/check-typos.am new file mode 100644 index 000000000..10d072b6d --- /dev/null +++ b/lib/am/check-typos.am @@ -0,0 +1,66 @@ +## automake - create Makefile.in from Makefile.am +## Copyright (C) 2012 Free Software Foundation, Inc. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . +## +## See if any _SOURCES or similar variable were misspelled, as in: +## bin_PROGRAMS = bar +## baz_SOURCES = main.c # Should be bar_SOURCES. + +## FIXME: With this, we impose runtime penalty to all make runs. Maybe we +## FIXME: should make all these checks conditional to whether the user sets +## FIXME: a AM_SANITY_CHECKS variable or something? + +## FIXME: We should document the '.am/' namespace as reserved for automake +## FIXME: internals somewhere. + +# Variables with these suffixes are candidates for typo checking. +.am/vartypos/suffixes := _SOURCES _LIBADD _LDADD _LDFLAGS +# But these variables are not, even if they match the patterns above. +.am/vartypos/whitelisted-vars := AM_LDFLAGS BUILT_SOURCES + +# Canonicalized names of programs and libraries (vanilla or libtool) that +# have been declared. +.am/vartypos/known-canon-proglibs := \ + $(sort $(call am__canon, $(am__all_progs) \ + $(am__all_libs) \ + $(am__all_ltlibs))) + +# Extract 'foo' from something like "EXTRA_nodist_foo_SOURCES". +define .am/vartypos/canon-name-from-var +$(call am__strip_suffixes, $(.am/vartypos/suffixes), \ + $(patsubst dist_%,%, \ + $(patsubst nodist_%,%, \ + $(patsubst nobase_%,%, \ + $(patsubst EXTRA_%,%, \ + $1))))) +endef + +define .am/vartypos/check +$(eval $0/canon := $(call .am/vartypos/canon-name-from-var,$1)) +$(if $(filter $($0/canon),$(.am/vartypos/known-canon-proglibs)),, \ + $(call am__error,variable '$1' is defined but no program) \ + $(call am__error, or library has '$($0/canon)' as canonical name)) +endef + +# The variables candidate for checking of typos. +.am/vartypos/candidate-vars := \ + $(filter-out $(.am/vartypos/whitelisted-vars), \ + $(filter $(addprefix %,$(.am/vartypos/suffixes)), \ + $(.VARIABLES))) + +# Apparently useless use of eval required to avoid a spurious "missing +# separator" error from GNU make. +$(eval $(foreach v,$(.am/vartypos/candidate-vars), \ + $(call .am/vartypos/check,$v))) diff --git a/lib/am/header-vars.am b/lib/am/header-vars.am index 9903af91a..74870c66d 100644 --- a/lib/am/header-vars.am +++ b/lib/am/header-vars.am @@ -16,6 +16,14 @@ VPATH = @srcdir@ +## Declare an error, without immediately terminating the execution (proper +## code will take care later of that). This will allow us to diagnose more +## issues at once, rather than stopping at the first one. +am__seen_error := +define am__error +$(warning $1)$(eval am__seen_error := yes) +endef + # Some problematic characters (especially when used in arguments # to make functions, or for syntax highlighting). am__bslash := \\ diff --git a/t/spell.sh b/t/spell.sh index a2b475278..790739d15 100755 --- a/t/spell.sh +++ b/t/spell.sh @@ -16,14 +16,39 @@ # Test to make sure misspellings in _SOURCES variables cause failure. +required=cc . ./defs || Exit 1 +cat >> configure.ac << 'END' +AC_PROG_CC +AC_OUTPUT +END + cat > Makefile.am << 'END' bin_PROGRAMS = zardoz foo zardoz_SOURCES = x.c boo_SOURCES = y.c END +echo 'int main (void) { return 0; }' > x.c +echo 'int main (void) { return 0; }' > y.c + $ACLOCAL -AUTOMAKE_fails -grep 'Makefile.am:3:.*boo' stderr +$AUTOCONF +$AUTOMAKE + +./configure +$MAKE 2>stderr && { cat stderr >&2; Exit 1; } +cat stderr >&2 + +LC_ALL=C sed 's/^Makefile:[0-9][0-9]*: //' stderr > got + +cat > exp << 'END' +variable 'boo_SOURCES' is defined but no program + or library has 'boo' as canonical name +*** Some Automake-NG error occurred. Stop. +END + +diff exp got + +: diff --git a/t/spell2.sh b/t/spell2.sh index a4b0a4605..dead9c118 100755 --- a/t/spell2.sh +++ b/t/spell2.sh @@ -14,18 +14,41 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# Test to make sure misspellings in _SOURCES variables cause failure. +# Test to make sure misspellings in _LDADD variable cause failure. +required=cc . ./defs || Exit 1 -echo AC_PROG_CC >> configure.ac +cat >> configure.ac << 'END' +AC_PROG_CC +AC_OUTPUT +END cat > Makefile.am << 'END' bin_PROGRAMS = zardoz zardoz_SOURCES = x.c -qardoz_LDADD = -ljoe +qardoz_LDADD = -lm END +echo 'int main (void) { return 0; }' > x.c + $ACLOCAL -AUTOMAKE_fails -grep 'Makefile.am:3:.*qardoz' stderr +$AUTOCONF +$AUTOMAKE + +./configure + +$MAKE 2>stderr && { cat stderr >&2; Exit 1; } +cat stderr >&2 + +LC_ALL=C sed 's/^Makefile:[0-9][0-9]*: //' stderr > got + +cat > exp << 'END' +variable 'qardoz_LDADD' is defined but no program + or library has 'qardoz' as canonical name +*** Some Automake-NG error occurred. Stop. +END + +diff exp got + +: diff --git a/t/vartypo2.sh b/t/vartypo2.sh deleted file mode 100755 index 9c1b6d77e..000000000 --- a/t/vartypo2.sh +++ /dev/null @@ -1,63 +0,0 @@ -#! /bin/sh -# Copyright (C) 2010-2012 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Make sure we warn about possible variable typos when we should, -# Libtool variant. - -required=libtoolize -. ./defs || Exit 1 - -cat >>configure.ac <<'END' -AM_PROG_AR -AC_PROG_LIBTOOL -AC_OUTPUT -END - -cat >Makefile.am <<'END' -libfoo_la_SOURCES = unused -nodist_libfoo_la_SOURCES = unused -EXTRA_libfoo_la_SOURCES = unused -libfoo_la_LIBADD = unused -END - -libtoolize -$ACLOCAL -AUTOMAKE_fails --add-missing -# The expected diagnostic is: -# automake: warnings are treated as errors -# Makefile.am:3: warning: variable `EXTRA_libfoo_la_SOURCES' is defined but no program or -# Makefile.am:3: library has `libfoo_la' as canonical name (possible typo) -# Makefile.am:1: warning: variable `libfoo_la_SOURCES' is defined but no program or -# Makefile.am:1: library has `libfoo_la' as canonical name (possible typo) -# Makefile.am:2: warning: variable `nodist_libfoo_la_SOURCES' is defined but no program or -# Makefile.am:2: library has `libfoo_la' as canonical name (possible typo) -# Makefile.am:4: warning: variable `libfoo_la_LIBADD' is defined but no program or -# Makefile.am:4: library has `libfoo_la' as canonical name (possible typo) - -grep 'as canonical' stderr | grep -v ' .libfoo_la. ' && Exit 1 -test `grep 'variable.*is defined but' stderr | wc -l` = 4 - -# If we add a global -Wnone, all warnings should disappear. -$AUTOMAKE -Wnone - -# Likewise, if matching programs or libraries are defined. -cat >>Makefile.am <<'END' -lib_LTLIBRARIES = libfoo.la -END - -$AUTOMAKE - -: diff --git a/t/vartypos.sh b/t/vartypos.sh index d176d047d..71647aca8 100755 --- a/t/vartypos.sh +++ b/t/vartypos.sh @@ -18,60 +18,83 @@ . ./defs || Exit 1 -cat >>configure.ac <<'END' +: > ltmain.sh + +cat >> configure.ac <<'END' +m4_define([AC_PROG_RANLIB], [AC_SUBST([RANLIB], [who-cares])]) +m4_define([AM_PROG_AR], [AC_SUBST([AR], [who-cares])]) +m4_define([LT_INIT], [AC_SUBST([LIBTOOL], [who-cares])]) +LT_INIT +AM_PROG_AR AC_PROG_RANLIB AC_OUTPUT END -cat >Makefile.am <<'END' -foo_SOURCES = unused -nodist_foo_SOURCES = unused -EXTRA_foo_SOURCES = unused -foo_LDADD = unused -foo_LDFLAGS = unused - -libfoo_a_SOURCES = unused -nodist_libfoo_a_SOURCES = unused -EXTRA_libfoo_a_SOURCES = unused -libfoo_a_LIBADD = unused +cat > Makefile.am <<'END' +foo_SOURCES = +dist_foo_SOURCES = +nodist_foo_SOURCES = +EXTRA_foo_SOURCES = +EXTRA_dist_foo_SOURCES = +EXTRA_nodist_foo_SOURCES = + +foo_LDADD = +foo_LDFLAGS = +EXTRA_foo_LDADD = +EXTRA_foo_LDFLAGS = + +libfoo_a_SOURCES = +dist_libfoo_a_SOURCES = +nodist_libfoo_a_SOURCES = +EXTRA_libfoo_a_SOURCES = +EXTRA_dist_libfoo_a_SOURCES = +EXTRA_nodist_libfoo_a_SOURCES = + +libfoo_a_LIBADD = +EXTRA_libfoo_a_LIBADD = +libfoo_a_LDFLAGS = +EXTRA_libfoo_a_LDFLAGS = + +libbar_la_SOURCES = +dist_libbar_la_SOURCES = +nodist_libbar_la_SOURCES = +EXTRA_libbar_la_SOURCES = +EXTRA_dist_libbar_la_SOURCES = +EXTRA_nodist_libbar_la_SOURCES = + +libbar_la_LIBADD = +EXTRA_libbar_la_LIBADD = +libbar_la_LDFLAGS = +EXTRA_libbar_la_LDFLAGS = + +.PHONY: nihil +nihil: + @: END $ACLOCAL -AUTOMAKE_fails -Wno-extra-portability -# The expected diagnostic is: -# automake: warnings are treated as errors -# Makefile.am:2: warning: variable 'nodist_foo_SOURCES' is defined but no program or -# Makefile.am:2: library has 'foo' as canonical name (possible typo) -# Makefile.am:1: warning: variable 'foo_SOURCES' is defined but no program or -# Makefile.am:1: library has 'foo' as canonical name (possible typo) -# Makefile.am:9: warning: variable 'libfoo_a_SOURCES' is defined but no program or -# Makefile.am:9: library has 'libfoo_a' as canonical name (possible typo) -# Makefile.am:10: warning: variable 'nodist_libfoo_a_SOURCES' is defined but no program or -# Makefile.am:10: library has 'libfoo_a' as canonical name (possible typo) -# Makefile.am:11: warning: variable 'EXTRA_libfoo_a_SOURCES' is defined but no program or -# Makefile.am:11: library has 'libfoo_a' as canonical name (possible typo) -# Makefile.am:3: warning: variable 'EXTRA_foo_SOURCES' is defined but no program or -# Makefile.am:3: library has 'foo' as canonical name (possible typo) -# Makefile.am:12: warning: variable 'libfoo_a_LIBADD' is defined but no program or -# Makefile.am:12: library has 'libfoo_a' as canonical name (possible typo) -# Makefile.am:4: warning: variable 'foo_LDADD' is defined but no program or -# Makefile.am:4: library has 'foo' as canonical name (possible typo) -# Makefile.am:5: warning: variable 'foo_LDFLAGS' is defined but no program or -# Makefile.am:5: library has 'foo' as canonical name (possible typo) - -grep 'as canonical' stderr | grep -v ' .foo. ' | grep -v ' .libfoo_a. ' \ - && Exit 1 -test `grep 'variable.*is defined but' stderr | wc -l` = 9 - -# If we add a global -Wnone, all warnings should disappear. -$AUTOMAKE -Wnone - -# Likewise, if matching programs or libraries are defined. -cat >>Makefile.am <<'END' +$AUTOCONF +$AUTOMAKE -a + +./configure +$MAKE nihil 2>stderr && { cat stderr >&2; Exit 1; } +cat stderr >&2 + +$FGREP 'as canonical' stderr \ + | $EGREP -v " '(foo|libfoo_a|libbar_la)' " && Exit 1 +test 30 -eq $(grep -c 'variable.*is defined but' stderr) + +# If matching programs or libraries are defined, all errors should +# disappear. +cat >> Makefile.am <<'END' bin_PROGRAMS = foo lib_LIBRARIES = libfoo.a +lib_LTLIBRARIES = libbar.la END -$AUTOMAKE -Wno-extra-portability +# FIXME! We have to remake the Makefile by hand! This is unacceptable. +$AUTOMAKE Makefile +./config.status Makefile +$MAKE nihil : diff --git a/t/warnopts.sh b/t/warnopts.sh index 774a38a57..ccf011b69 100755 --- a/t/warnopts.sh +++ b/t/warnopts.sh @@ -18,7 +18,8 @@ . ./defs || Exit 1 -cat >>configure.ac <> configure.ac << 'END' +AC_PROG_CC AC_CONFIG_FILES([sub/Makefile]) AM_CONDITIONAL([COND_FALSE], [false]) AC_OUTPUT @@ -30,35 +31,36 @@ mkdir sub # warnings disabled. cat > Makefile.am << 'END' -AUTOMAKE_OPTIONS = -Wno-unsupported +AUTOMAKE_OPTIONS = subdir-objects -Wno-unsupported if COND_FALSE AUTOMAKE_OPTIONS += no-dependencies endif -foo_SOURCES = unused +bin_PROGRAMS = foo +foo_SOURCES = sub/foo.c SUBDIRS = sub END cat > sub/Makefile.am << 'END' -AUTOMAKE_OPTIONS = -Wno-syntax +AUTOMAKE_OPTIONS = subdir-objects -Wno-portability if COND_FALSE AUTOMAKE_OPTIONS += no-dependencies endif -foo_SOURCES = unused +bin_PROGRAMS = foo +foo_SOURCES = sub/foo.c END $ACLOCAL AUTOMAKE_fails # The expected diagnostic is # automake: warnings are treated as errors -# Makefile.am:5: warning: variable 'foo_SOURCES' is defined but no program or -# Makefile.am:5: library has 'foo' as canonical name (possible typo) +# Makefile.am:6: warning: compiling 'sub/foo.c' in subdir requires 'AM_PROG_CC_C_O' in 'configure.ac' # sub/Makefile.am:1: warning: 'AUTOMAKE_OPTIONS' cannot have conditional contents -grep '^Makefile.am:.*foo_SOURCES' stderr +grep '^Makefile\.am:.*sub/foo\.c.*AM_PROG_CC_C_O' stderr grep '^sub/Makefile.am:.*AUTOMAKE_OPTIONS' stderr -grep '^sub/Makefile.am:.*foo_SOURCES' stderr && Exit 1 -grep '^Makefile.am:.*AUTOMAKE_OPTIONS' stderr && Exit 1 -# Only three lines of warnings. -test `grep -v 'warnings are treated as errors' stderr | wc -l` = 3 +grep '^sub/Makefile\.am:.*AM_PROG_CC_C_O' stderr && Exit 1 +grep '^Makefile\.am:.*AUTOMAKE_OPTIONS' stderr && Exit 1 +# Only two lines of warnings. +test $(grep -v 'warnings are treated as errors' stderr | wc -l) = 2 rm -rf autom4te*.cache @@ -67,6 +69,7 @@ cat >configure.ac <