I had a similar challenge now. autoconf is really not so handy for C++ tricks, but it has basic bricks to build the functionality on the top. My suggestions after looking here and there:
- Read this article, it will bring you fresh ideas
- Look at the sources for autoconf macros at ac-archive (it is included into Debian, so you can use it as is)
- I personally have written simple helper, which is copied from
AC_CHECK_LIB
and AX_CXX_CHECK_LIB
. Yes, you need to write a mini-test-program, but this allows you to test types, classes (sizeof
might work, but what about constructors?), inline functions (this you can't do with help of linker) and external functions (you can't do it with nm
).
From aclocal.m4
:
# SYNOPSIS
#
# AX_TRY_LINK(library, includes, function-body [, action-if-true [, action-if-false]])
#
# DESCRIPTION
#
# This function is a wrapper around AC_ARG_WITH, which adds -I"value" to CPPFLAGS.
# "--with-" variable is initialized to default value, if it is passed.
#
AC_DEFUN([AX_TRY_LINK], [
dnl Below logic is a workaround for the limitation, that variables may not allow
dnl symbols like "+" or "-". See AC_CHECK_LIB source comments for more information.
m4_ifval([$4], , [AH_CHECK_LIB([$1])])
AS_LITERAL_IF([$1],
[AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$2])],
[AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1''_$2])])
AC_CACHE_CHECK([for -l$1], [ac_Lib], [
dnl Save the current state
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ax_try_link_save_LIBS=$LIBS
LIBS="-l$1 $LIBS"
AC_TRY_LINK([$2], [$3], [AS_VAR_SET([ac_Lib], [yes])], [AS_VAR_SET([ac_Lib], [no])])
dnl Restore the state to original regardless to the result
LIBS=$ax_try_link_save_LIBS
AC_LANG_RESTORE
])
dnl If the variable is set, we define a constant and push library to LIBS by default or execute $4, otherwise execute $5.
AS_VAR_IF([ac_Lib], [yes],
[m4_default([$4], [
AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1))
dnl Do not prepend a library, if it is already in the list:
(echo $LIBS | grep -q -- "-l$1 ") || LIBS="-l$1 $LIBS"
])],
[$5]
)
AS_VAR_POPDEF([ac_Lib])
]) # AX_ARG_WITH
Now in configure.ac
:
AC_INIT([ABC], [1.2.3])
AC_LANG([C++])
AC_PROG_CXX
AC_CXX_HAVE_STL
if test "x${ac_cv_cxx_have_stl}" != "xyes"; then
AC_MSG_ERROR([STL was not found; make sure you have installed libstdc++-dev])
fi
...
dnl openbabel library
sr_openbabel_lib=yes
AC_CHECK_HEADERS([openbabel/mol.h openbabel/obconversion.h openbabel/builder.h], [], [sr_openbabel_lib=no])
AX_TRY_LINK([openbabel], [
#include <openbabel/mol.h>
#include <openbabel/obconversion.h>
#include <openbabel/builder.h>
], [
OpenBabel::OBAtom atom;
OpenBabel::OBMol mol;
OpenBabel::OBConversion conversion;
atom.IsHeteroatom();
atom.IsCarbon();
mol.NumAtoms();
mol.NumBonds();
mol.NumRotors();
mol.GetAtom(0);
conversion.ReadString(&mol, "");
conversion.WriteString(&mol, false);
], [], [sr_openbabel_lib=no])
if test ${sr_openbabel_lib} != yes; then
AC_MSG_ERROR([openbabel headers or library was not found (use --with-openbabel to define custom header location)])
fi