Discussion:
Possible bug: AC_USE_SYSTEM_EXTENSIONS ignores "AS_IF" conditionals
David A. Wheeler
2014-09-21 00:19:08 UTC
Permalink
I *think* that AC_USE_SYSTEM_EXTENSIONS has a bug; it seems to ignore conditionals.

E.G., given this configure.ac:
====
AC_PREREQ([2.63])
AC_INIT([bug], [0.01])
AC_CONFIG_HEADERS([config.h])
AS_IF([test 0 = 1 ],
[AC_USE_SYSTEM_EXTENSIONS])
AC_OUTPUT
====

The file "config.h" still enables extensions, even though the test is false.

I'm trying to conditionally use extensions like this:
AS_IF([test "$enable_all_system_extensions" = "yes"],
[AC_USE_SYSTEM_EXTENSIONS])

Am I going about this the wrong way?

Suggestions welcome.

--- David A. Wheeler
Gavin Smith
2014-09-21 16:55:43 UTC
Permalink
I got it down to the use of AC_DEFUN_ONCE in the definition of
AC_USE_SYSTEM_EXTENSIONS. If configure.ac is

AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS_TEST],
[ echo here
])# AC_USE_SYSTEM_EXTENSIONS

AC_PREREQ([2.63])
AC_INIT([bug], [0.01])
# XXXXX 111111111111111111111111111111111111111111111111111111111111111111111
AS_IF([test 0 = 1], [AC_USE_SYSTEM_EXTENSIONS_TEST])
# XXXXXX 22222222222222222222222222222222222222222222222222222222222222222222
AC_OUTPUT

the following appears in configure:

# XXXXX 111111111111111111111111111111111111111111111111111111111111111111111
echo here

if test 0 = 1; then :

fi
# XXXXXX 22222222222222222222222222222222222222222222222222222222222222222222

If AC_DEFUN is used instead, this becomes

# XXXXX 111111111111111111111111111111111111111111111111111111111111111111111
if test 0 = 1; then :
echo here

fi
# XXXXXX 22222222222222222222222222222222222222222222222222222222222222222222

I found there was a mention of this "hoisting" in a discussion:
http://lists.gnu.org/archive/html/autoconf-patches/2009-01/msg00044.html.
Post by David A. Wheeler
Am I going about this the wrong way?
Suggestions welcome.
I haven't investigated or thought about whether this is the right behaviour.
Eric Blake
2014-09-22 14:51:52 UTC
Permalink
Post by David A. Wheeler
I *think* that AC_USE_SYSTEM_EXTENSIONS has a bug; it seems to ignore conditionals.
Not a bug, but a feature.
Post by David A. Wheeler
====
AC_PREREQ([2.63])
AC_INIT([bug], [0.01])
AC_CONFIG_HEADERS([config.h])
AS_IF([test 0 = 1 ],
The whole POINT of AS_IF is to allow macros to hoist pre-req code that
must be run unconditionally to occur before the if statement.
Post by David A. Wheeler
[AC_USE_SYSTEM_EXTENSIONS])
and AC_USE_SYSTEM_EXTENSIONS intentionally defines its body to be a
prerequisite that is hoisted outside the body of AS_IF or any other
macro that uses AC_REQUIRE. It is a feature that unconditional code is
hoisted like this.
Post by David A. Wheeler
AC_OUTPUT
====
The file "config.h" still enables extensions, even though the test is false.
That's because of the way the macros are designed to be expanded. You
are NOT writing:

if test 0 = 1; then
shell code to turn on conditionals
fi

rather, you are writing:

prereqs of any code embedded in the AS_IF, including the
AC_USE_SYSTEM_EXTENSIONS body that unconditionally turns on extensions
if test 0 = 1; then
any conditional remains (of which AC_USE_SYSTEM_EXTENSIONS has none)
fi
Post by David A. Wheeler
AS_IF([test "$enable_all_system_extensions" = "yes"],
[AC_USE_SYSTEM_EXTENSIONS])
Am I going about this the wrong way?
I don't think what you are asking for is possible. Either you want to
use extensions (and just use the macro) or you don't. I don't really
see a use case for wanting extensions on only some of the builds.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
David A. Wheeler
2014-09-22 16:07:52 UTC
Permalink
Post by Eric Blake
I don't think what you are asking for is possible. Either you want to
use extensions (and just use the macro) or you don't. I don't really
see a use case for wanting extensions on only some of the builds.
I want to write code that will *use* extensions where available, but will portably run on
systems that don't have the extensions. Various parts need to detect the
presence of some extensions, and then provide alternatives when they're
not available. Of course, that means I need to able to *test* the alternatives.

Thus, I want to be able to easily *disable*
extensions & then see if the code compiles/links/runs correctly.
My intent was to add a simple configure flag to disable extensions, to enable
some basic testing in those cases.

--- David A. Wheeler
Paul Eggert
2014-09-22 16:38:40 UTC
Permalink
I want to write code that will*use* extensions where available, but will portably run on
systems that don't have the extensions.
That sounds like a reasonable thing to do, but unfortunately autoconf
doesn't support it directly. The best workaround I can come up with off
the top of my head, is to copy the definition of
AC_USE_SYSTEM_EXTENSIONS from the Autoconf source, rename the copy to
dw_USE_SYSTEM_EXTENSIONS, and define the copy with AC_DEFUN rather than
AC_DEFUN_ONCE. It might be helpful to extend Autoconf to provide a
non-ONCE version of AC_USE_SYSTEM_EXTENSIONS, so that this kind of
hackery wasn't needed.
Eric Blake
2014-09-22 17:50:44 UTC
Permalink
Post by David A. Wheeler
Post by Eric Blake
I don't think what you are asking for is possible. Either you want to
use extensions (and just use the macro) or you don't. I don't really
see a use case for wanting extensions on only some of the builds.
I want to write code that will *use* extensions where available, but will portably run on
systems that don't have the extensions. Various parts need to detect the
presence of some extensions, and then provide alternatives when they're
not available. Of course, that means I need to able to *test* the alternatives.
Except that the intent of AC_USE_SYSTEM_EXTENSIONS is basically "enable
the exposure of all known extensions on all systems, so that all later
tests can probe for individual features regardless of whether they are
an extension that needs to be enabled to have a successful probe". Your
program will portably run on all systems if you don't use extensions,
and if you DO use extensions, then you STILL have to test on a
per-feature basis WHICH extensions are available on the given system.
At which point, it is STILL easier to just enable ALL extensions and
then do per-feature testing, than it is to try and make the enablement
of extensions be conditional.
Post by David A. Wheeler
Thus, I want to be able to easily *disable*
extensions & then see if the code compiles/links/runs correctly.
My intent was to add a simple configure flag to disable extensions, to enable
some basic testing in those cases.
That particular use case (explicitly having a mode that disables
extensions even when compiling on a system like GNU/Linux that normally
enables quite a bit) is seldom used in practice, but if it is something
that you really want, I would not be opposed to a patch to make it
easier to achieve. Bear in mind, though, that many systems pollute the
namespace by default; a system that is strictly limited to a
standards-comformant environment and which errors out on attempts to use
extensions is hard to find.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Loading...