Thursday, November 22, 2007

Using C/C++ libraries with Automake and Autoconf

Using C/C++ libraries with Automake and Autoconf
Contents
* Introduction.
* CFLAGS and LIBS
* configure.ac
* Makefile.am
* Example Files
* Recommended Reading
Introduction
If you have read Using Automake and Autoconf with C++ then you
already know how to use automake and autoconf to build your C/C
++ programs. This document will show you what you need to add to
those configure.ac and Makefile.am files to link your code with
a shared library.

I have included an example, which links to the examplelib
library used in Building C/C++ libraries with Automake and
Autoconf.

CFLAGS and LIBS
The Makefile needs 2 pieces of information - how to find the
library's header files and how to link to the library itself.
These are traditionally stored in variables ending in CFLAGS
(for the headers' include argument) and LIBS (for the linker
argument). For instance, GTKMM_CFLAGS and GTKMM_LIBS. These
variables will be set in the configure.ac file.

configure.ac
Your configure.ac script should find the library and set the
CFLAGS and LIBS variables:


Libraries which have installed a .pc pkg-config file
Recently, libraries have started to use pkg-config to
provide includes and linker information, instead of the
methods described below. In this case, you should use
the PKG_CHECK_MODULES() macro in your configure.ac file.
For instance:

PKG_CHECK_MODULES(DEPS, gtkmm-2.0 >= 1.3.3 somethingelse-1.0 >= 1.0.2)
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)

DEPS_CFLAGS and DEPS_LIBS will then include the include
and linker options for the library and all of its
dependencies, for you to use in your Makefile.am file. I
have used the DEPS prefix to mean 'dependencies', but
you can use any prefix that you like. Notice that you
can get information about several libraries at once,
putting all of the information into one set of _CFLAGS
and _LIBS variables. You can also use more than one
PKG_CHECK_MODULES() line to put information about
different sets of libraries in separate _CFLAGS and
_LIBS variables.

Of course you must ensure that you have installed
pkg-config.

Libraries which have installed an AM_PATH_* macro
Some libraries, such as gtkmm 1.2, install an m4 macro
which makes your life slightly easier. You can call the
macro from your configure.ac. It will set *_CFLAGS and
*_LIBS variables which you can use in your Makefile.am
files. For instance:

AM_PATH_GTKMM(1.2.2,,AC_MSG_ERROR([Cannot find correct gtkmm version]))

This macro will call the gtkmm-config script and sets
the GTKMM_CFLAGS and GTKMM_LIBS variables with the data
that it returns. It will also report the library version
found and complain if the library is not installed, or
if it is the wrong version.

When you call aclocal the macro will be copied to the
aclocal.m4 file in your project's directory. If you did
not install the library at the same prefix (e.g. /usr
or /usr/local) as the aclocal tool, then you will need
to call aclocal with the -I argument. For instance:

# aclocal -I /home/myinstalls/share/aclocal
Libraries which have installed a *-config script
Some libraries do not install an AM_PATH_* m4 macro, but
they do install a *-config script. In this situation you
need to call the script and set the variables in your
own code.

For instance,

# GNOME--:
# (These macros are in the 'macros' directory,
# copied from the gnome-libs distribution.)
# GNOME_INIT sets the GNOME_CONFIG variable, among other things:
GNOME_INIT
GNOME_COMMON_INIT
GNOME_COMPILE_WARNINGS

# GNOME-CONFIG script knows about gnomemm:
# ('gnome-config' is installed by GNOME)
# So call gnome-config with some arguments:
GNOMEMM_CFLAGS=`$GNOME_CONFIG --cflags gnomemm`
GNOMEMM_LIBS=`$GNOME_CONFIG --libs gnomemm`

AC_SUBST(GNOMEMM_CFLAGS)
AC_SUBST(GNOMEMM_LIBS)
Libraries with no macro and no script
There are still many libraries which do not use *-config
scripts or macros to make your life easier. The best
thing to do in this situation is to allow the user to
tell the configure script where to find the library. You
can do this with the AM_ARG_WITH() macro. This adds a
command line argument to the configure script and
complains if it isn't used.

For instance:

# Ask user for path to libmysqlclient stuff:.
AC_ARG_WITH(mysql,
[ --with-mysql=<path> prefix of MySQL installation. e.g. /usr/local or /usr],
[MYSQL_PREFIX=$with_mysql],
AC_MSG_ERROR([You must call configure with the --with-mysql option.
This tells configure where to find the MySql C library and headers.
e.g. --with-mysql=/usr/local or --with-mysql=/usr])
)
AC_SUBST(MYSQL_PREFIX)
MYSQL_LIBS="-L${MYSQL_PREFIX}/lib/mysql -lmysqlclient"
MYSQL_CFLAGS="-I${MYSQL_PREFIX}/include"
AC_SUBST(MYSQL_LIBS)
AC_SUBST(MYSQL_CFLAGS)


Makefile.am
The CFLAGS and LIBS variables are used in your Makefile.am
files.


For programs
If you are using the library in a program, then you
should do something like the following.

INCLUDES = $(DEPS_CFLAGS)
LIBS = $(DEPS_LIBS)
For libraries
If you are using the library from another library, then
you should do something like the following. This will
not actually link with a shared library - it will just
tells your library that it needs to link with the other
library at run time.

INCLUDES = $(DEPS_CFLAGS)
libsomething_la_LIBADD = $(DEPS_LIBS)
Example Files
You may download this example which demonstrates how to link an
executable to the example library used in Building C/C++
libraries with Automake and Autoconf.

Recommended Reading
* Building C/C++ libraries with Automake and Autoconf
* GNU's automake, autoconf, and libtool manuals

No comments:

Blog Archive