2

My colleague came to me with some linker errors they were seeing when trying to compile some code using CMake that was using Boost::serialization functionality. I tried to help them work through the problem but unfortunately this has been stumping me as well. I am not an expert in Boost or CMake, so perhaps I am missing something obvious to more experienced individuals. The simple main.cpp test code is the following:

#include <iostream>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp>

int main() {

    double number = 64.0;
    std::string my_string;
    boost::iostreams::back_insert_device<std::string> inserter(my_string);
    boost::iostreams::stream<boost::iostreams::back_insert_device<std::string> > si(inserter);
    boost::archive::binary_oarchive oa(si);
    oa << number;

    std::string serial_str = "My name is... ";
    std::string new_str;
    boost::iostreams::basic_array_source<char> device2(serial_str.data(), serial_str.size());
    boost::iostreams::stream<boost::iostreams::basic_array_source<char> > so(device2);
    boost::archive::binary_iarchive ia(so);
    ia >> new_str;
}

The CMakeLists.txt file used to compile this code is:

# minimum cmake version
cmake_minimum_required(VERSION 3.16)

# basic project info
project(boost_testing VERSION 0.1.0
        DESCRIPTION "project for testing boost stuff"
        LANGUAGES CXX)

# set the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# get the needed packages
find_package(Boost REQUIRED COMPONENTS serialization system iostreams)

# add a test executable, link with desired libraries, and modify include paths
message(STATUS "${Boost_LIBRARIES}")
add_executable(test_boost main.cpp)
target_link_libraries(test_boost PRIVATE Boost::serialization Boost::system Boost::iostreams)
target_include_directories(
        test_boost PUBLIC
        ${Boost_INCLUDE_DIRS}
        ${CMAKE_CURRENT_SOURCE_DIR}
        /usr/local/include
)
#target_compile_definitions(test_boost PUBLIC -DBOOST_ALL_NO_LIB )
#target_compile_definitions(test_boost PUBLIC -DBOOST_ALL_DYN_LINK)

I am getting the following linker errors at compilation:

====================[ Build | test_boost | Debug ]==============================
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /Users/cjh/Documents/code/cpp/test_boost/cmake-build-debug --target test_boost -- -j 12
[ 50%] Linking CXX executable test_boost
Undefined symbols for architecture x86_64:
  "__ZN5boost7archive23basic_binary_iprimitiveINS0_15binary_iarchiveEcSt11char_traitsIcEE4initEv", referenced from:
      __ZN5boost7archive20binary_iarchive_implINS0_15binary_iarchiveEcSt11char_traitsIcEE4initEj in main.cpp.o
  "__ZN5boost7archive23basic_binary_iprimitiveINS0_15binary_iarchiveEcSt11char_traitsIcEE4loadERNSt7__cxx1112basic_stringIcS4_SaIcEEE", referenced from:
      __ZN5boost7archive11load_access14load_primitiveINS0_15binary_iarchiveENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_RT0_ in main.cpp.o
  "__ZN5boost7archive23basic_binary_iprimitiveINS0_15binary_iarchiveEcSt11char_traitsIcEEC2ERSt15basic_streambufIcS4_Eb", referenced from:
      __ZN5boost7archive20binary_iarchive_implINS0_15binary_iarchiveEcSt11char_traitsIcEEC2ERSij in main.cpp.o
  "__ZN5boost7archive23basic_binary_iprimitiveINS0_15binary_iarchiveEcSt11char_traitsIcEED2Ev", referenced from:
      __ZN5boost7archive20binary_iarchive_implINS0_15binary_iarchiveEcSt11char_traitsIcEED2Ev in main.cpp.o
      __ZN5boost7archive20binary_iarchive_implINS0_15binary_iarchiveEcSt11char_traitsIcEED1Ev in main.cpp.o
      __ZN5boost7archive20binary_iarchive_implINS0_15binary_iarchiveEcSt11char_traitsIcEEC2ERSij in main.cpp.o
  "__ZN5boost7archive23basic_binary_oprimitiveINS0_15binary_oarchiveEcSt11char_traitsIcEE4initEv", referenced from:
      __ZN5boost7archive20binary_oarchive_implINS0_15binary_oarchiveEcSt11char_traitsIcEE4initEj in main.cpp.o
  "__ZN5boost7archive23basic_binary_oprimitiveINS0_15binary_oarchiveEcSt11char_traitsIcEE4saveERKNSt7__cxx1112basic_stringIcS4_SaIcEEE", referenced from:
      __ZN5boost7archive11save_access14save_primitiveINS0_15binary_oarchiveENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_RKT0_ in main.cpp.o
  "__ZN5boost7archive23basic_binary_oprimitiveINS0_15binary_oarchiveEcSt11char_traitsIcEEC2ERSt15basic_streambufIcS4_Eb", referenced from:
      __ZN5boost7archive20binary_oarchive_implINS0_15binary_oarchiveEcSt11char_traitsIcEEC2ERSoj in main.cpp.o
  "__ZN5boost7archive23basic_binary_oprimitiveINS0_15binary_oarchiveEcSt11char_traitsIcEED2Ev", referenced from:
      __ZN5boost7archive20binary_oarchive_implINS0_15binary_oarchiveEcSt11char_traitsIcEED2Ev in main.cpp.o
      __ZN5boost7archive20binary_oarchive_implINS0_15binary_oarchiveEcSt11char_traitsIcEED1Ev in main.cpp.o
      __ZN5boost7archive20binary_oarchive_implINS0_15binary_oarchiveEcSt11char_traitsIcEEC2ERSoj in main.cpp.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make[3]: *** [test_boost] Error 1
