Subject: Re: bug#8718: error when using nested conditionals

From: Stefano Lattarini <[email-masked]>
Date: Thu, 9 Jun 2011 21:17:48 +0200

On Monday 23 May 2011, Bruno Haible wrote:
> Hi,
Hello Bruno, sorry for the delay.

> When a Makefile.am has nested conditionals, then when an inner conditional
> is not defined _and_ not needed (because it's in an unused part of the
> Makefile.am), then 'configure' nevertheless emits a fatal error.
>
Ah, but the problem is, autoconf *and* the Automake-provided m4 macros have
no way to know that the conditional is not needed; this is because autoconf
knows nothing about the Makefile.am files, and the current autotools
"layerization" does not allow autoconf to use any sort of "callback" to
automake to get such information (and trying to implement such a "callback"
could open a really, really nasty can of worms IMHO).

> This causes major problems for the new 'conditional-dependencies' mode of
> gnulib-tool.
> 
> How to reproduce:
> 
> In an empty directory, create these files and then run the following commands.
> ================================ configure.ac =================================
> AC_INIT([dummy], [0])
> AM_INIT_AUTOMAKE([foreign])
> AC_PROG_CC
> AC_PROG_RANLIB
> if test 4 = 5; then
>   use_foo=true
>   gl_FOO
> else
>   use_foo=false
> fi
> AM_CONDITIONAL([USE_FOO], [$use_foo])
> AC_CONFIG_FILES([Makefile])
> AC_OUTPUT
> =================================== foo.m4 ====================================
> AC_DEFUN([gl_FOO],
> [
>   if test 7 = 7; then
>     use_variant_a=true
>   else
>     use_variant_a=false
>   fi
>   AM_CONDITIONAL([USE_VARIANT_A], [$use_variant_a])
> ])
> ================================= Makefile.am =================================
> ACLOCAL_AMFLAGS = -I .
> noinst_LIBRARIES = libgnu.a
> libgnu_a_SOURCES = bar.c
> if USE_FOO
> include foo.mk
> else
> libgnu_a_SOURCES += gazonk.c
> endif
> =================================== foo.mk ====================================
> if USE_VARIANT_A
> libgnu_a_SOURCES += foo_a.c
> else
> libgnu_a_SOURCES += foo_b.c
> endif
> ===============================================================================
> $ touch bar.c foo_a.c foo_b.c gazonk.c
> $ aclocal -I .
> $ automake -a -c
> $ autoconf
> $ ./configure
> checking for a BSD-compatible install... /usr/bin/install -c
> checking whether build environment is sane... yes
> checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
> checking for gawk... gawk
> checking whether make sets $(MAKE)... yes
> checking for gcc... gcc
> checking whether the C compiler works... yes
> checking for C compiler default output file name... a.out
> checking for suffix of executables... 
> checking whether we are cross compiling... no
> checking for suffix of object files... o
> checking whether we are using the GNU C compiler... yes
> checking whether gcc accepts -g... yes
> checking for gcc option to accept ISO C89... none needed
> checking for style of include used by make... GNU
> checking dependency style of gcc... gcc3
> checking for ranlib... ranlib
> configure: error: conditional "USE_VARIANT_A" was never defined.
> Usually this means the macro was only invoked conditionally.
> 
> The value of USE_VARIANT_A is irrelevant, because it occurs in the "if USE_FOO"
> part and USE_FOO evaluates to false.
> 
> I don't see how this error could be worked around in gnulib, because
>   1) it is a fatal error.
>   2) What I would need is to extract all AM_CONDITIONALs from foo.m4
>      and execute them with 'false' or 'true' values (doesn't matter which)
>      before executing the code
> 
>        if test 4 = 5; then
>          use_foo=true
>          gl_FOO
>        else
>          use_foo=false
>        fi
> 
>      But because the files { foo.m4, foo.mk, foo_a.c, foo_b.c } should be
>      considered as a unit, and there's no way to execute _just_ the
>      AM_CONDITIONALs inside gl_FOO and not the other statements, I'm
>      blocked.
>
I'm not sure I'm following you here.  Cannot you simply initialize the 
automake conditionals you might need and that you know might be called
conditionally to (possibly dummy) defaults in gl_INIT or gl_EARLY or
something like that?  Sorry if this is a stupid question, but I lack any
real knowledge about this 'conditional-dependencies' mode of gnulib-tool
you're referring to, so I'm mostly guessing here; links or documentation
that can remedy to my ignorance are welcome ;-)

> I do agree that it can be a useful behaviour of Automake to check that
> all conditional have values, not only those that are really used. But it
> should better a warning, rather than an error,
>
I disagree with this, because a configure-time warning could easily go
undetected (much more than an autoconf-time or automake-time warning,
anyway), and thus hide potential bugs.

> and there should be a way to turn it off.
>
This is a sensible and justified request in case we fail to find any easy
workaround to your current predicament.  And it could be easily done with
a new m4 macro, say 'AM_IGNORE_UNDEFINED_CONDITIONALS'.  But I'd rather
try, if possible, to find a solution that works with current Automake too,
and avoid the introduction of yet another macro or yet another option.

Regards,
  Stefano