[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: divert()/m4_divert() broken in autoconf-2.64+
From: |
Eric Blake |
Subject: |
Re: divert()/m4_divert() broken in autoconf-2.64+ |
Date: |
Tue, 24 Nov 2009 21:46:19 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Mike Frysinger <vapier <at> gentoo.org> writes:
> ok, let's try this example then. same as before ... things break starting
> with autoconf-2.64.
As they should. Don't play with fire without taking precautions against burns.
>
> $ cat configure.in
> AC_INIT
> AC_PROG_CC
Outputs prelimiary text in BODY (aka 1000).
> m4_divert(600)
Changes to 600.
> AC_CHECK_FUNC(socket)
Includes AC_REQUIRE([AC_PROG_CC]), and AC_REQUIRE plays with diversions under
the hood. To avoid outputting the text for AC_PROG_CC twice, autoconf
recognizes that AC_PROG_CC was already expanded, so it does not output a cc
check in 600. The end result? The socket check in 600 has no chance of
succeeding because it occurs in the script prior to the cc checkin in 1000:
600
check for socket
1000
check for cc
About the only case where m4_divert is useful is if you:
a) maintain a stack of current diversions (for this task,
m4_divert_push/m4_divert_pop is much friendlier than raw m4_divert; and
m4_divert_text is friendlier still)
b) don't call any autoconf macros while you are in your special diversion (in
other words, operate under the assumption that an arbitrary autoconf macro may
require a particular current diversion and/or use m4_divert under the hood, so
until you return the diversion stack to its original state, those autoconf
macros will misbehave). The assumption that an autoconf macro may play with
diversions under the hood is surprisingly reliable, because anything that uses
AC_REQUIRE falls into that category.
Yes, it might be possible to rewrite the AC_REQUIRE mechanism from scratch to
track not only whether a macro was expanded, but also into which diversion. If
I were to attempt that, then I could turn this toy example into another
manifestation of the expanded-before-required warning, where the resulting
script looks like:
600
check for cc
check for socket
1000
check for cc
along with a warning that check for cc was expanded before it was required.
But why go to that effort, especially given how many _years_ the AC_REQUIRE
mechanism silently allowed the expand-before-require bug that was finally
diagnosed by my rewrite of AC_REQUIRE for autoconf 2.64? You are using
m4_divert to an unnamed diversion, so you are violating the constraints
recommended by the manual. Until someone can show me a real configure.ac that
NEEDS to use m4_divert, with no other way of using documented autoconf
paradigms to acheive its goal, then I don't see the need to make this toy
example work at the expense of bloating autoconf for normal users.
> inserting a m4_divert() before the AC_INIT (and with different relative
> numbers) doesnt seem to make a difference
That's because AC_INIT sets its own diversion number anyway, overriding your
attempts at changing the diversion before starting autoconf's processing.
Again, proof that you should assume that an arbitrary autoconf macro is likely
to play with diversions under the hood, so you must restore diversions back to
a consistent state before using an autoconf macro.
There are very few reasons to use m4_divert and friends outside of autoconf;
and in general, when someone has pointed out such a reason, I've been
questioning whether it really implies that we would be better off exposing a
public autoconf API that hides the diversion magic under the hood to achieve
the same use case with less user confusion.
But for the record, here's a GOOD example of how a user can apply m4_divert
(and why I still feel okay about documenting m4_divert and friends in the first
place, even if they are tricky to use):
http://git.savannah.gnu.org/cgit/gnulib.git/tree/m4/getopt.m4
Track how the gl_getopt_required variable is used. If the user calls
gl_FUNC_GETOPT_POSIX, then it is assigned the value POSIX in diversion DEFAULTS
(10 - okay, so it goofed in that DEFAULTS is not a documented diversion name).
It does so using m4_divert_text rather than raw m4_divert, and uses a name
rather than a number. If the user calls gl_FUNC_GETOPT_GNU, then it is
assigned the value GNU in diversion INIT_PREPARE (300 - again an undocumented
diversion name). Then both macros proceed to (eventually) require the
expansion of gl_GETOPT_CHECK_HEADERS in diversion BODY (1000). That macro can
then depend on the current definition of $gl_getopt_required - it is guaranteed
to be either GNU or POSIX based on the earlier diversions. If you only called
one of the two interfaces, then the definition is obvious. But if you called
both macros, _in either order_, then gl_getopt_required will be GNU (that is,
requesting the GNU interface has precedence over the POSIX interface, since the
gnu extensions to getopt are indeed a superset of posix, but the configure
writer no longer has to double check whether they called macros in the correct
order). And since neither use of m4_divert_text calls any autoconf macro, but
only outputs shell code that is syntactically valid, then autoconf macros don't
get confused by the temporary diversion changes.
Maybe I should document the diversion names of DEFAULTS and INIT_PREPARE; I'm a
bit undecided on that one. But I don't want to document the values associated
with named diversions, so that we are free to change the underlying value at a
later date (maybe INIT_PREPARE will move to 350 if we add a new named diversion
that needs to be at 300); as long as you go through named interfaces rather
than raw numbers, then we can make such changes under the hood without breaking
compatibility with your configure.ac.
--
Eric Blake
- Re: divert()/m4_divert() broken in autoconf-2.64+, (continued)
- Re: divert()/m4_divert() broken in autoconf-2.64+, Mike Frysinger, 2009/11/21
- Re: divert()/m4_divert() broken in autoconf-2.64+, Ralf Wildenhues, 2009/11/24
- Re: divert()/m4_divert() broken in autoconf-2.64+, Mike Frysinger, 2009/11/24
- Re: divert()/m4_divert() broken in autoconf-2.64+, Ralf Wildenhues, 2009/11/24
- Re: divert()/m4_divert() broken in autoconf-2.64+, Mike Frysinger, 2009/11/24
- Re: divert()/m4_divert() broken in autoconf-2.64+, Eric Blake, 2009/11/24
- Re: divert()/m4_divert() broken in autoconf-2.64+, Mike Frysinger, 2009/11/24
- Re: divert()/m4_divert() broken in autoconf-2.64+, Ralf Wildenhues, 2009/11/27
- Re: divert()/m4_divert() broken in autoconf-2.64+, Mike Frysinger, 2009/11/27
Re: divert()/m4_divert() broken in autoconf-2.64+, Mike Frysinger, 2009/11/21
- Re: divert()/m4_divert() broken in autoconf-2.64+,
Eric Blake <=