【问题标题】:Autoconf with boost test - linker issue带有升压测试的 Autoconf - 链接器问题
【发布时间】:2013-03-21 10:39:42
【问题描述】:

我遇到了 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], [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

我的问题

当我构建 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 构建...

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

【问题讨论】:

  • 有一种方法可以定义单例来绕过这个问题,但是理解这个问题仍然很好: static StatisticManager &getInstance() { static StatisticManager instance;返回实例; } 我仍然面临提升未定义的参考!
  • 这里所有的 autotools 样板都相关吗?如果是这样,您可能需要添加一个标签,以便熟悉该环境的人看到这个问题。如果没有,请将代码减少到所需的内容。我不清楚您要解决什么问题。
  • 我的目的是提供尽可能多的信息,以便有足够的信息来找到问题,但我明白你的意思。我试图强调我要解决的问题,我希望这更容易理解!
  • 我认为丹尼尔的回答是正确的。此外 - 您可能会发现 boost.m4 比 autoconf 存档宏更有用。

标签: c++ boost linker autotools undefined-reference


【解决方案1】:

看起来宏 BOOST_ENABLE_ASSERT_HANDLER 正在以某种方式被定义。

the documentation for Boost.Assert 中所述,如果在包含<boost/assert.hpp> 时定义了BOOST_ENABLE_ASSERT_HANDLER,则BOOST_ASSERT(expr) 会扩展为对boost::assertion_failed 的调用,但此函数未实现;用户应该提供一个实现。

尝试查看在构建 check_PROGRAMS 时是否有什么导致 BOOST_ENABLE_ASSERT_HANDLER 被定义。

【讨论】:

  • 非常感谢,你是对的,但是文档没有提供任何示例实现......无论如何,再次感谢伙计们!
  • 我们的项目显然已经定义了这个,但是在一个库中,链接器顺序很关键,我需要包含循环库。谢谢!
猜你喜欢
  • 2014-03-27
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多