6

I'll start by stating I'm feeling like a moron tonight. I'm trying to minimally reproduce a work issue I have under RHEL5.6, gcc 4.1.2, boost 1.44.0, with Boost Serialization.

The environment I'm having this issue with is Ubuntu Server (with dev packages installed), gcc 4.7.2, and a build of boost 1.44.0 (against the system compiler, packages, etc).

My code compiles cleanly, but I'm getting a myriad of undefined symbols related to various boost::archive types. Running strace on my make, I see it picking up the expected boost_serialization library:

668 43569 stat("/usr/local/boost/1.44.0/lib/libboost_serialization.so", {st_mode=S_IFREG|0755, st_size=700481, ...}) = 0
669 43569 open("/usr/local/boost/1.44.0/lib/libboost_serialization.so", O_RDONLY) = 8

My makefile is:

default: test-app
all: test-app

BOOST := /usr/local/boost/1.44.0

CPPFLAGS := -fPIC -Wall -Wextra -Werror
INCDIRS := -isystem$(BOOST)/include
.LIBDIRS. := $(BOOST)/lib
.LIBS. :=boost_serialization
LIBS := $(foreach lib,$(.LIBS.),-l$(lib))
LIBDIRS := $(foreach dir,$(.LIBDIRS.),-L$(dir))
CPPFLAGS += $(INCDIRS)

base.o : base.cpp base.hpp
        g++ $(CPPFLAGS) --compile $< -o $@ -g

derived.o : derived.cpp base.hpp derived.hpp
        g++ $(CPPFLAGS) --compile $< -o $@ -g

main.o: main.cpp derived.hpp
        g++ $(CPPFLAGS) --compile $< -o $@ -g

test-app: main.o derived.o base.o
        g++ -o $@ $(LIBDIRS) $(LIBS) $^

clean:
        rm -f *.o test

A (very) small sample of the linker errors I'm getting are like:

base.o: In function void boost::archive::basic_text_oprimitive<std::ostream>::save<boost::archive::class_id_reference_type>(boost::archive::class_id_reference_type const&)': /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::archive_exception(boost::archive::archive_exception::exception_code, char const*, char const*)' /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::~archive_exception()' /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::~archive_exception()' base.o: In function void boost::archive::basic_text_oprimitive<std::ostream>::save<boost::archive::tracking_type>(boost::archive::tracking_type const&)': /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::archive_exception(boost::archive::archive_exception::exception_code, char const*, char const*)' /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::~archive_exception()' /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::~archive_exception()' base.o: In function void boost::archive::basic_text_oprimitive<std::ostream>::save<unsigned int>(unsigned int const&)': /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::archive_exception(boost::archive::archive_exception::exception_code, char const*, char const*)' /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::~archive_exception()' /usr/local/boost/1.44.0/include/boost/archive/basic_text_oprimitive.hpp:91: undefined reference to boost::archive::archive_exception::~archive_exception()'

Likewise, if I do a symbol dump on the referenced .so's, I see the required symbols:

objdump -t /usr/local/boost/1.44.0/lib/libboost_serialization.so | c++filt | grep "boost::archive::archive_exception::~archive_exception()" 000000000004e670 g F .text 0000000000000065
boost::archive::archive_exception::~archive_exception() 000000000004e6e0 g F .text 0000000000000009 virtual thunk to boost::archive::archive_exception::~archive_exception() 000000000004e6f0 g F .text 0000000000000012
boost::archive::archive_exception::~archive_exception() 000000000004ed60 g F .text 000000000000005c
boost::archive::archive_exception::~archive_exception() 000000000004e710 g F .text 0000000000000009 virtual thunk to boost::archive::archive_exception::~archive_exception()

I've been banging my head against the table for a while now...hoping someone can help. I don't think the specific source matters, but if requested, I can post it.

Additional environmental details:

g++ --version g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ld --version
GNU ld (GNU Binutils for Ubuntu) 2.22.90.20120924
Copyright 2012 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

Additionally, this is on a VM running under Hyper-V on Windows 8, although, I don't think that matters here.

Complete link line: g++ -L/usr/local/boost/1.44.0/lib -lboost_serialization -o test-app main.o derived.o base.o

