2009-10-20 6 views
2

Каков наилучший способ автоматического определения зависимостей библиотек в проекте C/C++?Каков наилучший способ автоматического определения зависимостей библиотек в проекте C/C++?

У меня есть проект, где у меня есть все зависимости от машины. Он строит и работает. Теперь я хочу собрать систему сборки autotools. Я ищу хороший способ автоматического обнаружения всех необходимых зависимостей, таких как используемые файлы заголовков и библиотеки, необходимые для связывания.

Битовая библиотека, пожалуй, самая сложная для меня. Я хотел бы сказать, генерировать команды AC_CHECK_LIB для каждой функции в списке или что-то в этом роде. Возможно, я мог бы сделать это в Perl, но я должен представить, что он уже существует в другом месте.

Что я знаю, так это то, что я могу просматривать символы с objdump и nm, я могу найти, какая библиотека является функцией с этими utilties, тогда я могу вручную ввести команду AC_CHECK_LIB в моем configure.ac, чтобы проверить ее. На этом этапе автоматизация была бы потрясающей.

Спасибо, Chenz

ответ

1

Этот тип исчерпывающего тестирования (т. Е. Каждая функция) не требуется. Не говоря уже о том, что будет трудно поддерживать и занять некоторое время.

Тест на функции, которые, как вы знаете, требуют испытания. Если вы просто проверяете наличие библиотеки, выберите часто используемую функцию, которая будет использоваться в вашем тесте. Если вы хотите удостовериться, что какая-то функция доступна только в новых версиях, попробуйте использовать функцию, только найденную в этих более новых версиях.

0

В Windows я использовал Dependency Walker для вещей, как это. Его вывод является подробным, но он обычно показывает вам каждую библиотеку, которая требуется исполняемому файлу.

Я не знаю ничего подобного для Linux или Mac, но я уверен, что что-то должно существовать.

1

У меня была аналогичная задача. autoconf действительно не очень удобен для трюков C++, но у него есть базовые кирпичи для создания функциональности сверху. Мои предложения после глядя здесь и там:

  • Read this article, это принесет вам свежие идеи
  • Посмотрите на источниках для AUTOCONF макросов в ac-archive (он входит в Debian, так что вы можете использовать его как есть)
  • Я лично написал простой помощник, который копируется из AC_CHECK_LIB и AX_CXX_CHECK_LIB. Да, вам нужно написать мини-тестовую программу, но это позволяет вам тестировать типы, классы (sizeof может работать, но как насчет конструкторов?), Встроенные функции (этого вы не можете сделать с помощью компоновщика) и внешние функций (вы не можете сделать это с помощью nm).

От 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 

Сейчас в 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