Autoconf with boost test - linker issue
autotools, boost, c++, linker, undefined-reference
Solution
It looks like the macro `BOOST_ENABLE_ASSERT_HANDLER` is somehow being defined.
As stated in the documentation for Boost.Assert, if `BOOST_ENABLE_ASSERT_HANDLER` is defined when `<boost/assert.hpp>` is included, then `BOOST_ASSERT(expr)` expands to a call to `boost::assertion_failed`, but this function is not implemented; the user is expected to provide an implementation.
Try to see if something is causing `BOOST_ENABLE_ASSERT_HANDLER` to be defined when building check_PROGRAMS.
Problem
I'm facing an issue with boost unit_test framework along with autoconf & automake... Here's about the project structure: - ./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 ``` My Problem: When I build the DLL (.so under linux) it works perfectly, but when I try to build the check_PROGRAMS, the linker returns the following undefined references: - undefined reference to FooSingleton::_instance - In function `boost::shared_ptr::operator->() const': undefined reference to boost::assertion_failed(char const*, char const*, char const*, long) About FooSingleton, I don't understand why because I'm well linking my check program with the built dll... About boost, I guess I'm lacking a -lboost_xxxx in my test/Makefile.am, but I don't get why I'd have to explicitly specify boost libs to the linker for check_PROGRAMS while it works perfectly with the DLL build... I've looked everywhere for a solution, but I'm running out of ideas so any help would be appreciated!