-1

I am encountering problems while compiling a c++ program including boost library. The problems seem to have started occuring after I updated to Catalina, before everything worked correctly.

I use boost installed via homebrew ("brew install boost") and compile the program with g++ version 9 als installed with homebrew.

When compiling with "g++-9 -I/usr/local/include -L/usr/local/lib -lboost_serialization test.cc" the libararies are correctly found by the compiler but the following error occurs. Below I include the error message and the test program that causes it.

An interesting observation is that the name in the error message referenced as "cclgNgf3.o" changes each time I compile. So far I also got "ccmG1kWi.o" and "cc25AYXh.o".

Undefined symbols for architecture x86_64:
  "boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::save(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
      void boost::archive::save_access::save_primitive<boost::archive::text_oarchive, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(boost::archive::text_oarchive&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in cclgNgf3.o
  "boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::text_oarchive_impl(std::basic_ostream<char, std::char_traits<char> >&, unsigned int)", referenced from:
      boost::archive::text_oarchive::text_oarchive(std::basic_ostream<char, std::char_traits<char> >&, unsigned int) in cclgNgf3.o
  "boost::archive::basic_text_oprimitive<std::basic_ostream<char, std::char_traits<char> > >::~basic_text_oprimitive()", referenced from:
      boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::~text_oarchive_impl() in cclgNgf3.o
      boost::archive::text_oarchive_impl<boost::archive::text_oarchive>::~text_oarchive_impl() in cclgNgf3.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
#include <boost/archive/text_oarchive.hpp>
#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
    boost::archive::text_oarchive oa{cout};
    return 0;
}

On the off chance that it might be relevant when compiling with macOS clang compiler by invoking "g++ -lboost_serialization test.cc" a following error message is printed.

test.cc:8:32: error: no matching constructor for initialization of 'boost::archive::text_oarchive'
        boost::archive::text_oarchive oa{cout};
                                      ^
/usr/local/include/boost/archive/text_oarchive.hpp:98:28: note: candidate constructor (the implicit copy constructor) not viable: requires 1
      argument, but 0 were provided
class BOOST_SYMBOL_VISIBLE text_oarchive : 
                           ^
/usr/local/include/boost/archive/text_oarchive.hpp:102:5: note: candidate constructor not viable: requires at least argument 'os_', but no arguments
      were provided
    text_oarchive(std::ostream & os_, unsigned int flags = 0) :
    ^
test.cc:8:34: error: expected ';' at end of declaration
        boost::archive::text_oarchive oa{cout};
                                        ^
                                        ;
2 errors generated.
ramkick
  • 49
  • 4
  • 1
    Your `-I/usr/local/include` allows the compiler to find the headers of the library, allowing the code to compile, but as long as the library is not header-only there is also a compiled part of that library. And you need tell to which of those libraries to link `-lboost_` to. – t.niese Mar 13 '20 at 15:34
  • Does this answer your question? [Boost Serialization example Error: symbol(s) not found for architecture x86\_64](https://stackoverflow.com/questions/31920179/boost-serialization-example-error-symbols-not-found-for-architecture-x86-64) – t.niese Mar 13 '20 at 15:39
  • I have indeed forgotten to add the linking for the test program but for the real program with which I have this problem I do add the linking and the problem persists. I have eddited the error message when including the linking flag for the test program. – ramkick Mar 13 '20 at 15:44
  • One possible explanation to the remaining error message is, that two different std libs are involved. That your application is built against a different stdlib then boost is. – t.niese Mar 13 '20 at 15:56
  • Those `cclgNgf3.o`, `ccmG1kWi.o` are the temporary output files of the compiled application in the linking step. And as they are temporary names they change. – t.niese Mar 13 '20 at 15:57
  • Ok this sounds interesting any idea how I could confirm or fix it? – ramkick Mar 13 '20 at 15:57
  • How did you install boost? – t.niese Mar 13 '20 at 15:58
  • as mentioned in the problem description, using homebrew. Is it possible that boost uses clang libs and the program itself uses gcc std lib? – ramkick Mar 13 '20 at 15:58
  • So just `brew install boost` without any flags or env variables set? – t.niese Mar 13 '20 at 15:59
  • yes, exactly that – ramkick Mar 13 '20 at 16:00
  • Yes that my assumption. I guess `gcc-9` is also installed using brew. Maybe the brew installation of gcc defaults to the stdlib that is not the default one use on macOS and ABI incompatible (especially `std::string` is prone to be ABI incompatible between different stds libs, that's what my assumption is based on given the shown error message). I currently don't have a macOS machine around so I can't tell what exactly is the case. But what you could do is try to set a different stdlib with your `g++-9` invocation. – t.niese Mar 13 '20 at 16:05
  • Based on [Linker errors when using boost serialization](https://stackoverflow.com/questions/8728742) my assumption seems to be true, but if I interpret is correctly is the other way around in that wquestion. The reason for it being the other way round is that the question is a few years old and iirc macOS switch the stdlib between that date and now. So try to use the std of clang with gcc. – t.niese Mar 13 '20 at 16:15
  • How exactly would that look? Using "-stdlib=libc++" flag with g++ is not possible - it is exclusive to clang. – ramkick Mar 13 '20 at 16:18

1 Answers1

1

I built boost manually using gcc instead of clang and now it works. It would appear the brew version is built with clang and so then when I try to build my project using gcc we get the conflicts of standard libraries.

ramkick
  • 49
  • 4
  • Hi @ramkick, thanks for following up on your own question. Could you provide more detail on building boost manually? Thanks. – fabern Aug 11 '20 at 14:50
  • I followed the instructions at https://github.com/liballeg/allegro5 I think – ramkick Aug 12 '20 at 21:05
  • Thanks for the quick reply! However, it doesn't seem that allegro5 depends on boost. I couldn't find any instructions relating to it. Might it have been another project? – fabern Aug 13 '20 at 09:20
  • indeed, I was refering to a different project. I do not remember the build process exactly, but I think I followed the official docs https://www.boost.org/doc/libs/1_64_0/doc/html/bbv2.html. – ramkick Aug 14 '20 at 11:07