Autoconf 与 boost 测试 - 链接器问题

Syf*_*fys 3 c++ linker boost autotools undefined-reference

我正面临 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;
    ...
Run Code Online (Sandbox Code Playgroud)
  • ./include/com_api.h

    #include "com_foo.h"
Run Code Online (Sandbox Code Playgroud)
  • ./include/Makefile.am

    include_HEADERS = \
            com_i_foo.h \
            com_foo.h \
            com_api.h \
            $(NULL)
Run Code Online (Sandbox Code Playgroud)
  • ./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 =
Run Code Online (Sandbox Code Playgroud)
  • ./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
Run Code Online (Sandbox Code Playgroud)
  • ./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()
Run Code Online (Sandbox Code Playgroud)
  • ./Makefile.am

    SUBDIRS = include src test
    #dist_doc_DATA = README
    ACLOCAL_AMFLAGS = -I m4
Run Code Online (Sandbox Code Playgroud)
  • ./configure.ac

    AC_INIT([com_api], [1.0], [bug@foo.foo])
    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
Run Code Online (Sandbox Code Playgroud)

我的问题

当我构建 DLL(Linux 下的 .so)时,它运行良好,但是当我尝试构建 check_PROGRAMS 时,链接器返回以下未定义的引用:

  • 对 FooSingleton::_instance 的未定义引用
  • 在函数`boost::shared_ptr::operator->() const'中:对boost::assertion_failed(char const*, char const*, char const*, long)的未定义引用

关于 FooSingleton,我不明白为什么,因为我很好地将我的检查程序与内置的 dll 链接起来......

关于 boost,我想我的 test/Makefile.am 中缺少 -lboost_xxxx,但我不明白为什么我必须明确地为 check_PROGRAMS 的链接器指定 boost 库,同时它与 DLL 构建完美配合。 ..

我到处寻找解决方案,但我的想法不多了,所以任何帮助将不胜感激!

Dan*_*ien 5

看起来宏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 时是否定义了某些内容。