LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   autoconf qns (https://www.linuxquestions.org/questions/programming-9/autoconf-qns-237324/)

ugenn 09-30-2004 10:13 PM

autoconf qns
 
1. How do I define a custom #define macro in config.h based on configure arguments? eg if I set --with-foo, I would like to have #define WITH_FOO 1 set in config.h

2. How do I make the directory variables (eg @includedir, @shareddir etc) visible to my code? I know how to achieve this by adding -D options to AM_CPPFLAGS in Makefile.am, but I would like to have the macros inside config.h. Can this be done?

3. How do I fail the configure script when a test fails. eg if AC_HEADER_STDC is not found, exit/fail the configure script.

Thanks.

Hko 10-01-2004 08:36 AM

Long answer...
 
About a year ago I was wondering exactly the same things. I didn't find autoconf/automake/m4 stuff very easy. When I read your question I decided to make very basic example package that does the things you asked, so I have it documented for myself in the future as well.

Get it here if you are interested:
http://www.xs4all.nl/~heiky/myprog-0.1.tar.gz

It boils down to this:
Quote:

1. How do I define a custom #define macro in config.h based on configure arguments? eg if I set --with-foo, I would like to have #define WITH_FOO 1 set in config.h
In your package source directory create a file "ac_foo.m4" that looks like this:
(this assumes --with-foo to specify a library directory, not "WITH_FOO 1", but you can figure out how to that from this. It will be easier I think)
Code:

AC_DEFUN([AC_FOO], [
        AC_ARG_WITH([foo], AC_HELP_STRING([--with-foo=DIR], [Foo directory.]), [foo_dir=$withval])

        dnl Do shell scripting here in most cross-platform
        dnl compatible bourne shell (sh) code

        dnl First make sure there's a default for the foo directory ($foo_dir)
        dnl (if --with-foo is not given, m4 parameter here will be empty)
        if test "x$foo_dir" = "x"
        then
                foo_dir=/usr/local/lib/foo
        fi

        dnl Make configure print a "Checking for..." message.
        AC_MSG_CHECKING([for Foo library files])

        dnl Find the directory of foo and check to see
        dnl if $foo_dir contains what you expect from it.
        if ! test -f $foo_dir/foo.so
        then
                dnl This will exit the configure script
                AC_MSG_FAILURE(["Foo library not found!])
        fi

        dnl If did not exit before this line the foo lib dir is OK.

        dnl Set CFLAGS according to what directory we have found
        CFLAGS="$CFLAGS -L$foo_dir"

        dnl Have configure say that it's OK
        AC_MSG_RESULT([yes])

])

Also create a file called "acinclude.m4" to make the above file known to autoconf. This file should look like this:
Code:

sinclude(ac_foo.m4)
And, to make sure "make dist" and "make distcheck" will package the new files in the distribution make sure this is in your "Makefile.am":
Code:

EXTRA_DIST = ac_foo.m4
And finally call the new m4 macro (from the file "ac_foo.m4") from "configure.ac":
Code:

AC_INIT([My Program], [0.1], [you@somewhere.com], [myprog])
AC_CONFIG_SRCDIR([main.c])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_PROG_INSTALL
AC_FOO
AC_CONFIG_FILES([Makefile])
AC_OUTPUT


Quote:

2. How do I make the directory variables (eg @includedir, @shareddir etc) visible to my code? I know how to achieve this by adding -D options to AM_CPPFLAGS in Makefile.am, but I would like to have the macros inside config.h. Can this be done?
I found an m4 file that does this in the "autoconf archive" from the GNU site. It's called "ac_define_dir:
Code:

dnl Taken from the autoconf archive (www.gnu.org)
dnl
dnl @synopsis AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
dnl
dnl This macro _AC_DEFINEs VARNAME to the expansion of the DIR
dnl variable, taking care of fixing up ${prefix} and such.
dnl
dnl Note that the 3 argument form is only supported with autoconf 2.13 and
dnl later (i.e. only where _AC_DEFINE supports 3 arguments).
dnl
dnl Examples:
dnl
dnl    AC_DEFINE_DIR(DATADIR, datadir)
dnl    AC_DEFINE_DIR(PROG_PATH, bindir, [Location of installed binaries])
dnl
dnl @version $Id: ac_define_dir.m4,v 1.1 2002/12/31 02:15:21 heiko Exp $
dnl @author Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva

AC_DEFUN([AC_DEFINE_DIR], [
  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
  ac_define_dir=`eval echo [$]$2`
  ac_define_dir=`eval echo [$]ac_define_dir`
  ifelse($3, ,
    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
])

To use this, put this file also in your source directory, and like the --with-foo procedure above, mention it in the "acinclude.m4" file:
Code:

sinclude(ac_foo.m4)
sinclude(ac_define_dir.m4)

..and in your Makefile.am:
Code:

EXTRA_DIST = ac_define_dir.m4 ac_foo.m4
(note that the "ac_foo.m4" stuff from before is also included)

And finally call it from configure.ac". Here the datadir is #defined in config.h. (the datadir is the directory to store data used by your program. By default ./configure will make it: $PREFIX/share)
Code:

AC_DEFINE_DIR([DATADIR], [datadir], [Directory for data files.])

Quote:

3. How do I fail the configure script when a test fails. eg if AC_HEADER_STDC is not found, exit/fail the configure script.
Use this (also see the first listing in this post):
Code:

AC_MSG_FAILURE(["Your custom error message"])
Like I already said, I've put a working example program package including all this on the web at:
http://www.xs4all.nl/~heiky/myprog-0.1.tar.gz

If you can improve or extend that, I'd be very interested!

ugenn 10-01-2004 09:46 PM

Thanks a lot.That was really helpful. I'll see what I can add once I make sense of it. :)

Hko 10-02-2004 06:33 AM

P.S. The code assumes autoconf version 2.57 or higher.

ugenn 10-31-2004 06:43 AM

Sorry for the evil bump.

How can I select certain subdirs to compile based on the user's configure --enable option?

eg.
/foo
-> foo.c
-> Makefile.am
main.c
configure.in
Makefile.am

If the user used configured --enable-foo, I would build in foo, otherwise, foo is left out.

I tried this in configure.in, but didn't work as thought:

Code:

if test x"with_foo" = xyes ; then
  AC_OUTPUT([Makefile foo/Makefile])
else
  AC_OUTPUT([Makefile])
fi



All times are GMT -5. The time now is 10:21 AM.