Undefined reference to Boost copy_file

Problem

C++ code that uses Boost Filesystem was compiling fine with Boost 1.49. However, when I switched to Boost 1.55, the same code gave this error:

foobar.cpp.o: In function `do_something()':
foobar.cpp:(.text+0xb78): undefined reference to `boost::filesystem::detail::copy_file(boost::filesystem::path const&, boost::filesystem::path const&, boost::filesystem::copy_option, boost::system::error_code*)'

This was surprising since the declaration of the copy_file method was present in filesystem.hpp and libboost_filesystem.so was linked during compilation.

Solution

Turns out this is a known bug with Boost Filesystem as described here. Apparently, this happens only if the C++ code is compiled with the -std=c++11 option. I was indeed using that option.

The current fix for this bug is to temporarily disable the C++ scoped enums when the Boost Filesystem header file is included, like this:

#define BOOST_NO_CXX11_SCOPED_ENUMS
#include <boost/filesystem.hpp>
#undef BOOST_NO_CXX11_SCOPED_ENUMS

Tried with: Boost 1.55, GCC 4.8.4 and Ubuntu 14.04

Error building Caffe with Python 3 support

Caffe can be built with support for Python 2.x. This allows you to invoke Caffe easily from Python code. However, I wanted to call Caffe from Python 3.x code.

  • I built Boost with Python 3.x support. I could see that libboost_python3 library files were generated.

  • I added this to the normal CMake command that I use to build Caffe: -Dpython_version=3

Sadly, this popped up errors of this type:

libboost_python.so: undefined reference to `PyClass_Type'

This type of error indicates that the Python 2.x Boost library was being used to compile with Python 3.x libraries.

Undefined reference to boost symbol

Problem

I was compiling code from someone using a Makefile. It gave this error:

/usr/bin/ld: main.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'

Solution

If you demangle the C++ symbol _ZN5boost6system15system_categoryEv using C++Filt you get the function boost::system::system_category(). So, the code was using this function, but was missing the library file. Adding the linker directive -lboost_system to include the library, fixed the error.

Tried with: Ubuntu 14.04

How Boost automatically includes libraries

Boost is mostly a template based library, but using certain functionality requires linking with its libraries. On Windows, when you include a Boost header file in your code, it automatically generates a linking dependency on its corresponding library file. This library path is used by the linker to complete its linking operation.

For example, if I use the threading features of Boost, it generates a dependency on the library file: libboost_thread-vc110-mt-gd-1_53.lib.

This filename has various components: the Boost module, the Visual Studio version, the build type and the Boost version. These are obtained from various definitions in the boost/config/auto_link.hpp header file.

If you find that your code is looking for a Boost library filename that looks wrong in any way, then you might have to look into the above header file and configure some of the definitions.

For example, I built Boost 1.53 on Visual Studio 2013, even though it is not officially supported. When I used this Boost with my code, the linker complained that it was looking for libboost_thread-vc110-mt-gd-1_53.lib. This is strange, since I have built both Boost and my code using Visual Studio 2013 (vc120), but it is looking for Visual Studio 2012 (vc110). I found that the variable BOOST_LIB_TOOLSET was set to vc110 in auto_link.hpp. Changing this fixed the error.

Tried with: Boost 1.53, Visual Studio 2013 and Windows 7 x64

Use of deleted function error with Boost

Problem

I was compiling C++ code that uses the Boost library when the compiler threw out this mysterious error:

/usr/include/boost/thread/pthread/thread_data.hpp: In constructor β€˜boost::detail::tss_data_node::tss_data_node(boost::shared_ptr, void*)’:
/usr/include/boost/thread/pthread/thread_data.hpp:36:41: error: use of deleted function β€˜boost::shared_ptr::shared_ptr(const boost::shared_ptr&)’
                 func(func_),value(value_)

Solution

This type of error typically occurs when there is a feature mismatch between the C++ compiler and the library code. In this case, I was using the Boost library version 1.48.0, which is from Ubuntu 12.04. However, I was using a newer version of the g++ compiler since the code used C++11 features. The version that is in Ubuntu was 4.6, while I using a more recent version 4.8 compiler.

One solution is to go back and use an older version of the C++ compiler. The other solution is to upgrade the Boost library to a more recent version. I chose the second solution and upgraded Boost to version 1.54 and the code compiled without errors.

Tried with: Ubuntu 12.04

How to upgrade the Boost library on Ubuntu

If you use Ubuntu LTS, you are stuck with a pretty old version of the Boost library. You can upgrade to the latest version of Boost in a few steps:

  • First uninstall all the Boost library packages of the current version.

  • Next, add the PPA ppa:boost-latest/ppa and upgrade your installation:

$ sudo add-apt-repository ppa:boost-latest/ppa
$ sudo apt-get update
  • Look at the latest version Boost library packages available to you and install those that you need:
$ aptitude search boost
$ sudo apt-get install libboost1.54-dev

Tried with: Ubuntu 12.04

BoostPro Binaries on 64-bit Computers

BoostPro Computing offers pre-compiled Boost library binaries for Windows here. This is the easiest way to install Boost on Windows, since compiling Boost source code can be quite painful. As of version 1.42.0, BoostPro only offers 32-bit binaries. It is important to note this since the BoostPro installer does not mention that it is 32-bit anywhere. Other 64-bit libraries and code compiled along with this Boost flavor will give strange linker errors like this:

Foobar.obj : error LNK2019: unresolved external symbol __imp____gmpq_clear referenced in function “public: __thiscall CGAL::Gmpq_rep::~Gmpq_rep(void)”

If you have to stick to BoostPro, then you might be forced to switch your other libraries or code to 32-bit mode.

CGAL: Syntax Errors on intmax_t and uintmax_t

Trying to compile CGAL 3.6.1 with Boost 1.42 on Windows generated a lot of errors of this form:

CGAL-3.6.1\auxiliary\gmp\include\mpfr.h(280) : error C2061: syntax error : identifier ‘intmax_t’
CGAL-3.6.1\auxiliary\gmp\include\mpfr.h(283) : error C2061: syntax error : identifier ‘uintmax_t’

The errors are related to the (missing) declaration of intmax_t and uintmax_t. According to this thread on the MPFR mailing list, these errors are caused due to changes in Boost 1.42 and later. So, until MPFR is updated to handle these Boost versions, the solution is to use older versions of Boost. I used Boost 1.41 and CGAL compiled successfully! πŸ™‚