bug-autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: AC_REQUIRE fails to ensure ordering of macros


From: Eric Blake
Subject: Re: AC_REQUIRE fails to ensure ordering of macros
Date: Mon, 29 Dec 2008 20:57:21 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Bruno Haible <bruno <at> clisp.org> writes:

> 
> Same thing with autoconf 2.60..2.62. So if it's really an autoconf bug,
> it must be a long-standing one.

I've played with this some more, and reduced it to a very simple test case.  
Unfortunately, you are right: I am of the opinion that it is a LOOOOONG-
standing autoconf bug; even 2.59 has it.


$ m4 -Ilib m4sugar/m4sugar.m4 - <<\EOF
m4_init
m4_defun([a],[in A
])
m4_defun([b],[in B
m4_require([a])])
m4_defun([c],[in C
m4_require([b])])
m4_divert[]dnl
a
c
EOF
in A

in B

in C

$ m4 -Ilib m4sugar/m4sugar.m4 - <<\EOF
m4_init
m4_defun([a],[in A
])
m4_defun([b],[in B
m4_require([a])])
m4_defun([c],[in C
m4_require([b])])
m4_defun([outer], [pre
a
c
post
])
m4_divert[]dnl
outer
EOF

in B

pre
in A

in C

post


The bug?  When C requires B, the text for B should be injected at the place 
where C will be output, not at the place where the macro invoking B will be 
injected.  In other words, we've forgotten to add C to the stack of defun'd 
macros being expanded, such that require's encountered inside C are wrongly 
treated as require's of outer.

I'm working on a patch now.... :(

Note what happens when you swap things, and expand C before A:

$ m4 -Ilib m4sugar/m4sugar.m4 - <<\EOF
m4_init
m4_defun([a],[in A
])
m4_defun([b],[in B
m4_require([a])])
m4_defun([c],[in C
m4_require([b])])
m4_defun([outer], [pre
c
a
post
])
m4_divert[]dnl
outer
EOF

in A

in B

pre
in C

in A

post


Now both A and B are treated as require's of outer (manifestation of the same 
bug; there is no reason they can't occur after pre).  But notice the second 
occurrence of "in A", which results because A was direct-expanded rather than 
require'd by outer; this is not a bug, but is an explanation for why some 
configure scripts are so bloated - anyone who direct-expands instead of 
require'ing a macro is likely to get multiple copies of the expansion, even if 
the macro only needed to be expanded once.  AC_DEFUN_ONCE exists to help 
isolate the worst offenders, if it is really desired to make smaller m4 scripts.

In the meantime, there _is_ a workaround, already in use in various gnulib 
macros:

$ m4 -Ilib m4sugar/m4sugar.m4 - <<\EOF
m4_init
m4_defun([a],[m4_require([a_body])])
m4_defun([a_body],[in A
])
m4_defun([b],[m4_require([b_body])])
m4_defun([b_body],[in B
m4_require([a])])
m4_defun([c],[m4_require([c_body])])
m4_defun([c_body],[in C
m4_require([b])])
m4_defun([outer],[pre
a
c
post
])
m4_divert
outer
EOF

in A

in B


in C

pre


post


The trick is recognizing that since all released versions of autoconf mishandle 
require's occurring inside direct-invoked defun'd macros inside the body of an 
outer defun'd macro, we merely need avoid that by making any macro which 
_might_ be directly expanded require its body, _and nothing else_, then have 
all the original requires be done as part of that body.  In the existing 
autoconf, this hoists the entire require dependency chain outside outer; my 
goal is that with fixed autoconf, the output will change to the (equally 
correct):

pre
in A
in B
in C
post

So in the case of your original report, it seems like the solution is as simple 
as changing gl_MULTIARCH to defer to a require'd body.

-- 
Eric Blake






reply via email to

[Prev in Thread] Current Thread [Next in Thread]