Tutorial :How to test a C++ library usability in configure.in?



Question:

I'm working on a C++ project on GNU/Linux and I'm looking for a way to test the existence and usability of IBM Informix's library with the Autotools - namely, editing a configure.in. I don't have experience with Autotools, so basically I'm picking up from the project's configure.in et al. scripts and copying&changing where I feel needs to be changed. IOW, I've been adapting from the existing text in configure.in.

So far I've been using successfully the AC_CHECK_LIB in configure.in to test whether a certain library both exists and is usable. But this only seems to work with libraries with functions, not e.g. classes. Namely, this fails when testing Informix's libifc++.so library:

AC_CHECK_LIB(ifc++, ITString,           INFORMIX_LIB="-L$INFORMIX_LIB_LOCATION/c++ -lifc++ -L$INFORMIX_LIB_LOCATION -L$INFORMIX_LIB_LOCATION/dmi -L$INFORMIX_LIB_LOCATION/esql -lifdmi -lifsql -lifasf -lifgen -lifos -lifgls -lifglx $INFORMIX_LIB_LOCATION/esql/checkapi.o -lm -ldl -lcrypt -lnsl",          echo "* WARNING: libifc++.so not found!"          INFORMIX_INC=""          INFORMIX_LIB=""  )  

I've also tried using other combinations, like ITString::ITString, etc.

I haven't found a "pure" function in Informix's API (i.e., one that isn't contexted in a C++ class). So I'm hoping that either there's a way to use AC_CHECK_LIB in this context, or there's another autoconf/configure.in "command" for this specific use.

Thanks in advance for your feedback.


Solution:1

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.


Solution:2

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            


Solution:3

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?


Solution:4

AC_LANG_CPLUSPLUS  AC_CHECK_LIB(Sockets, main)  

http://lists.gnu.org/archive/html/autoconf/2006-09/msg00019.html


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »