bug-autoconf
[Top][All Lists]
Advanced

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

Re: conditionally using AC_PROG_CXX


From: Akim Demaille
Subject: Re: conditionally using AC_PROG_CXX
Date: 30 Oct 2002 13:03:30 +0100
User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Honest Recruiter)

| Hi,
| If using AC_PROG_CXX conditionally (automake-1.7.1 + autoconf-2.54b),
| configure scripts die at configuration time, without any warning nor
| error at autoreconf-time.
| 
| # autoreconf -f
| # ./configure
| checking for a BSD-compatible install... /usr/bin/install -c
| checking whether build environment is sane... yes
| checking for gawk... gawk
| checking whether make sets ${MAKE}... yes
| configure: error: conditional "AMDEP" was never defined.
| Usually this means the macro was only invoked conditionally.
| 
| Cf. example below.

Known issue :(  It is the same as this one:



Prerequisite Macros
-------------------

   A macro that you write might need to use values that have previously
been computed by other macros.  For example, `AC_DECL_YYTEXT' examines
the output of `flex' or `lex', so it depends on `AC_PROG_LEX' having
been called first to set the shell variable `LEX'.

   Rather than forcing the user of the macros to keep track of the
dependencies between them, you can use the `AC_REQUIRE' macro to do it
automatically.  `AC_REQUIRE' can ensure that a macro is only called if
it is needed, and only called once.

 - Macro: AC_REQUIRE (MACRO-NAME)
     If the M4 macro MACRO-NAME has not already been called, call it
     (without any arguments).  Make sure to quote MACRO-NAME with
     square brackets.  MACRO-NAME must have been defined using
     `AC_DEFUN' or else contain a call to `AC_PROVIDE' to indicate that
     it has been called.

     `AC_REQUIRE' must be used inside an `AC_DEFUN''d macro; it must
     not be called from the top level.

   `AC_REQUIRE' is often misunderstood.  It really implements
dependencies between macros in the sense that if one macro depends upon
another, the latter will be expanded _before_ the body of the former.
In particular, `AC_REQUIRE(FOO)' is not replaced with the body of
`FOO'.  For instance, this definition of macros:

     AC_DEFUN([TRAVOLTA],
     [test "$body_temperature_in_celsius" -gt "38" &&
       dance_floor=occupied])
     AC_DEFUN([NEWTON_JOHN],
     [test "$hair_style" = "curly" &&
       dance_floor=occupied])
     
     AC_DEFUN([RESERVE_DANCE_FLOOR],
     [if date | grep '^Sat.*pm' >/dev/null 2>&1; then
       AC_REQUIRE([TRAVOLTA])
       AC_REQUIRE([NEWTON_JOHN])
     fi])

with this `configure.ac'

     AC_INIT
     RESERVE_DANCE_FLOOR
     if test "$dance_floor" = occupied; then
       AC_MSG_ERROR([cannot pick up here, let's move])
     fi

will not leave you with a better chance to meet a kindred soul at other
times than Saturday night since it expands into:

     test "$body_temperature_in_Celsius" -gt "38" &&
       dance_floor=occupied
     test "$hair_style" = "curly" &&
       dance_floor=occupied
     fi
     if date | grep '^Sat.*pm' >/dev/null 2>&1; then
     
     
     fi

   This behavior was chosen on purpose: (i) it prevents messages in
required macros from interrupting the messages in the requiring macros;
(ii) it avoids bad surprises when shell conditionals are used, as in:

     if ...; then
       AC_REQUIRE([SOME_CHECK])
     fi
     ...
     SOME_CHECK

   You are encouraged to put all `AC_REQUIRE's at the beginning of a
macro.  You can use `dnl' to avoid the empty lines they leave.



I have also started to write the following elsewhere:

----------------------------------------------------------------------

@node Keep It Stupid Simple
@subsection Keep It Stupid Simple

It is unfortunate that the most important rule is still a secret today:

@center Never try to be smart with Autoconf

Many people write @file{configure.ac}s that are rejected by different
versions of Autoconf, or will be rejected in the future.  The Autoconf
maintainers often receive complaints about such problems, but they are
really introduced by the users themselves.

@sp 1

The first most common problem is relying on undocumented features.  You
should @strong{never} do that.  If it is undocumented, it is private, and
likely to be changed in the future.  The most frequent reason to rely on
undocumented feature is to save some typing: you have to address a task,
and notice some internal macro performs a job close to your needs.
Don't use it: either you copy and adjust it to your very needs ---under
a different name of course---, or you ask to the maintainers to make a
public version of this macro.

The worst case is with people who want to rely on very low level
details, or even in some cases, @emph{change} some low level macros!
This is doomed to failure.  There are several reasons making maintainers
try this perverse game:

@table @asis
@item bypass the official interface
Autoconf follows the GNU Coding Standards, which some people sometimes
find painful ---for instance because they want options that do not fall
into the GNU standard set of options for @command{configure}.  You
should rely stick to these standards, experience has proved that they
cover all the needs, possibly in an admittedly convoluted way.  And if
they don't, then ask for changes in the GNU Coding Standards: Autoconf
will follow.

@item adjust existing macros to different needs
Many people want to hook their code onto Autoconf macros.  For instance,
``when @code{AC_PROG_CC} is called I want @code{MY_PROG_CC_HOOK} to be
invoked''.  You cannot imagine the complex tissue of interdependencies
that already exists in Autoconf!  Checking for a compiler for instance,
requires relying on many different preliminary initializations and
checks.  The following figures should give you an idea of this amount of
work: @code{AC_PROG_CC} alone produces more than 20Kb of code, almost
900 lines of shell script!  And this code is not contiguous: it goes
into three different sections of @command{configure}.

Don't try to hook your macros: just invoke them.  Sure, your change is
not longer ``invisible'', the user must call it explicitly, but at least
it will be robust.
@end table

If you see no option to address your need, ask the Autoconf maintainers:
either the know the right way to do it, or they will provide you with a
new macro in the official Autoconf.

@sp 1

The second most common problem is trying to optimize
@command{configure}.  For instance they skip long series of tests needed
only for some features the user did not chose.  This exposes you to
extremely nasty, stealthy, vicious bugs.  Unless you know exactly what
you do (I am here referring to people who have an exact knowledge of
Autoconf), @emph{never perform tests conditionally: depend conditionally
on their output!}

Here is a simple example of such an broken ``optimized''
@file{configure.ac}:

@example
AC_INIT

AC_ARG_WITH([fprintf])
if test "x$with_fprintf" = xyes; then
  AC_CHECK_FUNCS(fprintf)
fi

AC_ARG_WITH([sprintf])
if test "x$with_sprintf" = xyes; then
  AC_CHECK_FUNCS(sprintf)
fi
@end example

@noindent
The following runs clearly demonstrate the point of this optimization:

@example
$ @kbd{./configure}
@end example

@noindent
as nothing was needed, nothing was checked for.  If using @code{fprintf}
is requested, then of course, we need a C compiler to check for its
existence, and then check for it:

@example
$ @kbd{./configure --with-fprintf}
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for executable suffix...
checking for object suffix... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for fprintf... yes
@end example

@noindent
Similarly if both @code{fprintf} and @code{sprintf} are needed:

@example
$ @kbd{./configure --with-fprintf --with-sprintf}
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for executable suffix...
checking for object suffix... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for fprintf... yes
checking for sprintf... yes
@end example

@noindent
As expected, @code{fprintf} and @code{sprintf} are both available on my
GNU/Linux system.

Now, sit back, and look at this:

@example
$ @kbd{./configure --with-sprintf}
checking for sprintf... no
@end example

@noindent
although @code{sprintf} @emph{is} present!

What happened is that Autoconf knows that checking for a function
requires a compiler for the current language (here, C), so it actually
expands something similar to the following @file{configure.ac}:

@example
AC_INIT

AC_ARG_WITH([fprintf])
if test "x$with_fprintf" = xyes; then
  AC_PROG_CC
  AC_CHECK_FUNCS(fprintf)
fi

AC_ARG_WITH([sprintf])
if test "x$with_sprintf" = xyes; then
  AC_CHECK_FUNCS(sprintf)
fi
@end example

@noindent
As a consequence, if @code{fprintf} is not requested,
@command{configure} will not look for a C compiler, and all the
following tests are broken.  Never run tests conditionally: depend
conditionally on the @emph{results} of the tests:

@example
AC_INIT

AC_ARG_WITH([fprintf])
AC_CHECK_FUNCS(fprintf)
if test "x$with_fprintf" = xyes; then
  # Depend on the presence/absence of fprintf here.
fi

AC_ARG_WITH([sprintf])
AC_CHECK_FUNCS(sprintf)
if test "x$with_sprintf" = xyes; then
  # Depend on the presence/absence of sprintf here.
fi
@end example




reply via email to

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