1

I'm having issues compiling with boost serialization tools. Info:

  • macOS 10.15.5
  • cmake version 3.19.6 (installed via homebrew)
  • boost version 1.67.0 (installed via homebrew)

I built a small test program, that looks like this:

#include <boost/archive/text_oarchive.hpp>
#include <fstream>

void writeTest(std::string test, std::string filename) {
    std::ofstream ofs( filename.c_str() );
    boost::archive::text_oarchive oa( ofs );

    oa << test;
}

int main(int argc, char *argv[]) {
    writeTest("test123123123", "test.txt");
}

And my CMakeLists.txt file looks like this:

cmake_minimum_required(VERSION 3.0.0)
project(testProj VERSION 0.1.0)

set(CMAKE_CXX_STANDARD 17)

SET (BOOST_MIN_VERSION "1.55.0")

FIND_PACKAGE(Boost ${BOOST_MIN_VERSION} REQUIRED)

include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})

add_executable(testProj main.cpp ${Boost_LIBRARIES})

Then I run cmake --build . in my build folder and get the following error:

Undefined symbols for architecture x86_64:
  "boost::archive::archive_exception::archive_exception(boost::archive::archive_exception::exception_code, char const*, char const*)", referenced from:
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<unsigned int>(unsigned int const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_id_type>(boost::archive::object_id_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_reference_type>(boost::archive::object_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_type>(boost::archive::class_id_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_reference_type>(boost::archive::class_id_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::tracking_type>(boost::archive::tracking_type const&, mpl_::bool_<false>&) in main.cpp.o
  "boost::archive::archive_exception::archive_exception(boost::archive::archive_exception const&)", referenced from:
      void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&) in main.cpp.o
  "boost::archive::archive_exception::~archive_exception()", referenced from:
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<unsigned int>(unsigned int const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_id_type>(boost::archive::object_id_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::object_reference_type>(boost::archive::object_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_type>(boost::archive::class_id_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::class_id_reference_type>(boost::archive::class_id_reference_type const&, mpl_::bool_<false>&) in main.cpp.o
      void boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::save_impl<boost::archive::tracking_type>(boost::archive::tracking_type const&, mpl_::bool_<false>&) in main.cpp.o
      ...
  "boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(boost::archive::text_oarchive&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in main.cpp.o
  "boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::text_oarchive_impl(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, unsigned int)", referenced from:
      boost::archive::text_oarchive::text_oarchive(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, unsigned int) in main.cpp.o
  "boost::archive::basic_text_oarchive<boost::archive::text_oarchive>::newtoken()", referenced from:
      void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<unsigned int>(unsigned int const&) in main.cpp.o
      void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::object_id_type>(boost::archive::object_id_type const&) in main.cpp.o
      void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::object_reference_type>(boost::archive::object_reference_type const&) in main.cpp.o
      void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::class_id_type>(boost::archive::class_id_type const&) in main.cpp.o
      void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::class_id_reference_type>(boost::archive::class_id_reference_type const&) in main.cpp.o
      void boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save<boost::archive::tracking_type>(boost::archive::tracking_type const&) in main.cpp.o
  "boost::archive::basic_text_oprimitive<std::__1::basic_ostream<char, std::__1::char_traits<char> > >::~basic_text_oprimitive()", referenced from:
      boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::~text_oarchive_impl() in main.cpp.o
  "boost::archive::detail::basic_oarchive::end_preamble()", referenced from:
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::version_type>(boost::archive::text_oarchive&, boost::archive::version_type const&) in main.cpp.o
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::object_id_type>(boost::archive::text_oarchive&, boost::archive::object_id_type const&) in main.cpp.o
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::object_reference_type>(boost::archive::text_oarchive&, boost::archive::object_reference_type const&) in main.cpp.o
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::class_id_type>(boost::archive::text_oarchive&, boost::archive::class_id_type const&) in main.cpp.o
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::class_id_reference_type>(boost::archive::text_oarchive&, boost::archive::class_id_reference_type const&) in main.cpp.o
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, boost::archive::tracking_type>(boost::archive::text_oarchive&, boost::archive::tracking_type const&) in main.cpp.o
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(boost::archive::text_oarchive&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in main.cpp.o
      ...
  "boost::archive::detail::basic_oarchive::~basic_oarchive()", referenced from:
      boost::archive::detail::common_oarchive<boost::archive::text_oarchive>::~common_oarchive() in main.cpp.o
  "typeinfo for boost::archive::archive_exception", referenced from:
      void boost::serialization::throw_exception<boost::archive::archive_exception>(boost::archive::archive_exception const&) in main.cpp.o
  "typeinfo for boost::archive::detail::basic_oarchive", referenced from:
      typeinfo for boost::archive::detail::common_oarchive<boost::archive::text_oarchive> in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Maybe it has something to do with the compiler? I checked CMAKE_CXX_COMPILER_ID in cmake which is "AppleClang".

Really appreciate any help, I am totally new to cmake and boost.

  • Serialization is not a header only lib, so you should at least add 'serialization' to your find_package command. Otherwise the lib is not added to the ${Boost_LIBRARIES} variable. – vre Mar 01 '21 at 19:06

1 Answers1

1

Never expand package variables into your sources. Always prefer imported targets. If you do things the easiest possible way in modern CMake, you get simple, portable builds like this:

cmake_minimum_required(VERSION 3.19)
project(testProj VERSION 0.1.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)

find_package(Boost 1.55 REQUIRED serialization)

add_executable(testProj main.cpp)
target_link_libraries(testProj PRIVATE Boost::serialization)

That's all it takes! Imported targets like Boost::serialization set up library and include paths for you. They carry that information with them. I tested this on my Mac Mini with homebrew-installed CMake and Boost and your main.cpp.

To determine which imported targets a package provides, read its documentation. For Boost, it's here: https://cmake.org/cmake/help/latest/module/FindBoost.html

Some general CMake advice: Use lowercase names for CMake commands. Forget include_directories and link_directories exist. Don't create unnecessary variables like BOOST_MIN_VERSION. Finally, never set a minimum CMake version lower than the one you use to test it. CMake doesn't warn you if you use something too new for the minimum version.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
  • Hi Alex, Thanks a lot for your response :) I now get this error when trying to run cmake: ```CMake Error at /usr/local/Cellar/cmake/3.19.6/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:218 (message): Could NOT find Boost (missing: serialization) (found version "1.67.0")``` I installed boost with `brew install boost` but do I need to do anything else to make serialization available? – Asger Kjeldsen Mar 05 '21 at 10:04
  • @AsgerKjeldsen - Sounds like you haven't run `brew update` / `brew upgrade` in a while? For me, `brew install boost` pulled in version 1.75.0_2, not 1.67.0. – Alex Reinking Mar 05 '21 at 17:33
  • I just uninstalled Boost via `brew remove boost` to be sure I wasn't picking up on another installation... I wasn't. It's possible there's a problem with the old 1.67.0 package. Reinstalling Boost 1.75.0 from Homebrew worked for me with no modifications to my answer. – Alex Reinking Mar 05 '21 at 19:10
  • Thanks a lot Alex :) I reinstalled Boost and updated the paths to the boost package, and now it works ! I guess it was an issue with my version. – Asger Kjeldsen Mar 12 '21 at 12:03