I need to conditionally compile some code based on the presence of a library. Seems like this should be easy with autoconf/automake but I can't figure it out.
For example, if there is a PNG library present, I want to include code to use it. My configure.ac has:
AC_CHECK_LIB([png], [png_create_write_struct_2])
and my Makefile.am has:
if USE_LIBPNG
libdev_la_SOURCES += png.c
endif
(which adds png.c to the list of sources for libdev so it gets compiled).
An automake conditional like USE_LIBPNG requires the conditional be defined in configure.ac, so i need:
AM_CONDITIONAL([USE_LIBPNG], [test SOMETHINGOROTHER])
The question is, what can test SOMETHINGOROTHER be? What does AC_CHECK_LIB define that I can test for?
AC_CHECK_LIB's default behavior is to define a symbol (in config.h) which can be used in source code, but that doesn't help the Makefile since the AM_CONDITIONAL needs a shell test
I tried overriding the default AC_CHECK_LIB behavior like so:
AC_CHECK_LIB([png], [png_create_write_struct_2], [HAS_LIBPNG=1])
after which I could test for it:
AM_CONDITIONAL([USE_LIBPNG], [test "x$HAS_LIBPNG" = "x1"])
This is ugly, but works for the Makefile... but creates a new problem: since it discards the original AC_CHECK_LIB behavior, and I no longer get a symbol added to config.h, which I need.
I must be missing something basic, or possible Doing It Wrong. Have been digging around for hours and found no answer.
Anyone?
If the library you're checking for supplies a .pc
file for use with pkg-config
, then you're much better off using PKG_CHECK_MODULES
to get the correct flags. libpng does:
(in configure.ac
)
PKG_CHECK_MODULES([libpng], [libpng12])
This gives you access to the variables $(libpng_CFLAGS)
and $(libpng_LIBS)
which you will want to add to Makefile.am
(probably in AM_CFLAGS
/AM_CXXFLAGS
and LDADD
, or target-specific versions thereof).
It will also cause configure
to fail with an error if libpng12.pc
isn't found. If you want configure
to continue, you'll need to supply the third and fourth arguments to PKG_CHECK_MODULES
, which are ACTION-IF-FOUND
and ACTION-IF-NOT-FOUND
:
(in configure.ac
)
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
Now, if you need an automake
conditional, you can do something like:
(in configure.ac
)
AM_CONDITIONAL([USE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])
If you also need the preprocessor definition, you could use AC_DEFINE
like so:
(in configure.ac
)
AS_IF([test "$USE_LIBPNG" -eq 1], [AC_DEFINE([USE_LIBPNG], [1], [Define if using libpng.])])
Possibly nicer is to set the definition in Makefile.am
:
(in Makefile.am
)
AM_CPPFLAGS =
if USE_LIBPNG
AM_CPPFLAGS += -DUSE_LIBPNG
endif
This will clutter your command line, though, whereas AC_DEFINE
can put the definition in a header if you use AC_CONFIG_HEADERS
. I guess this doesn't really matter if you use AM_SILENT_RULES([yes])
or don't care about your command line being neat (and let's be honest, automake
generates some pretty gnarly command lines anyway).
autoconf
styleIt is considered poor form to build optional support based on whether or not a check succeeded (see this gentoo doc for details). Here's how I'd code optional support for libpng:
(in configure.ac
)
# This is because the first PKG_CHECK_MODULES call is inside a conditional.
PKG_PROG_PKG_CONFIG
AC_ARG_WITH([libpng],
[AS_HELP_STRING([--with-libpng],
[support handling png files @<:@default=check@:>@])],
[],
[with_libpng=check])
AS_CASE(["$with_libpng"],
[yes], [PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1])],
[no], [],
[PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])])
AM_CONDITIONAL([USE_LIBPNG], [test "$with_libpng" != no -a "$HAVE_LIBPNG" -eq 1])
(in Makefile.am
)
if USE_LIBPNG
AM_CPPFLAGS += -DUSE_LIBPNG
AM_CFLAGS += $(libpng_CFLAGS)
LDADD += $(libpng_LIBS)
libdev_la_SOURCES += png.c
endif
.pc
fileFor completeness, here's how I'd check for a library that didn't have a .pc
file. I'll skip over the details of following good autoconf
style. AC_CHECK_LIB
sets a cache variable, so you can test that instead of replacing the ACTION-IF-FOUND
of AC_CHECK_LIB
:
(in configure.ac
)
AC_CHECK_LIB([png], [png_create_write_struct_2])
# Then test:
AS_IF([test "$ac_cv_lib_png_png_create_write_struct_2" = yes], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
# Or set conditional:
AM_CONDITIONAL([USE_LIBPNG], [test "$ac_cv_lib_png_png_create_write_struct_2" = yes])
IMHO, you should only do it this way if you have no other option.