我正在尝试在 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/