Autoconf с тестом повышения - проблема с компоновщиком

У меня возникла проблема с фреймворком boost unit_test вместе с autoconf и automake...

Вот структура проекта:

  • ./include/com_i_foo.h
  • ./include/com_foo.h

    ...
    class FooSingleton {
    protected:
    FooSingleton() {}
    private:
    FooSingleton* _instance;
    public:
    virtual ~FooSingleton() {}
    static FooSingleton* getInstance();
    };

    class FooFoo {
    public:
    FooFoo() {}
    virtual uint32_t getSomeInt();
    virtual ~FooFoo() {}
    };
    typedef boost::shared_ptr FooFooPtr_t;
    ...
  • ./include/com_api.h

    #include "com_foo.h"
  • ./include/Makefile.am

    include_HEADERS = \
            com_i_foo.h \
            com_foo.h \
            com_api.h \
            $(NULL)
  • ./src/com_foo.cpp
  • ./src/Makefile.am

    PLATEFORM=LINUX64
    DEBUG_OPTIONS = -g
    DEFINE_OPTIONS=-D${PLATEFORM}
    OPTIONS = -Wall -Werror -shared -O2 $(DEBUG_OPTIONS) $(DEFINE_OPTIONS)

    COMMON_CXXFLAGS= ${OPTIONS} -I$(top_builddir)/include
    ACLOCAL_AMFLAGS = -I ${top_builddir}/m4
    AM_LDFLAGS=

    lib_LTLIBRARIES  = \
            libcom_api.la \
            $(NULL)

    libcom_api_la_SOURCES = com_foo.cpp
    libcom_api_la_CXXFLAGS = ${COMMON_CXXFLAGS}
    libcom_api_la_LDFLAGS =
    libcom_api_la_LIBADD =
  • ./test/Makefile.am

    PLATEFORM=LINUX64
    DEBUG_OPTIONS = -g
    DEFINE_OPTIONS=-D${PLATEFORM} -DBOOST_ENABLE_ASSERT_HANDLER
    OPTIONS = -Wall -Werror -O2 $(DEBUG_OPTIONS) $(DEFINE_OPTIONS)

    BOOST_LIBS = -lboost_unit_test_framework -lboost_locale -lboost_filesystem -lboost_system -lboost_thread

    COMMON_CXXFLAGS= ${OPTIONS} -I$(top_srcdir)/include -I$(top_srcdir)/src
    AM_LDFLAGS=
    ACLOCAL_AMFLAGS = -I ${top_builddir}/m4

    check_PROGRAMS = ut_com_api

    ut_com_api_SOURCES = \
            ut_com_api.cpp \
            $(NULL)
    ut_com_api_CXXFLAGS = ${COMMON_CXXFLAGS}
    ut_com_api_LDFLAGS = -rdynamic
    ut_com_api_LDADD = ${BOOST_LIBS} $(top_builddir)/src/libcom_api.la
  • ./test/ut_com_api.cpp

    #define BOOST_LIB_DIAGNOSTIC
    #define BOOST_TEST_DYN_LINK
    #define BOOST_TEST_MODULE "Common API Unit tests"

    #include 

    #include "com_api.h"

    using namespace boost::unit_test;

    BOOST_AUTO_TEST_SUITE(com_api)

    BOOST_AUTO_TEST_CASE(FooFooTest) {
    FooFooPtr_t myFoo(new FooFoo());
    BOOST_CHECK(myFoo->getSomeInt() == 2);
    }

    BOOST_AUTO_TEST_CASE(FooSingletonTest) {
    FooSingleton* myFoo = FooSingleton::getInstance();
    BOOST_CHECK(myFoo != NULL);
    }

    BOOST_AUTO_TEST_SUITE_END()
  • ./Makefile.am

    SUBDIRS = include src test
    #dist_doc_DATA = README
    ACLOCAL_AMFLAGS = -I m4
  • ./configure.ac

    AC_INIT([com_api], [1.0], [[email protected]])
    AC_CONFIG_MACRO_DIR([m4])
    AM_INIT_AUTOMAKE([-Wall -Werror foreign])
    AC_PROG_LIBTOOL
    AC_PROG_CXX
    AC_LANG_PUSH(C++)
    AX_BOOST_BASE([1.53], ,[AC_MSG_ERROR([You need boost library])])
    AX_BOOST_PROGRAM_OPTIONS
    AX_BOOST_DATE_TIME
    AC_CHECK_HEADER([boost/shared_ptr.hpp], , [AC_MSG_ERROR([You need boost library])])
    AC_LANG_POP(C++)
    AC_CONFIG_HEADERS([config.h])
    AC_CONFIG_FILES([
    Makefile
    include/Makefile
    src/Makefile
    test/Makefile
    ])
    AC_OUTPUT

