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

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

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

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

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

Спасибо, Ченз


person Crazy Chenz    schedule 20.10.2009    source источник


Ответы (3)


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

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

person Braden    schedule 22.10.2009

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

  • Прочтите эту статью, она принесет вам свежие идеи
  • Источники макросов 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
person dma_k    schedule 10.06.2010

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

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

person Herms    schedule 20.10.2009