【发布时间】: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