make[2]: *** [CMakeFiles/test_boost.dir/all] Error 2
make[1]: *** [CMakeFiles/test_boost.dir/rule] Error 2
make: *** [test_boost] Error 2

I am using Boost 1.76.0 installed via Homebrew on my MacBook Pro running macOS Big Sur 11.4. The compiler being used is GCC 11.1. I have also tried using information from the following other stack overflow questions to solve this problem, to no avail:

I am at a loss for how to proceed as I have tried quite a few ways to solve the issue, including removing an older version (1.75) of Boost and adding in a new one to see if something was wrong there. Some of the links above offer what I view as straight forward ways to link the boost libraries, something I would expect, but the fact this linking issue is occurring is just surprising. The only other option I can think to do is build Boost on my own system and see if that resolves the issues, but I want to avoid doing that if possible.

Update 1

After further attempts to work through the issue, what I have found is the following. First, the default Apple g++ that is really clang++ compiles, links, and runs fine with the Boost serialization pieces I have gotten via Homebrew. The GCC compiler I am using is not working, so perhaps this relates to another post I saw where maybe the Boost libraries were compiled with a different standard library implementation? I am going to do some more digging.

spektr
  • 777
  • 5
  • 14
  • First fix your code as in my answer to your Question 1 above. – Alex Reinking Aug 09 '21 at 20:17
  • Based on your update, if you want to use GCC instead of Clang (which was used to build Boost in the first place), you'll [need to tell GCC to use libc++](https://releases.llvm.org/8.0.0/projects/libcxx/docs/UsingLibcxx.html#using-libc-with-gcc) in your toolchain file... or just build Boost from scratch using GCC. That's probably easier. – Alex Reinking Aug 09 '21 at 20:22
  • @AlexReinking: I made the fix I believe you were referring to, namely writing out the components directly in the linking part of the CMakeLists.txt, though it still produces the same errors. To your second comment and in light of the new info, I do agree that either of the options you listed should get this working. I will probably just build Boost with GCC, too. – spektr Aug 09 '21 at 20:27
  • Did you try with: set(Boost_USE_STATIC_LIBS ON) – Francois Zard Aug 09 '21 at 23:40
  • @FrancoisZard: I actually did and it unfortunately did not resolve the issue! At this point it seems the solution is just to do one of the options that Alex Reinking mentioned. – spektr Aug 10 '21 at 00:21

0 Answers0