How to test a C++ library usability in configure.in?
There might be a cleaner way of achieving this, but I think your problem is that C++ methods get "mangled" to allow additional information about the method (argument & return types etc) to be encoded. For example; the method int A::foo(void)
will get mangled to something like __ZN1A3fooEv
.
So you need to find the mangled name of a method in the library. You can do this by using the nm
command on Unix-like OSs:
$ nm libifc++.so | grep ITString
It's worth mentioning that the exact mangling format varies across different compilers; and so by embedding a certain compiler's mangled symbol in your configure.in
it may not work on other platforms - YMMV.
Note: you can use the c++filt
utility to demangle a name back to it's human-readable form; so for the example I gave previously:
$ c++filt __ZN1A3fooEv
A::foo()
See Name Mangling in C++ on Wikipedia for more information.
If the library you are checking for supports pkg-config, this becomes very easy. Here is all I added to my configure.in
to check for and enable gtest
and gmock
:
dnl ************************************
dnl Check for googletest and googlemock
dnl ************************************
PKG_CHECK_MODULES(gtestmock, libgtest >= 0.4.0, libgmock >= 0.4.0)
AC_SUBST(gtestmock_LIBS)
AC_SUBST(gtestmock_CFLAGS)
And then in my Makefile.am
somewhere:
sometarget_CXXFLAGS = $(gtestmock_CFLAGS) $(AM_CXXFLAGS)
sometarget_LDADD = $(gtestmock_LIBS)
Pretty trivial, eh?
You've discovered a shortcoming of autotools, but one that can't really be helped. Autotools checks for symbol names in the library binary, and unlike C where symbol names of functions are identical to the function names, C++ "mangles" function's symbol names to accomplish things like function overloading. What's worse is that C++ doesn't really even have a "standard" mangling convention, so different C++ compilers may produce different symbol names for the same function. Thus, autotools can't check for C++ symbol names in a reliable manner.
Does the library you are trying to use have any functions that are declared with extern "C"
? This causes the C++ compiler to generate standardized C-style symbol names, and autotools will be able to find them.
I ran into this issue trying to detect gtest and gmock (the Google unit testing and object mocking frameworks) with Autotools, and here's what I came up with:
# gtest has a main function in the gtest_main library with C linkage, we can test for that.
AC_CHECK_LIB([gtest_main], [main], [HAVE_GTEST=1] [TEST_LIBS="$TEST_LIBS -lgtest_main"],
AC_MSG_WARN([libgtest (Google C++ Unit Testing Framework) is not installed. Will not be able to make check.]))
# gmock has no functions with C linkage, so this is a roundabout way of testing for it. We create a small test
# program that tries to instantiate one of gmock's objects, and try to link it with -lgmock and see if it works.
if test "$HAVE_GTEST"
then
saved_ldflags="${LDFLAGS}"
LDFLAGS="${LDFLAGS} -lgtest -lgmock"
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <gmock/gmock.h>], [testing::Cardinality dummy])],
[TEST_LIBS="$TEST_LIBS -lgmock"] [HAVE_GMOCK=1],
[AC_MSG_WARN([libgmock (Google C++ Object Mocking Framework) is not installed. Will not be able to make check.])])
LDFLAGS="${saved_ldflags}"
fi