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.