Как проверить удобство использования библиотеки C ++ в configure.in? - PullRequest
12 голосов
/ 20 июня 2009

Я работаю над проектом C ++ для GNU / Linux и ищу способ проверить существование и удобство использования библиотеки IBM Informix с помощью Autotools, а именно редактировать configure.in. У меня нет опыта работы с Autotools, поэтому в основном я беру из сценариев проекта configure.in и др. и копирую и изменяю, где, по моему мнению, нужно изменить. Я адаптируюсь к существующему тексту в configure.in.

До сих пор я успешно использовал AC_CHECK_LIB в configure.in, чтобы проверить, существует ли и может ли использоваться определенная библиотека. Но, похоже, это работает только с библиотеками с функциями , а не, например. классы. А именно, это происходит сбой при тестировании библиотеки Informix libifc++.so:

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

Я также пытался использовать другие комбинации, такие как ITString::ITString и т. Д.

Я не нашел «чистой» функции в API Informix (то есть той, которая не описана в классе C ++). Поэтому я надеюсь, что либо есть способ использовать AC_CHECK_LIB в этом контексте, либо есть другая autoconf / configure.in «команда» для этого конкретного использования.

Заранее благодарим вас за отзыв.

Ответы [ 4 ]

16 голосов
/ 20 июня 2009

Вы обнаружили недостаток автоинструментов, но с ним ничего не поделаешь. Autotools проверяет имена символов в двоичном файле библиотеки, и в отличие от C, где имена символов функций идентичны именам функций, C ++ «искажает» имена символов функций для выполнения таких вещей, как перегрузка функций. Что еще хуже, в C ++ на самом деле даже нет «стандартного» соглашения о календаре, поэтому разные компиляторы C ++ могут создавать разные имена символов для одной и той же функции. Таким образом, autotools не может проверять имена символов C ++ надежным способом.

Есть ли в библиотеке, которую вы пытаетесь использовать, какие-либо функции, объявленные с extern "C"? Это заставляет компилятор C ++ генерировать стандартизированные имена символов в стиле C, и autotools сможет их найти.

Я столкнулся с этой проблемой, пытаясь обнаружить gtest и gmock (фреймворки модульного тестирования и объектной проверки Google) с помощью Autotools, и вот что я придумал:

# 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          
7 голосов
/ 20 июня 2009

Возможно, есть более чистый способ достижения этого, но я думаю, что ваша проблема в том, что методы C ++ «искажаются», чтобы позволить дополнительную информацию о методе (аргументы, типы возврата и т. Д.) Кодироваться. Например; метод int A::foo(void) будет искажен чем-то вроде __ZN1A3fooEv.

Так что вам нужно найти искаженное имя метода в библиотеке. Вы можете сделать это, используя команду nm в Unix-подобных ОС:

$ nm libifc++.so | grep ITString

Стоит отметить, что точный формат искажения зависит от разных компиляторов; и поэтому, встраивая искаженный символ определенного компилятора в configure.in, он может не работать на других платформах - YMMV.

Примечание: вы можете использовать утилиту c++filt, чтобы вернуть имя в читабельную форму; так для примера, который я привел ранее:

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

См. Имя искажения в C ++ в Википедии для получения дополнительной информации.

3 голосов
/ 24 марта 2010

Если библиотека, которую вы проверяете, поддерживает pkg-config , это становится очень просто. Вот все, что я добавил к своему configure.in, чтобы проверить и включить gtest и 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)

А потом по моему Makefile.am где-то:

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

Довольно банально, а?

0 голосов
/ 02 августа 2012
AC_LANG_CPLUSPLUS
AC_CHECK_LIB(Sockets, main)

Предупреждение: http://lists.gnu.org/archive/html/autoconf/2006-09/msg00019.html

...