Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::filesystem::copy_file() missing symbol in c++11

Tags:

c++11

boost

If Boost is compiled without C++11 support the boost::filesystem uses emulated scoped enumerators. If you then take this built Boost and use it in a project with C++11 support you end up with a missing symbol because the declaration of boost::filesystem::copy_file() has changed.

There is an easy fix for this:

# if __cplusplus >= 201103L
#   define NO_SCOPED_ENUMS
# endif
# ifdef NO_SCOPED_ENUMS
#   if BOOST_VERSION < 105000
#     ifndef BOOST_NO_SCOPED_ENUMS
#       define BOOST_NO_SCOPED_ENUMS
#       define REMOVE
#     endif
#   else
#     ifndef BOOST_NO_CXX11_SCOPED_ENUMS
#       define BOOST_NO_CXX11_SCOPED_ENUMS
#       define REMOVE
#     endif
#   endif
# endif
# include "boost/filesystem.hpp"
# if defined(NO_SCOPED_ENUMS) && defined(REMOVE)
#   undef REMOVE
#   if BOOST_VERSION < 105000
#     undef BOOST_NO_SCOPED_ENUMS
#   else
#     undef BOOST_NO_CXX11_SCOPED_ENUMS
#   endif
# endif

This preprocess bit defines either the BOOST_NO_SCOPED_ENUMS or BOOST_NO_CXX11_SCOPED_ENUMS depending on the Boost version, includes boost/filesystem and then removes it again if it wasn't defined before (to be safe)

Now the issue here is that the scoped enumerators are turned off when we are compiling for C++11:

# if __cplusplus >= 201103L
#   define NO_SCOPED_ENUMS
# endif

However, if Boost has actually been compiled with C++11 support this will break again because the declaration will be changed. It needs to be something like:

// BOOST_COMPILED_WITH_CXX11 doesn't exist
# if (__cplusplus >= 201103L) && !defined(BOOST_COMPILED_WITH_CXX11)
#   define NO_SCOPED_ENUMS
# endif

This is where my question comes in:

tl;dr - Can I determine if Boost was compiled with C++11 support?

The closest I've found is:

However you run the configure script, when it finishes you will find a new header -user.hpp- located in the <boost-root>/libs/config/ directory. Note that configure does not install this header into your boost include path by default. This header contains all the options generated by the configure script, plus a header-section that contains the user settable options from the default version of (located under /boost/config/).

like image 808
Matt Clarkson Avatar asked Sep 13 '13 10:09

Matt Clarkson


Video Answer


1 Answers

You don't want to link a C++11 project with non-C++11 libraries. C++11 breaks binary compatibility and while things may work in most cases, it will bite you in the butt at some point.

See also do we need to recompile libraries with c++11?

like image 157
thelamb Avatar answered Oct 15 '22 21:10

thelamb