2009-06-20 16 views
10

Estoy trabajando en un proyecto de C++ en GNU/Linux y estoy buscando una manera de probar la existencia y la usabilidad de la biblioteca de IBM Informix con las Autotools, es decir, editar un configure.in. No tengo experiencia con Autotools, así que básicamente estoy recogiendo del proyecto configure.iny otros. scripts y copia & cambiando donde siento que necesita ser cambiado. IOW, me he estado adaptando del texto existente en configure.in.¿Cómo probar una usabilidad de la biblioteca C++ en configure.in?

Hasta ahora he estado utilizando con éxito el AC_CHECK_LIB en configure.in para comprobar si una determinada biblioteca existe y es utilizable. Pero esto solo parece funcionar con bibliotecas con funciones, no p. clases Es decir, esto no funciona cuando se prueba libifc++.so la biblioteca de Informix:

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="" 
) 

También he intentado usar otras combinaciones, como ITString::ITString, etc.

no he encontrado una función de "puro" en la API de Informix (es decir, , uno que no está contextualizado en una clase de C++). Así que espero que haya una forma de usar AC_CHECK_LIB en este contexto, o que haya otro autoconf/configure.in "comando" para este uso específico.

Gracias de antemano por su comentario.

Respuesta

5

Puede haber una forma más limpia de lograr esto, pero creo que su problema es que los métodos de C++ se 'destrozan' para permitir que se codifique información adicional sobre el método (argumento & tipos de retorno, etc.). Por ejemplo; el método int A::foo(void) se mutilará a algo como __ZN1A3fooEv.

Así que debe encontrar el nombre destrozado de un método en la biblioteca. Usted puede hacer esto mediante el uso de la nm command en Unix-como sistemas operativos:

$ nm libifc++.so | grep ITString 

Vale la pena mencionar que el formato exacto mangling varía a través de diferentes compiladores; y así, al incrustar el símbolo destrozado de cierto compilador en su configure.in puede que no funcione en otras plataformas, YMMV.

Nota: puede utilizar la utilidad c++filt para exigir un nombre a su forma legible por humanos; así que para el ejemplo que di anteriormente:

$ c++filt __ZN1A3fooEv 
A::foo() 

Ver Name Mangling in C++ en la Wikipedia para más información.

+0

Obras-para-mí. Pensé en hacer algo como esto, pero parecía un truco. Por ejemplo, no estoy seguro de qué sucede si el código se vuelve a compilar con una versión diferente de la biblioteca Informix (espero que cambie el nombre). Pero bueno, ¡funciona! :-) – jbatista

+2

Esto debería seguir funcionando con una nueva versión de biblioteca (asumiendo que los nombres de clase y método no cambian), pero puede romperse si la versión del compilador cambia, y casi seguramente se romperá si alguien más intenta compilar su código en otro compilador o compilador. –

+0

@Tyler - un punto válido; He resaltado esto en la respuesta. – DaveR

13

Ha descubierto un defecto de autotools, pero uno que realmente no puede ser ayudado. Autotools busca nombres de símbolos en el binario de la biblioteca y, a diferencia de C, donde los nombres de símbolos de las funciones son idénticos a los nombres de las funciones, C++ "altera" los nombres de los símbolos para lograr cosas como la sobrecarga de funciones. Lo que es peor es que C++ en realidad ni siquiera tiene una convención de manipulación "estándar", por lo que diferentes compiladores de C++ pueden producir diferentes nombres de símbolos para la misma función. Por lo tanto, las autotools no pueden verificar los nombres de los símbolos C++ de manera confiable.

¿La biblioteca que está intentando utilizar tiene funciones declaradas con extern "C"? Esto hace que el compilador de C++ genere nombres de símbolos de estilo C estandarizados, y las herramientas automáticas podrán encontrarlos.

me encontré con este problema tratando de detectar gtest y gmock (la unidad de pruebas Google y objeto marcos burlones) con Autotools, y esto es lo que ocurrió:

# 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   
2

Si la biblioteca está comprobando las admite pkg-config, esto se vuelve muy fácil. Aquí es todo lo que añadido a mi configure.in para comprobar y permitir gtest y 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) 

Y luego, en algún lugar de mi Makefile.am:

sometarget_CXXFLAGS = $(gtestmock_CFLAGS) $(AM_CXXFLAGS) 
sometarget_LDADD = $(gtestmock_LIBS) 

Bastante trivial, ¿eh?

+0

[Hay problemas] (http://stackoverflow.com/questions/10220946/pkg-check-modules-considered-harmful/10229811#10229811) con el uso de pkg-config. Y, más fundamentalmente, pkg-config y autotools funcionan de una manera diferente. Autoconf comprueba las características, mientras que pkg-config prueba las versiones del paquete. Si está tratando de hacer las cosas a la manera de autotools, lo que debería brindarle la máxima compatibilidad entre los sistemas, no le recomendaría usar pkg-config en absoluto. – edam

Cuestiones relacionadas