Call the AC_CHECK_HEADER macro on a condition

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Call the AC_CHECK_HEADER macro on a condition

YuGiOhJCJ Mailing-List
Hello,

This is my configure.ac file:
AC_INIT([my-project], [20160412])
AM_INIT_AUTOMAKE
AM_PROG_CC_C_O
AC_CHECK_HEADER([avr/io.h], [], [AC_MSG_ERROR([missing header: avr/io.h])])
AC_CHECK_HEADER([util/delay.h], [], [AC_MSG_ERROR([missing header: util/delay.h])])
AC_CHECK_HEADER([stdio.h], [], [AC_MSG_ERROR([missing header: stdio.h])])
AC_CHECK_HEADER([time.h], [], [AC_MSG_ERROR([missing header: time.h])])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

The two first header checks must be called only when host is "avr" whereas the two last checks must be called in other cases.

Currently, if I call my configure script with host set to "avr" that's what happens:
$ ./configure --host=avr
checking for a BSD-compatible install... /bin/ginstall -c
checking whether build environment is sane... yes
checking for avr-strip... avr-strip
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for avr-gcc... avr-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... yes
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether avr-gcc accepts -g... yes
checking for avr-gcc option to accept ISO C89... none needed
checking dependency style of avr-gcc... gcc3
checking whether avr-gcc and cc understand -c and -o together... yes
checking how to run the C preprocessor... avr-gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... no
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... no
checking for strings.h... no
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking avr/io.h usability... yes
checking avr/io.h presence... yes
checking for avr/io.h... yes
checking util/delay.h usability... yes
checking util/delay.h presence... yes
checking for util/delay.h... yes
checking stdio.h usability... yes
checking stdio.h presence... yes
checking for stdio.h... yes
checking time.h usability... yes
checking time.h presence... yes
checking for time.h... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands

As you can see the :
AC_CHECK_HEADER([stdio.h], [], [AC_MSG_ERROR([missing header: stdio.h])])
AC_CHECK_HEADER([time.h], [], [AC_MSG_ERROR([missing header: time.h])])
calls are done whereas it is useless for my project when host is "avr".

And you can guess what happens when I call my configure script with host not set:
$ ./configure
checking for a BSD-compatible install... /bin/ginstall -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
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 dependency style of gcc... gcc3
checking whether gcc and cc understand -c and -o together... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking avr/io.h usability... no
checking avr/io.h presence... no
checking for avr/io.h... no
configure: error: missing header: avr/io.h

Here, the:
AC_CHECK_HEADER([avr/io.h], [], [AC_MSG_ERROR([missing header: avr/io.h])])
AC_CHECK_HEADER([util/delay.h], [], [AC_MSG_ERROR([missing header: util/delay.h])])
calls are done whereas when host is my linux machine, these checks should not be done.

So, I would like to call the AC_CHECK_HEADER macro on a condition:
AC_INIT([my-project], [20160412])
AM_INIT_AUTOMAKE
AM_PROG_CC_C_O
if test "x$host" == xavr; then
        AC_CHECK_HEADER([avr/io.h], [], [AC_MSG_ERROR([missing header: avr/io.h])])
        AC_CHECK_HEADER([util/delay.h], [], [AC_MSG_ERROR([missing header: util/delay.h])])
        else
                AC_CHECK_HEADER([stdio.h], [], [AC_MSG_ERROR([missing header: stdio.h])])
                AC_CHECK_HEADER([time.h], [], [AC_MSG_ERROR([missing header: time.h])])
fi
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

With this new configure.ac file, if I call my configure script with host set to "avr" that's what happens:
$ ./configure --host=avr
checking for a BSD-compatible install... /bin/ginstall -c
checking whether build environment is sane... yes
checking for avr-strip... avr-strip
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for avr-gcc... avr-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... yes
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether avr-gcc accepts -g... yes
checking for avr-gcc option to accept ISO C89... none needed
checking dependency style of avr-gcc... gcc3
checking whether avr-gcc and cc understand -c and -o together... yes
checking how to run the C preprocessor... avr-gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... no
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... no
checking for strings.h... no
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking avr/io.h usability... yes
checking avr/io.h presence... yes
checking for avr/io.h... yes
checking util/delay.h usability... yes
checking util/delay.h presence... yes
checking for util/delay.h... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands

