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

标签 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_

谁能帮我解决这个问题,好吗?

最佳答案

较新版本的 xcode 默认对编译的所有内容使用 -stdlib=libc++,这意味着 10.9 上的 boost 会使用这些标志进行编译,这意味着一切都可以愉快地链接。

我们可以通过 c++filt 提供其中一个符号来验证这一点,它显示了 10.9 编译的 boost:

$ 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 上的 boost 版本是使用 libstdc++ 编译的,在这种情况下,名称 mangling 证明了这一点:

$ 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 的存在告诉我们情况就是这样。

这意味着当 MacPorts 构建 boost 时,它是针对其他标准构建的。

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

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

更改您自己的代码可能是最简单的,这意味着无需费力地构建 boost 并干扰端口文件,但是如果您依赖于 libc++ 提供的功能,您就有点不适应了运气。

构建 boost 的私有(private)拷贝仅意味着您遵循构建说明,并在使用 b2 编译它时添加:cxxflags=-stdlib=libc++,这会导致它使用该 c++ 库构建,然后您链接到从该库构建的拷贝而不是从 MacPorts 构建的拷贝。

我的订单或偏好是私有(private) boost ,更改我的标志,使用 boost Portfile。

关于c++ - OS X 10.7 上 MacPorts 的 Boost.Log 链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25410886/

相关文章:

c++ - 使用boost的scoped_allocator_adaptor作为共享内存容器

c++ - Boost::bind 与对象占位符

c++ - Boost记录器静态链接: Not Working

c++ - 函数模板重载 - 排序

c++ - 如何使用迭代器计算列表的值?

ios - 如何在 Xcode 构建成功或错误时播放声音?

xcode - 为什么 OSX Snow Leopard 附带 GCC 4.2.1,是否可以(建议?)升级?

c++ - 编译器评估常量表达式

c++ - 如何让QT Application写入崩溃日志

macos - Mac 应用程序名称