OS X 10.7上的MacPorts的Boost.Log链接器错误

时间:2014-08-20 17:24:52

标签: c++ macos boost macports

我正在尝试在OS X 10.7上构建我的C ++库,但由于链接器错误而导致以下消息失败。

/usr/bin/c++   -std=c++11 -stdlib=libc++ -Wall -O2 -dynamiclib -Wl,-headerpad_max_install_names   -o libCHEC.dylib -install_name /Users/oxon/libCHEC_build/libCHEC.dylib CMakeFiles/CHEC.dir/src/BasePacket.cc.o CMakeFiles/CHEC.dir/src/Buffer.cc.o CMakeFiles/CHEC.dir/src/CommandPacket.cc.o CMakeFiles/CHEC.dir/src/DataPacket.cc.o CMakeFiles/CHEC.dir/src/Event.cc.o CMakeFiles/CHEC.dir/src/Logger.cc.o CMakeFiles/CHEC.dir/src/ResponsePacket.cc.o  -L/opt/local/lib -lcfitsio /opt/local/lib/libboost_log-mt.dylib /opt/local/lib/libboost_thread-mt.dylib /opt/local/lib/libboost_system-mt.dylib /opt/local/lib/libboost_unit_test_framework-mt.dylib -Wl,-rpath,/opt/local/lib 
Undefined symbols for architecture x86_64:
  "void boost::log::v2_mt_posix::aux::put_integer<char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int, unsigned int, char)", referenced from:
      boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::format_fractional_seconds(boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::context&) in Logger.cc.o
      boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::format_seconds(boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::context&) in Logger.cc.o
      boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::format_minutes(boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::context&) in Logger.cc.o
  void boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::format_hours_12<(char)48>(boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::context&) in Logger.cc.o
  void boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::format_hours_12<(char)32>(boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::context&) in Logger.cc.o
  void boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::format_hours<(char)48>(boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::context&) in Logger.cc.o
  void boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::format_hours<(char)32>(boost::log::v2_mt_posix::aux::date_time_formatter<boost::log::v2_mt_posix::aux::decomposed_time_wrapper<boost::posix_time::ptime>, char>::context&) in Logger.cc.o
  ...
  "boost::log::v2_mt_posix::aux::code_convert(wchar_t const*, unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::locale const&)", referenced from:
  boost::log::v2_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> >& boost::log::v2_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> >::formatted_write<wchar_t>(wchar_t const*, long) in Logger.cc.o
  void boost::log::v2_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> >::aligned_write<wchar_t>(wchar_t const*, long) in Logger.cc.o
  "boost::log::v2_mt_posix::sinks::basic_text_ostream_backend<char>::add_stream(boost::shared_ptr<std::__1::basic_ostream<char, std::__1::char_traits<char> > > const&)", referenced from:
  CTA::SST::CHEC::Logger::Logger(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in Logger.cc.o
  "boost::log::v2_mt_posix::sinks::basic_text_ostream_backend<char>::consume(boost::log::v2_mt_posix::record_view const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
  void boost::log::v2_mt_posix::sinks::basic_formatting_sink_frontend<char>::feed_record<boost::log::v2_mt_posix::aux::fake_mutex, boost::log::v2_mt_posix::sinks::basic_text_ostream_backend<char> >(boost::log::v2_mt_posix::record_view const&, boost::log::v2_mt_posix::aux::fake_mutex&, boost::log::v2_mt_posix::sinks::basic_text_ostream_backend<char>&) in Logger.cc.o
      void boost::log::v2_mt_posix::sinks::basic_formatting_sink_frontend<char>::feed_record<boost::recursive_mutex, boost::log::v2_mt_posix::sinks::basic_text_ostream_backend<char> >(boost::log::v2_mt_posix::record_view const&, boost::recursive_mutex&, boost::log::v2_mt_posix::sinks::basic_text_ostream_backend<char>&) in Logger.cc.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libCHEC.dylib] Error 1
make[1]: *** [CMakeFiles/CHEC.dir/all] Error 2
make: *** [all] Error 2

如您所见,我使用CMake,C ++ 11,Clang和Boost.Log构建此库。我在使用非常相似的软件设置的OS X 10.9上没有出现此错误。

在我的CMakeLists.txt中,我添加了“BOOST_ALL_DYN_LINK”的定义,因此我认为这不是由此处解释的Boost.Log命名空间问题引起的http://www.boost.org/doc/libs/1_54_0_beta1/libs/log/doc/html/log/rationale/namespace_mangling.html

find_package(Boost 1.5.5 COMPONENTS log thread system unit_test_framework REQUIRED)
ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK)

我在OS X 10.7和10.9上使用的软件版本

10.7

  • CMake 2.8.12(MacPorts)
  • boost @ 1.56.0_1 + no_single + no_static + python27(MacPorts)
  • Clang 4.2(Xcode 4.6.3)