It seems to do the job.
The:
AC_CHECK_HEADER([stdio.h], [], [AC_MSG_ERROR([missing header: stdio.h])])
AC_CHECK_HEADER([time.h], [], [AC_MSG_ERROR([missing header: time.h])])
calls are not anymore done.

And that's what happens when I call my configure script with host not set:
$ ./configure
checking for a BSD-compatible install... /bin/ginstall -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
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 dependency style of gcc... gcc3
checking whether gcc and cc understand -c and -o together... yes
checking stdio.h usability... yes
checking stdio.h presence... no
configure: WARNING: stdio.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: stdio.h: proceeding with the compiler's result
checking for stdio.h... yes
checking time.h usability... yes
checking time.h presence... no
configure: WARNING: time.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: time.h: proceeding with the compiler's result
checking for time.h... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands

As you can see, the good thing is that the:
AC_CHECK_HEADER([avr/io.h], [], [AC_MSG_ERROR([missing header: avr/io.h])])
AC_CHECK_HEADER([util/delay.h], [], [AC_MSG_ERROR([missing header: util/delay.h])])
calls are not anymore done.
However, the bad thing is that I got some warnings:
[...]
configure: WARNING: stdio.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: stdio.h: proceeding with the compiler's result
[...]
configure: WARNING: time.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: time.h: proceeding with the compiler's result
[...]

So, I guess my configure.ac file is wrong.

How to do the things correctly please to call the AC_CHECK_HEADER macro on a condition?

Thank you.
Best regards.

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Call the AC_CHECK_HEADER macro on a condition

Nick Bowler-2
Hi,

On 2016-04-12, YuGiOhJCJ Mailing-List <[hidden email]>
wrote:
[snip exposition]

> So, I would like to call the AC_CHECK_HEADER macro on a condition:
> AC_INIT([my-project], [20160412])
> AM_INIT_AUTOMAKE
> AM_PROG_CC_C_O
> if test "x$host" == xavr; then
> AC_CHECK_HEADER([avr/io.h], [], [AC_MSG_ERROR([missing header:
> avr/io.h])])
> AC_CHECK_HEADER([util/delay.h], [], [AC_MSG_ERROR([missing header:
> util/delay.h])])
> else
> AC_CHECK_HEADER([stdio.h], [],
>                               [AC_MSG_ERROR([missing header: stdio.h])])
> AC_CHECK_HEADER([time.h], [],
>                               [AC_MSG_ERROR([missing header: time.h])])
> fi
> AC_CONFIG_FILES([Makefile])
> AC_OUTPUT

The basic problem with the above is that AC_PROG_CPP is not
called properly in your configure.ac.  Because (simplifying
a bit) AC_CHECK_HEADER requires a the preprocessor, it expands

  AC_REQUIRE([AC_PROG_CPP]).

Loosely, this means that the first expansion of AC_CHECK_HEADER
will expand AC_PROG_CPP, if it was not already done.  In your
original version, these expansions were unconditional and things
worked fine.

But in your second instance, the first expansion of AC_CHECK_HEADER
expands AC_PROG_CPP inside an "if".  The result is that no preprocessor
is checked in the "else" case.  You can see this in the configure output,
the following line is only printed in the avr case:

  checking how to run the C preprocessor... avr-gcc -E

There are several basic solutions:

- First, you can just expand AC_PROG_CPP directly and unconditionally
  before your if.  This will ensure the macro is available in both cases.

- Second is to rewrite your condition using AS_IF, which automatically
  "hoists" the dependency AC_PROG_CPP (and any other dependencies)
  outside of the if condition.  For example:

  AS_IF([test x"$host" = x"avr"],
    [AC_CHECK_HEADER([avr/io.h], [],
                     [AC_MSG_ERROR([missing header: avr/io.h])])
     AC_CHECK_HEADER([util/delay.h], [],
                     [AC_MSG_ERROR([missing header: util/delay.h])])],

    [AC_CHECK_HEADER([stdio.h], [],
                     [AC_MSG_ERROR([missing header: stdio.h])])
     AC_CHECK_HEADER([time.h], [],
                     [AC_MSG_ERROR([missing header: time.h])])])

- Third, you can make the checks unconditional but the hard
  failures conditional, e.g.:

  AC_CHECK_HEADER([avr/io.h], [],
    [if test x"$host" = x"avr"; then
       AC_MSG_ERROR([missing header: avr/io.h])
     fi])

Normally I would go with AS_IF.

Hope that helps,
  Nick

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Call the AC_CHECK_HEADER macro on a condition

