How to link boost library 1.54 using clang?

2019-08-04 11:32发布

问题:

I have installed boost in my mac using clang.

Include =  /usr/local/include/boost-1_54/  
Lib    = /usr/local/lib/ 

( libboost_atomic-clang-darwin42-mt-1_54.a, libboost_math_c99f-clang-darwin42-mt-1_54.dylib)

and then I wanted to test if the installation is gone right or not. I try to compile a simple code which use boost::regex.

$$ clang++ -I /usr/local/include/boost-1_54/ -L /usr/local/lib/ -o regex test_regex.cpp

It gives error saying

 Undefined symbols for architecture x86_64:
 "boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)", referenced from:
  boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> >           >::assign(char const*, char const*, unsigned int) in test_regex-qSWMLF.o
 "boost::re_detail::get_mem_block()", referenced from:
  boost::re_detail::perl_matcher<std::__1::__wrap_iter<char const*>, std::__1::allocator<boost::sub_match<std::__1::__wrap_iter<char const*> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::extend_stack() in test_regex-qSWMLF.o
  boost::re_detail::save_state_init::save_state_init(boost::re_detail::saved_state**, boost::re_detail::saved_state**) in test_regex-qSWMLF.o
 "boost::re_detail::put_mem_block(void*)", referenced from:
  boost::re_detail::save_state_init::~save_state_init() in test_regex-qSWMLF.o
  boost::re_detail::perl_matcher<std::__1::__wrap_iter<char const*>, std::__1::allocator<boost::sub_match<std::__1::__wrap_iter<char const*> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::unwind_extra_block(bool) in test_regex-qSWMLF.o
 "boost::re_detail::verify_options(unsigned int, boost::regex_constants::_match_flags)", referenced from:
  boost::re_detail::perl_matcher<std::__1::__wrap_iter<char const*>, std::__1::allocator<boost::sub_match<std::__1::__wrap_iter<char const*> > >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_imp() in test_regex-qSWMLF.o
 "boost::re_detail::raise_runtime_error(std::runtime_error const&)", referenced from:
  void boost::re_detail::raise_error<boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > >(boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::error_type) in test_regex-qSWMLF.o
 "boost::re_detail::get_default_error_string(boost::regex_constants::error_type)", referenced from:
  boost::re_detail::cpp_regex_traits_implementation<char>::error_string(boost::regex_constants::error_type) const in test_regex-qSWMLF.o
 "boost::re_detail::cpp_regex_traits_implementation<char>::transform_primary(char const*, char const*) const", referenced from:
  boost::cpp_regex_traits<char>::transform_primary(char const*, char const*) const in test_regex-qSWMLF.o
"boost::re_detail::cpp_regex_traits_implementation<char>::transform(char const*, char const*) const", referenced from:
  boost::cpp_regex_traits<char>::transform(char const*, char const*) const in test_regex-qSWMLF.o
 ld: symbol(s) not found for architecture x86_64
 clang: error: linker command failed with exit code 1 (use -v to see invocation)

I remember using -libregex or something while using gcc to compile simple boost program. I have tried all combination but it still gives error saying ( by that I mean -libboost_regex-mt, libboost_atomic-clang-darwin42-mt-1_54.a , ..)

 $$ clang++ -I /usr/local/include/boost-1_54/ -L /usr/local/lib/ -o regex test_regex.cpp -libboost_regex

   ld: library not found for -libregex

Can anyone help how can I tell clang to use the proper library function to compile the test correctly?Please

回答1:

Now I as a beginner osx programmer also had this problem, and the cryptic 1 line below the answer did not help me.

After several frustrating hours and installing and recompiling boost I finally found out how to do this.

I installed boost libraries using a very helpful program called MacPorts, which can be found at : http://www.macports.org/

Then the command to get and install boost is : sudo port install boost

The boost libraries then appear in the folder /opt/local/lib

To link add the following to your librarys in the ld linker : -lboost_regex-mt

note that the actual filename is libboost_regex-mt.a , the "lib" at the start is omitted on the linker command line, something that threw me until I read the manual page.

If you do this then boost should link and the undefined symbols error should disappear.

I hope this helps.



回答2:

The problem probably has to to with the c++ standard library being used. Some time ago, Apple switched from, by default, using libstdc++ (the GNU version) to libc++ (the Clang version). There are basically two ways to solve this:

1) make sure the boost libraries you're using are using libc++ too;

2) override this default, and use libstdc++ instead.

Since Apple decided to switch to CLang,1) is probably the most practical in the long run to go with the flow. You can do that by building the boost libraries using command like:

$ ./bootstrap  --prefix=... 
$ ./b2  toolset=clang  cxxflags="-stdlib=libc++"  linkflags="-stdlib=libc++"   link=static install

I don't know your bootstrap options of course, and your options to b2 may vary, for example, you may for example want to leave out the 'link=static' and you may provide other compiler or linker flags, but this should give you the general idea.

If you want to go for option 2) and are using XCode, you can go to the 'Build settings' of your project, and under 'C++ Standard Library', select libstdc++ instead of libc++. Or do the equivalent from the command line if you're not using XCode.