10.9

  • CMake 2.8.12(MacPorts)
  • boost @ 1.56.0_1 + no_single + no_static + python27(MacPorts)
  • Clang 5.1(Xcode 5.1.1)

我发现OS X 10.7和10.9上的/opt/local/lib/libboost_log-mt.dylib中的符号名称是不同的。这似乎是我问题的根本原因。

10.7

$ nm -a /opt/local/lib/libboost_log-mt.dylib | grep put_integer
000000000004c1a0 T __ZN5boost3log11v2_mt_posix3aux11put_integerIcEEvRSbIT_St11char_traitsIS4_ESaIS4_EEjjS4_
000000000004c1a0 - 01 0000   FUN __ZN5boost3log11v2_mt_posix3aux11put_integerIcEEvRSbIT_St11char_traitsIS4_ESaIS4_EEjjS4_
000000000004c900 - 01 0000   FUN __ZN5boost3log11v2_mt_posix3aux11put_integerIwEEvRSbIT_St11char_traitsIS4_ESaIS4_EEjjS4_
000000000004c900 T __ZN5boost3log11v2_mt_posix3aux11put_integerIwEEvRSbIT_St11char_traitsIS4_ESaIS4_EEjjS4_

10.9

$ nm -a /opt/local/lib/libboost_log-mt.dylib | grep put_integer
0000000000048a00 - 01 0000   FUN __ZN5boost3log11v2_mt_posix3aux11put_integerIcEEvRNSt3__112basic_stringIT_NS4_11char_traitsIS6_EENS4_9allocatorIS6_EEEEjjS6_
0000000000048a00 T __ZN5boost3log11v2_mt_posix3aux11put_integerIcEEvRNSt3__112basic_stringIT_NS4_11char_traitsIS6_EENS4_9allocatorIS6_EEEEjjS6_
0000000000049000 - 01 0000   FUN __ZN5boost3log11v2_mt_posix3aux11put_integerIwEEvRNSt3__112basic_stringIT_NS4_11char_traitsIS6_EENS4_9allocatorIS6_EEEEjjS6_
0000000000049000 T __ZN5boost3log11v2_mt_posix3aux11put_integerIwEEvRNSt3__112basic_stringIT_NS4_11char_traitsIS6_EENS4_9allocatorIS6_EEEEjjS6_

有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:3)

较新版本的xcode默认使用-stdlib=libc++来编译所有内容,这意味着使用这些标志编译10.9上的boost,这意味着一切都很愉快。

我们可以通过c++filt提供一个符号来验证这一点,10.9显示$ c++filt __ZN5boost3log11v2_mt_posix3aux11put_integerIcEEvRNSt3__112basic_stringIT_NS4_11char_traitsIS6_EENS4_9allocatorIS6_EEEEjjS6_ void boost::log::v2_mt_posix::aux::put_integer<char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int, unsigned int, char) 已编译的提升:

std::__1::basic_string

10.7的存在是那里的诅咒证据。

但是,libstdc++上的你的增强版本是使用$ c++filt __ZN5boost3log11v2_mt_posix3aux11put_integerIcEEvRSbIT_St11char_traitsIS4_ESaIS4_EEjjS4_ void boost::log::v2_mt_posix::aux::put_integer<char>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned int, unsigned int, char) 编译的,在这种情况下可以通过名称修改来证明:

std::basic_string

更简单的-std=libc++的存在告诉我们情况就是这样。

这意味着当由MacPorts构建boost时,它是根据其他标准构建的。

一些解决方案是: 1.编辑用于boost的portfile以使用-std=libstdc++重新编译它,以便它现在可以与其他代码链接 2.在10.7中编译而不是使用-std=libc++时,使用-std=libc++更改自己的代码以进行构建 3.编译boost的私有副本,以便与使用10.7上的libc++构建的代码一起使用。

所有这些都有优点和缺点。如果你用libc++重建macports boost,那么任何使用它的东西也必须用libc++编译,这可能是一个无尽的地狱圈。

更改自己的代码可能是最简单的,这意味着不需要使用boost版本和干扰端口文件,但如果你依赖于b2提供的设施,那你就有点不走运了

构建boost的私有副本只意味着您遵循构建说明,当使用cxxflags=-stdlib=libc++编译它时,您添加:c++,这会导致它使用{{1}构建然后你链接到从那个而不是MacPorts的副本构建的副本。

我的订单或偏好是私人提升,用升级Portfile改变我的旗帜,futz。

答案 1 :(得分:0)

我使用以下选项构建了Boost 1.56,强制使用“-stdlib = libc ++”构建它。

$ sudo ./b2 -j 4 --prefix=/usr/local link=shared threading=multi toolset=clang install -a cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++"

现在没有出现链接问题。

相关问题