[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
AC_DEFUN_ONCE and maintainability
From: |
Bruno Haible |
Subject: |
AC_DEFUN_ONCE and maintainability |
Date: |
Tue, 03 Jul 2012 03:08:32 +0200 |
User-agent: |
KMail/4.7.4 (Linux/3.1.10-1.9-desktop; KDE/4.7.4; x86_64; ; ) |
Hi Eric,
> The canonical
> fix in gnulib is to use AC_DEFUN_ONCE instead of AC_DEFUN for any
> function that we want to guarantee that it gets expanded without
> triggering the older autoconf bug.
You're right; I should revert the patch and use
AC_DEFUN_ONCE([gl_FUNC_LOG],...) instead.
But I have two issues with AC_DEFUN_ONCE. The first one is a maintainability
issue:
There are 4 classes of Autoconf macros in Gnulib:
(A) Macros that are defined at m4 level and not subject to reordering
via AC_REQUIRE. Defined through m4_defun.
(B) Macros that takes arguments, meant to be invoked (possibly inside
'if' branches).
(C) Macros without arguments, that can be required - must be safe to reorder,
must not call AC_LIBOBJ.
(D) Macros without arguments, that can be required - must be safe to reorder,
must not call AC_LIBOBJ - or invoked (but not inside 'if' branches).
So far,
for (B) we use AC_DEFUN,
for (C) we use AC_DEFUN,
for (D) we use AC_DEFUN_ONCE.
Issue #1: When I add an AC_REQUIRE([FOO]) somewhere, I don't immediately
know whether I have to transform AC_DEFUN([FOO]) to AC_DEFUN_ONCE([FOO]) -
because to determine whether we're in case (B) or (C) requires grepping
across all of Gnulib.
Issue #2: When I add an invocation FOO somewhere, I don't immediately
know whether I have to transform AC_DEFUN([FOO]) to AC_DEFUN_ONCE([FOO]) -
because to determine whether we're in case (B) or (C) requires grepping
across all of Gnulib.
Issue #3: When I add some code inside macro FOO, I don't know whether I'm
allowed to rely on global variables (possible in case (B)) or whether I
have to provide position independent code (in case (C)) - because to
determine whether we're in case (B) or (C) requires grepping across all
of Gnulib.
So it would be better to be able to distinguish cases (B) and (C).
I suggest to introduce a new macro AC_ONCE, that expands to AC_DEFUN,
so that:
for (B) we use AC_DEFUN,
for (C) we use AC_ONCE,
for (D) we use AC_DEFUN_ONCE.
About the naming: The macro FOO in case (C) cannot take arguments and
cannot be invoked; it is far from a "function" - and 'defun' in Lisp
is meant to define a function.
Considering just the macros named gl_FUNC_*, here would be the suggested
changes:
Candidates for changing AC_DEFUN -> AC_ONCE:
gl_FUNC_REALPATH_WORKS
gl_FUNC_EACCESS
gl_FUNC_FEGETROUND
gl_FUNC_GETCWD_NULL
gl_FUNC_GETCWD_SIGNATURE
gl_FUNC_MEMMEM_SIMPLE
gl_FUNC_STRERROR_0
gl_FUNC_STRERROR_R_WORKS
gl_FUNC_UTIMES
Candidates for changing AC_DEFUN_ONCE -> AC_ONCE:
gl_FUNC_CHOWN_FOLLOWS_SYMLINK
gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
Candidates for changing AC_DEFUN -> AC_DEFUN_ONCE:
gl_FUNC_ACOS
gl_FUNC_ACOSL
gl_FUNC_ASIN
gl_FUNC_ASINL
gl_FUNC_ATAN
gl_FUNC_ATAN2
gl_FUNC_ATANL
gl_FUNC_CBRT
gl_FUNC_CBRTL
gl_FUNC_CEIL
gl_FUNC_CEILF
gl_FUNC_CEILL
gl_FUNC_CLOSE
gl_FUNC_COPYSIGN
gl_FUNC_COS
gl_FUNC_COSH
gl_FUNC_COSL
gl_FUNC_EUIDACCESS
gl_FUNC_EXP
gl_FUNC_EXP2
gl_FUNC_EXP2L
gl_FUNC_EXPL
gl_FUNC_EXPM1
gl_FUNC_EXPM1F
gl_FUNC_EXPM1L
gl_FUNC_FABS
gl_FUNC_FABSF
gl_FUNC_FABSL
gl_FUNC_FLOOR
gl_FUNC_FLOORF
gl_FUNC_FLOORL
gl_FUNC_FMA
gl_FUNC_FMOD
gl_FUNC_FMODF
gl_FUNC_FMODL
gl_FUNC_FNMATCH_POSIX
gl_FUNC_FREXP
gl_FUNC_FREXPF
gl_FUNC_FREXPL
gl_FUNC_FSEEKO
gl_FUNC_FTELLO
gl_FUNC_GETOPT_POSIX
gl_FUNC_HYPOT
gl_FUNC_HYPOTF
gl_FUNC_HYPOTL
gl_FUNC_ILOGB
gl_FUNC_INET_NTOP
gl_FUNC_ISNAND
gl_FUNC_ISNANF
gl_FUNC_ISNANL
gl_FUNC_LDEXP
gl_FUNC_LDEXPF
gl_FUNC_LDEXPL
gl_FUNC_LINK_FOLLOWS_SYMLINK
gl_FUNC_LOG and modify modules/log
gl_FUNC_LOG10
gl_FUNC_LOG10F
gl_FUNC_LOG1P
gl_FUNC_LOG1PF
gl_FUNC_LOG1PL
gl_FUNC_LOG2
gl_FUNC_LOG2F
gl_FUNC_LOGB
gl_FUNC_LOGF
gl_FUNC_LOGL
gl_FUNC_MBRTOWC
gl_FUNC_MEMCHR
gl_FUNC_MKFIFO
gl_FUNC_MKTIME
gl_FUNC_MMAP_ANON
gl_FUNC_MODF
gl_FUNC_MODFF
gl_FUNC_MODFL
gl_FUNC_OPENAT
gl_FUNC_POW
gl_FUNC_REMAINDER
gl_FUNC_REMAINDERF
gl_FUNC_REMAINDERL
gl_FUNC_RENAME
gl_FUNC_RINT
gl_FUNC_RMDIR
gl_FUNC_ROUND
gl_FUNC_ROUNDF
gl_FUNC_ROUNDL
gl_FUNC_SELECT
gl_FUNC_SETENV_SEPARATE
gl_FUNC_SIN
gl_FUNC_SINH
gl_FUNC_SINL
gl_FUNC_SQRT
gl_FUNC_SQRTL
gl_FUNC_STRERROR_R
gl_FUNC_STRCASESTR_SIMPLE
gl_FUNC_STRSTR_SIMPLE
gl_FUNC_TAN
gl_FUNC_TANH
gl_FUNC_TANL
gl_FUNC_TRUNC
gl_FUNC_TRUNCF
gl_FUNC_TRUNCL
gl_FUNC_UNLINK
gl_FUNC_VFPRINTF_POSIX
gl_FUNC_WCWIDTH
More generally, this would lead to the coding convention that all macros
gl_FUNC_FOO for a single function foo() would be an AC_DEFUN_ONCE.
The macro AC_ONCE would be defined in 00gnulib.m4.
Bruno