Hi Eric, > I noticed the following, as part of investigating why autoconf on m4's tree > was > so slow on cygwin: > > $ cd m4 > $ autoconf --trace m4_syscmd --trace m4_esyscmd | wc > 72 570 4742 > > It turns out that my additions last September are the culprit [1, 2]. OK to > apply this patch, which cuts down the number of syscmd forks from 72 to 2? > Here's how the autoconf run looks when catching the error: > > $ mv lib/error.c{,.bak} > $ autoconf -f > missing lib/error.c > configure.ac:68: error: problem checking LIBSOURCES > m4/gnulib-comp.m4:42: M4_INIT is expanded from... > configure.ac:68: the top level > autom4te: /usr/local/bin/m4 failed with exit status: 1
Very good observation! When autoconf is slow, I usually blame 'm4', not the number of forks :-) I committed your patch with three small modifications: - Add comments. It wasn't clear to me in the beginning why the two variables were defined as m4 macros and not as shell variables (naive expectation). - Change the error message to be a little more explicit: $ autoconf -f missing file gllib/error.c configure.ac:114: error: expected source file, required through AC_LIBSOURCES, not found configure.ac:28: gl_INIT is expanded from... configure.ac:114: the top level autom4te: /packages/gnu/bin/m4 failed with exit status: 1 - Change the prefix of the two variables. The prefix "AC_" is not appropriate since it's gnulib which defines them, not autoconf. Furthermore, when I see how, in func_import, two blocks of func_emit_initmacro_start/func_emit_initmacro_end are used to produce a single gl_INIT macro, it is safer to prefix the variables with "gl_" in one case and "gltests_" in the other case. Your version was not wrong, since the variables are exploited in func_emit_initmacro_end, not in func_emit_initmacro_done, but it's a walk on very thin ice. Many thanks! It's tricky code. Bruno 2008-05-13 Eric Blake <[EMAIL PROTECTED]> Bruno Haible <[EMAIL PROTECTED]> Reduce number of forks required during autoconf. * gnulib-tool (func_emit_initmacro_start): Prepare gl_LIBSOURCES_LIST and gl_LIBSOURCES_DIR. (func_emit_initmacro_end): Use them here in a single m4_syscmd... (func_emit_initmacro_done) <gl_LIBSOURCES>: ...rather than in one m4_syscmd per file. <m4_foreach_w>: Move... * m4/gnulib-common.m4 (m4_foreach_w): ...here. *** gnulib-tool.orig 2008-05-14 02:04:47.000000000 +0200 --- gnulib-tool 2008-05-14 01:59:13.000000000 +0200 *************** *** 2046,2051 **** --- 2046,2059 ---- # We let automake know about the files to be distributed through the # EXTRA_lib_SOURCES variable. echo " m4_pushdef([AC_LIBSOURCES], m4_defn([${macro_prefix_arg}_LIBSOURCES]))" + # Create data variables for checking the presence of files that are mentioned + # as AC_LIBSOURCES arguments. These are m4 variables, not shell variables, + # because we want the check to happen when the configure file is created, + # not when it is run. ${macro_prefix_arg}_LIBSOURCES_LIST is the list of + # files to check for. ${macro_prefix_arg}_LIBSOURCES_DIR is the subdirectory + # in which to expect them. + echo " m4_pushdef([${macro_prefix_arg}_LIBSOURCES_LIST], [])" + echo " m4_pushdef([${macro_prefix_arg}_LIBSOURCES_DIR], [])" echo " gl_COMMON" } *************** *** 2055,2060 **** --- 2063,2085 ---- func_emit_initmacro_end () { macro_prefix_arg="$1" + # Check the presence of files that are mentioned as AC_LIBSOURCES arguments. + # The check is performed only when autoconf is run from the directory where + # the configure.ac resides; if it is run from a different directory, the + # check is skipped. + echo " m4_ifval([${macro_prefix_arg}_LIBSOURCES_LIST], [" + echo " m4_syscmd([test ! -d ]${macro_prefix_arg}_LIBSOURCES_DIR[ ||" + echo " for gl_file in ]${macro_prefix_arg}_LIBSOURCES_LIST[ ; do" + echo " if test ! -r ]${macro_prefix_arg}_LIBSOURCES_DIR[/\$gl_file ; then" + echo " echo \"missing file ]${macro_prefix_arg}_LIBSOURCES_DIR[/\$gl_file\" >&2" + echo " exit 1" + echo " fi" + echo " done])dnl" + echo " m4_if(m4_sysval, [0], []," + echo " [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])" + echo " ])" + echo " m4_popdef([${macro_prefix_arg}_LIBSOURCES_DIR])" + echo " m4_popdef([${macro_prefix_arg}_LIBSOURCES_LIST])" echo " m4_popdef([AC_LIBSOURCES])" echo " m4_popdef([AC_REPLACE_FUNCS])" echo " m4_popdef([AC_LIBOBJ])" *************** *** 2090,2102 **** echo " ${macro_prefix_arg}_LIBOBJS=\"\$${macro_prefix_arg}_LIBOBJS \$1.\$ac_objext\"" echo "])" echo - echo "# m4_foreach_w is provided by autoconf-2.59c and later." - echo "# This definition is to accommodate developers using versions" - echo "# of autoconf older than that." - echo "m4_ifndef([m4_foreach_w]," - echo " [m4_define([m4_foreach_w]," - echo " [m4_foreach([\$1], m4_split(m4_normalize([\$2]), [ ]), [\$3])])])" - echo echo "# Like AC_REPLACE_FUNCS, except that the module name goes" echo "# into ${macro_prefix_arg}_LIBOBJS instead of into LIBOBJS." echo "AC_DEFUN([${macro_prefix_arg}_REPLACE_FUNCS], [" --- 2115,2120 ---- *************** *** 2111,2119 **** echo "AC_DEFUN([${macro_prefix_arg}_LIBSOURCES], [" echo " m4_foreach([_gl_NAME], [\$1], [" echo " m4_if(_gl_NAME, [alloca.c], [], [" ! echo " m4_syscmd([test -r $sourcebase_arg/]_gl_NAME[ || test ! -d $sourcebase_arg])dnl" ! echo " m4_if(m4_sysval, [0], []," ! echo " [AC_FATAL([missing $sourcebase_arg/]_gl_NAME)])" echo " ])" echo " ])" echo "])" --- 2129,2136 ---- echo "AC_DEFUN([${macro_prefix_arg}_LIBSOURCES], [" echo " m4_foreach([_gl_NAME], [\$1], [" echo " m4_if(_gl_NAME, [alloca.c], [], [" ! echo " m4_define([${macro_prefix_arg}_LIBSOURCES_DIR], [$sourcebase_arg])" ! echo " m4_append_uniq([${macro_prefix_arg}_LIBSOURCES_LIST], _gl_NAME, [ ])" echo " ])" echo " ])" echo "])" *** m4/gnulib-common.m4.orig 2008-05-14 02:04:47.000000000 +0200 --- m4/gnulib-common.m4 2008-05-14 01:32:09.000000000 +0200 *************** *** 1,4 **** ! # gnulib-common.m4 serial 4 dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, --- 1,4 ---- ! # gnulib-common.m4 serial 5 dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, *************** *** 31,36 **** --- 31,43 ---- [Define to 1 when using the gnulib module ]$1[.]) ]) + # m4_foreach_w + # is a backport of autoconf-2.59c's m4_foreach_w. + # Remove this macro when we can assume autoconf >= 2.60. + m4_ifndef([m4_foreach_w], + [m4_define([m4_foreach_w], + [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])]) + # AC_PROG_MKDIR_P # is a backport of autoconf-2.60's AC_PROG_MKDIR_P. # Remove this macro when we can assume autoconf >= 2.60.