Nathan Ernst
  • 4,540
  • 25
  • 38
  • Just to isolate any issues that could be from the set of boost libraries from /usr/local, could you try to point your Makefile to pull the libraries and headers from the ones in /usr/lib and /usr/include instead and see if it compiles there successfully ? – Tuxdude Feb 27 '13 at 04:08
  • 1
    Paste the actual link command `make` is running. – n. m. could be an AI Feb 27 '13 at 04:10
  • @n.m. done above. It's: g++ -L/usr/local/boost/1.44.0/lib -lboost_serialization -o test-app main.o derived.o base.o – Nathan Ernst Feb 27 '13 at 04:42
  • @Tuxdude, initially I was building against the system boost (1.49.0), and I was receiving similar, if not identical, errors. – Nathan Ernst Feb 27 '13 at 04:42
  • 1
    Try reordering your linker command arguments. Object files should go first and the libraries afterwards. – n. m. could be an AI Feb 27 '13 at 04:53
  • @n.m. I've tried the libs before & after the object files...same result. I know 'ld' is order dependent. Libs first is the first attempt I made. – Nathan Ernst Feb 27 '13 at 05:21
  • I tried compiling a sample program using the boost serialization libraries on my system using a version of Makefile you provided and I did not have any issues. The file I tried is this one: http://www.boost.org/doc/libs/1_41_0/libs/serialization/example/demo.cpp BTW the order of arguments to ld should not matter. Can you try compiling same example and see if you get any errors ? – Tuxdude Feb 27 '13 at 05:26
  • Tuxdude, modifying my makefile and using the same above test app (copied from the source at libs/serialization/example.demo.cpp from my 1.44.0 source) - I get the same errors. – Nathan Ernst Feb 27 '13 at 05:32
  • Check your lib with `nm -CD yourlib.so | grep yoursym` – n. m. could be an AI Feb 27 '13 at 05:36
  • I just want to say: I think this issue is an f'up on my end. I'm just not seeing it, and need help. I'm not blaming boost, gcc/g++ or Ubuntu. – Nathan Ernst Feb 27 '13 at 05:37
  • @NathanErnst - I tried the same demo.cpp with the exact Makefile which worked on openSUSE 12.2 on a Ubuntu 12.04 box and I get a similar set of undefined reference errors. :| – Tuxdude Feb 27 '13 at 05:49
  • Also make sure your libraries and objects are the same architecture (i.e. all 32 or all 64 bits). – n. m. could be an AI Feb 27 '13 at 07:54
  • @n.m., all intermediate .o's are x86-64, as is libboost_serialization.so at /usr/local/boost/1.44.0/lib/libbost_serialization.so – Nathan Ernst Feb 27 '13 at 16:16
  • So what did the `nm` check reveal? – n. m. could be an AI Feb 27 '13 at 16:23
  • Shows that the symbol exists: nm /usr/local/boost/1.44.0/lib/libboost_serialization.so | c++filt | grep "boost::archive::archive_exception::~archive_exception()" 000000000004e6f0 T boost::archive::archive_exception::~archive_exception() 000000000004e670 T boost::archive::archive_exception::~archive_exception() 000000000004ed60 T boost::archive::archive_exception::~archive_exception() 000000000004e710 T virtual thunk to boost::archive::archive_exception::~archive_exception() 000000000004e6e0 T virtual thunk to boost::archive::archive_exception::~archive_exception() – Nathan Ernst Feb 27 '13 at 17:14
  • Also odd, I just tried the same code and makefile (with a few tweeks to paths) on a RHEL5.6 machine, and everything linked fine. So, maybe I am beginning to think there might be something wrong with my Ubuntu setup.. – Nathan Ernst Feb 27 '13 at 17:16
  • Are your boost libraries and headers coming from the same boost version? – n. m. could be an AI Feb 27 '13 at 18:13
  • Yeah. On a whim, tried against 1.53.0, same issue. I also tried adding all of the libs and object files into a linker group, no luck there, either. – Nathan Ernst Feb 27 '13 at 18:22
  • If you cannot compile and link against distro-supplied boost as well, I suggest opening a bug in Ubuntu Launchpad. – n. m. could be an AI Feb 27 '13 at 18:27
  • It looks like something specific to Ubuntu, given I ran into the same error with Ubuntu 12.04 with the distro supplied libraries. Filing a bug in Launchpad sounds like the best idea for now. – Tuxdude Feb 27 '13 at 20:27
  • 1
    And searching on google for **undefined reference to boost::archive::archive_exception** yields quite a lot of results on people having trouble linking against the boost serialization library but not one solid solution on how they got it fixed other than trying a different build. I'm not pointing fingers but it just looks to me that it has got something to do with the way the boost libraries are built. In addition I would try posting the question in the boost forum or mailing list if they have one. – Tuxdude Feb 27 '13 at 21:07

2 Answers2

8

I've had the same problem, putting -lboost_serialization at the end like

g++ -L/usr/local/boost/1.44.0/lib -o test-app main.o derived.o base.o -lboost_serialization

should solve it

grizzancs
  • 397
  • 3
  • 11
  • I'll give this a shot later, once I'm home. – Nathan Ernst May 29 '13 at 20:12
  • Thanks, this worked. I had tried using `-Wl,--start-group $(LIBS) $^ -Wl,--end-group`, and my understanding ordering shouldn't matter inside of a group. When I did `-Wl,--start-group $^ $(LIBS) -Wl,--end-group`, the link worked. Weird. Not sure why order should matter within a group. – Nathan Ernst May 30 '13 at 00:11
-1

the binary object .o is not linked with libs.
first verify that in /usr/local/boost/1.44.0/lib there are file's lib boost_serialization.
and next, that lib is registered:
sudo ldconfig -v | grep boost_serialization
if not, create file boost1.44.0.conf in /etc/ld.so.conf.d with user root. With this ligne
usr/local/boost/1.44.0/lib
then start this command
sudo ldconfig -v | grep boost_serialization

  • 3
    This is wrong. Please don't do that. You are not supposed to go root and modify system-wide configs each time you want to link with a non-system library. – n. m. could be an AI Feb 27 '13 at 06:02
  • You need not touch ld.so.conf as long as you pass the correct search paths for linker using the -L option. – Tuxdude Feb 27 '13 at 06:26