Eric Blake-3
On 04/12/2016 09:05 AM, Nick Bowler wrote:

>
> But in your second instance, the first expansion of AC_CHECK_HEADER
> expands AC_PROG_CPP inside an "if".  The result is that no preprocessor
> is checked in the "else" case.  You can see this in the configure output,
> the following line is only printed in the avr case:
>
>   checking how to run the C preprocessor... avr-gcc -E
>
> There are several basic solutions:
>
> - First, you can just expand AC_PROG_CPP directly and unconditionally
>   before your if.  This will ensure the macro is available in both cases.
>
> - Second is to rewrite your condition using AS_IF, which automatically
>   "hoists" the dependency AC_PROG_CPP (and any other dependencies)
>   outside of the if condition.  For example:
>
>   AS_IF([test x"$host" = x"avr"],
>     [AC_CHECK_HEADER([avr/io.h], [],
>                      [AC_MSG_ERROR([missing header: avr/io.h])])
>      AC_CHECK_HEADER([util/delay.h], [],
>                      [AC_MSG_ERROR([missing header: util/delay.h])])],
>
>     [AC_CHECK_HEADER([stdio.h], [],
>                      [AC_MSG_ERROR([missing header: stdio.h])])
Also, checking for <stdio.h> is pointless these days.  You can portably
assume a C89 compiler (and these days, often a C99 compiler), which
guarantees <stdio.h> is present.

--
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf

signature.asc (617 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Call the AC_CHECK_HEADER macro on a condition

YuGiOhJCJ Mailing-List
In reply to this post by Nick Bowler-2
On Tue, 12 Apr 2016 11:05:51 -0400
Nick Bowler <[hidden email]> wrote:

> Hi,
>
> On 2016-04-12, YuGiOhJCJ Mailing-List <[hidden email]>
> wrote:
> [snip exposition]
> > So, I would like to call the AC_CHECK_HEADER macro on a condition:
> > AC_INIT([my-project], [20160412])
> > AM_INIT_AUTOMAKE
> > AM_PROG_CC_C_O
> > if test "x$host" == xavr; then
> > AC_CHECK_HEADER([avr/io.h], [], [AC_MSG_ERROR([missing header:
> > avr/io.h])])
> > AC_CHECK_HEADER([util/delay.h], [], [AC_MSG_ERROR([missing header:
> > util/delay.h])])
> > else
> > AC_CHECK_HEADER([stdio.h], [],
> >                               [AC_MSG_ERROR([missing header: stdio.h])])
> > AC_CHECK_HEADER([time.h], [],
> >                               [AC_MSG_ERROR([missing header: time.h])])
> > fi
> > AC_CONFIG_FILES([Makefile])
> > AC_OUTPUT
>
> The basic problem with the above is that AC_PROG_CPP is not
> called properly in your configure.ac.  Because (simplifying
> a bit) AC_CHECK_HEADER requires a the preprocessor, it expands
>
>   AC_REQUIRE([AC_PROG_CPP]).
>
> Loosely, this means that the first expansion of AC_CHECK_HEADER
> will expand AC_PROG_CPP, if it was not already done.  In your
> original version, these expansions were unconditional and things
> worked fine.
>
> But in your second instance, the first expansion of AC_CHECK_HEADER
> expands AC_PROG_CPP inside an "if".  The result is that no preprocessor
> is checked in the "else" case.  You can see this in the configure output,
> the following line is only printed in the avr case:
>
>   checking how to run the C preprocessor... avr-gcc -E
>
> There are several basic solutions:
>
> - First, you can just expand AC_PROG_CPP directly and unconditionally
>   before your if.  This will ensure the macro is available in both cases.
>
> - Second is to rewrite your condition using AS_IF, which automatically
>   "hoists" the dependency AC_PROG_CPP (and any other dependencies)
>   outside of the if condition.  For example:
>
>   AS_IF([test x"$host" = x"avr"],
>     [AC_CHECK_HEADER([avr/io.h], [],
>                      [AC_MSG_ERROR([missing header: avr/io.h])])
>      AC_CHECK_HEADER([util/delay.h], [],
>                      [AC_MSG_ERROR([missing header: util/delay.h])])],
>
>     [AC_CHECK_HEADER([stdio.h], [],
>                      [AC_MSG_ERROR([missing header: stdio.h])])
>      AC_CHECK_HEADER([time.h], [],
>                      [AC_MSG_ERROR([missing header: time.h])])])
>
> - Third, you can make the checks unconditional but the hard
>   failures conditional, e.g.:
>
>   AC_CHECK_HEADER([avr/io.h], [],
>     [if test x"$host" = x"avr"; then
>        AC_MSG_ERROR([missing header: avr/io.h])
>      fi])
>
> Normally I would go with AS_IF.
>
> Hope that helps,
>   Nick

It is a very useful answer with explanations.
I am using AS_IF now and it works perfectly.
Thank you.

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Call the AC_CHECK_HEADER macro on a condition

Earnie Boyd
In reply to this post by Eric Blake-3
On 4/12/2016 11:24 AM, Eric Blake wrote:
>
> Also, checking for <stdio.h> is pointless these days.  You can portably
> assume a C89 compiler (and these days, often a C99 compiler), which
> guarantees <stdio.h> is present.
>

But removing that check would thwart the purpose of autoconf being able
to provide legacy support, would it not?  I suppose there comes a point
in time when legacy needs a maximum age but I think that requires some
acknowledgement from the users of autoconf.

--
Earnie

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Call the AC_CHECK_HEADER macro on a condition

Paul Eggert
In reply to this post by Eric Blake-3
On 04/12/2016 08:24 AM, Eric Blake wrote:
> Also, checking for <stdio.h> is pointless these days.  You can portably
> assume a C89 compiler (and these days, often a C99 compiler), which
> guarantees <stdio.h> is present.

Although it's safe to assume C89ish (or even C99ish) these days, there
is the possibility that it's a freestanding C implementation, where the
C standard does not require <stdio.h>. This might happen in a
bootloader, say, where no operating system is available.

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Call the AC_CHECK_HEADER macro on a condition

Thomas Petazzoni-2
In reply to this post by Nick Bowler-2
Hello,

On Tue, 12 Apr 2016 11:05:51 -0400, Nick Bowler wrote:

> There are several basic solutions:
>
> - First, you can just expand AC_PROG_CPP directly and unconditionally
>   before your if.  This will ensure the macro is available in both cases.
>
> - Second is to rewrite your condition using AS_IF, which automatically
>   "hoists" the dependency AC_PROG_CPP (and any other dependencies)
>   outside of the if condition.  For example:
>
>   AS_IF([test x"$host" = x"avr"],
>     [AC_CHECK_HEADER([avr/io.h], [],
>                      [AC_MSG_ERROR([missing header: avr/io.h])])
>      AC_CHECK_HEADER([util/delay.h], [],
>                      [AC_MSG_ERROR([missing header: util/delay.h])])],
>
>     [AC_CHECK_HEADER([stdio.h], [],
>                      [AC_MSG_ERROR([missing header: stdio.h])])
>      AC_CHECK_HEADER([time.h], [],
>                      [AC_MSG_ERROR([missing header: time.h])])])
>
> - Third, you can make the checks unconditional but the hard
>   failures conditional, e.g.:
>
>   AC_CHECK_HEADER([avr/io.h], [],
>     [if test x"$host" = x"avr"; then
>        AC_MSG_ERROR([missing header: avr/io.h])
>      fi])

I just wanted to thank you for this explanation. I was not affected by
the original issue, but your answer was very useful. Until now, I
thought AS_IF() was just a stupid wrapper around the shell's if clause,
but your answer makes it clear that it is a lot smarter than that.

Thanks!

Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Call the AC_CHECK_HEADER macro on a condition

Julien ÉLIE-2
Hi all,

>> - Second is to rewrite your condition using AS_IF, which automatically
>>    "hoists" the dependency AC_PROG_CPP (and any other dependencies)
>>    outside of the if condition.
>
> I just wanted to thank you for this explanation. I was not affected by
> the original issue, but your answer was very useful. Until now, I
> thought AS_IF() was just a stupid wrapper around the shell's if clause,
> but your answer makes it clear that it is a lot smarter than that.

So did I!

Incidentally, I am aware of AS_IF and AS_CASE constructions, as
described in
<https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Common-Shell-Constructs.html>.
Is it planned to add other macros like AS_FOR, AS_WHILE...?

One may consider doing something like:

for header in $LIST ; do AC_CHECK_HEADER([$header]) ; done

If I understand well, in case $LIST happens to be empty, AC_PROG_CPP
will never be run, and subsequent calls to AC_CHECK_HEADER in the
configure script will fail.

--
Julien ÉLIE

« Je sens que ma dernière hure est proche ! » (Astérix)

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Loading...