Моя проблема:

Когда я создаю DLL (.so под linux), она работает отлично, но когда я пытаюсь собрать check_PROGRAMS, компоновщик возвращает следующие неопределенные ссылки:

  • неопределенная ссылка на FooSingleton::_instance
  • В функции `boost::shared_ptr::operator->() const': неопределенная ссылка на boost::assertion_failed(char const*, char const*, char const*, long)

Насчет FooSingleton, я не понимаю, почему, потому что я хорошо связываю свою программу проверки со встроенной dll ...

Что касается повышения, я думаю, что мне не хватает -lboost_xxxx в моем test/Makefile.am, но я не понимаю, почему мне нужно явно указывать библиотеки повышения для компоновщика для check_PROGRAMS, в то время как он отлично работает со сборкой DLL. ..

Я везде искал решение, но у меня заканчиваются идеи, поэтому любая помощь будет оценена!


person Syffys    schedule 31.03.2013    source источник
comment
Есть способ определить синглтон, чтобы обойти эту проблему, но было бы неплохо понять проблему: static StatisticManager &getInstance() { static StatisticManager instance; вернуть экземпляр; } Я все еще сталкиваюсь с неопределенной ссылкой boost!   -  person Syffys    schedule 31.03.2013
comment
Уместны ли здесь все шаблоны autotools? Если это так, вы можете добавить тег, чтобы кто-то, знакомый с этой средой, увидел этот вопрос. Если нет, сократите код до необходимого. Мне не очевидно, какую проблему вы пытаетесь решить.   -  person Sam Miller    schedule 31.03.2013
comment
Мое намерение состояло в том, чтобы предоставить как можно больше информации, чтобы найти проблему, но я понял вашу точку зрения. Я попытался выделить то, что я пытаюсь исправить, надеюсь, это более понятно!   -  person Syffys    schedule 01.04.2013
comment
Я думаю, что ответ Даниэля правильный. Кроме того, вы можете найти boost.m4 более полезным, чем макросы архива autoconf.   -  person Brett Hale    schedule 01.04.2013


Ответы (1)


Похоже, что макрос BOOST_ENABLE_ASSERT_HANDLER каким-то образом определяется.

Как указано в документации для Boost.Assert, если BOOST_ENABLE_ASSERT_HANDLER определяется при включении <boost/assert.hpp>, затем BOOST_ASSERT(expr) расширяется до вызова boost::assertion_failed, но эта функция не реализована; ожидается, что пользователь предоставит реализацию.

Попробуйте посмотреть, не вызывает ли что-то определение BOOST_ENABLE_ASSERT_HANDLER при сборке check_PROGRAMS.

person Daniel Trebbien    schedule 31.03.2013
comment
Большое спасибо, вы правы, однако в документации нет примера реализации... В любом случае, еще раз спасибо, ребята! - person Syffys; 01.04.2013
comment
В наших проектах, по-видимому, это определено, но в библиотеке такой порядок компоновщика имеет решающее значение, и мне нужно было включить циклическую библиотеку. Спасибо! - person sage; 03.11.2015