【问题标题】:Clang boost oddities铿锵声增强怪事
【发布时间】:2012-07-08 09:17:47
【问题描述】:

我正在做一个宠物项目并且正在使用 clang++(特别是 MacPorts clang 3.1)。所以我决定切换到 libc++(使用 std::array 等),但我使用的是 boost(特别是 asio 和 regex),所以我不得不使用 libc++ 重新编译 boost。我删除了安装在 macports 中的 boost 并从源代码构建 boost,现在安装在 /usr/local/include 和 /usr/local/lib 中。从那以后,我无法编译。以下是我遇到的奇怪现象:

执行时:

clang++ -g  -std=c++11 -stdlib=libc++ -c main.cpp

我收到一个与移动构造函数有关的奇怪编译错误(此错误还有更多,但正如您所见,它来自 boost):

/usr/include/c++/v1/string:1952:10: error: overload resolution selected implicitly-deleted copy assignment operator
__r_ = _STD::move(__str.__r_);
     ^
/usr/include/c++/v1/string:1942:9: note: in instantiation of member function 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__move_assign' requested here
    __move_assign(__str, true_type());
    ^
/usr/include/c++/v1/string:1961:5: note: in instantiation of member function 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__move_assign' requested here
__move_assign(__str, integral_constant<bool,
^
/usr/local/include/boost/regex/v4/perl_matcher.hpp:207:16: note: in instantiation of member function 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator=' requested here
        s1 = traits_inst.transform(a, a + 1);

但是,当我执行时(请注意“-I”,它必须在那个确切的位置):

clang++ -I -std=c++11 -stdlib=libc++ -g -c main.cpp

这会编译(但稍后链接会失败)。为什么是这样? -I do without a path 是什么意思? -stdlib= 必须以 -I 开头吗?

现在是有趣的部分:

尽管现在一切都编译了,但它不会链接。执行时:

clang++ main.o FTPClient.o FTPConnection.o -lboost_system -lboost_regex -std=c++11 -stdlib=libc++  -g  -o cli

我收到消息:

Undefined symbols for architecture x86_64:
"__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initIPKcEENS_9enable_ifIXsr21__is_forward_iteratorIT_EE5valueEvE4typeESA_SA_", referenced from:
  boost::re_detail::cpp_regex_traits_implementation<char>::lookup_collatename(char const*, char const*) const in libboost_regex.a(instances.o)
  boost::re_detail::cpp_regex_traits_implementation<char>::lookup_classname_imp(char const*, char const*) const in libboost_regex.a(instances.o)
  boost::re_detail::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::fail(boost::regex_constants::error_type, long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long) in libboost_regex.a(instances.o)
  boost::re_detail::cpp_regex_traits_implementation<char>::lookup_classname(char const*, char const*) const in libboost_regex.a(instances.o)
  ld: symbol(s) not found for architecture x86_64

现在我想也许我缺少一些 -lboost 标志,但我不确定它是什么。这可能是什么原因?

非常感谢!

编辑:查看安装 boost 的日志时,我注意到了这一点:

..failed clang-darwin.link.dll /usr/local/lib/libboost_filesystem.dylib...
clang-darwin.link.dll /usr/local/lib/libboost_regex.dylib
Undefined symbols for architecture x86_64:
  "__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initIPKcEENS_9enable_ifIXsr21__is_forward_iteratorIT_EE5valueEvE4typeESA_SA_", referenced from:
  boost::c_regex_traits<char>::transform(char const*, char const*) in c_regex_traits.o
  boost::c_regex_traits<char>::lookup_classname(char const*, char const*) in c_regex_traits.o
  boost::c_regex_traits<char>::lookup_collatename(char const*, char const*) in c_regex_traits.o
  boost::re_detail::RegExData::update() in cregex.o
  boost::RegEx::What(int) const in cregex.o
  boost::re_detail::pred2::operator()(boost::match_results<char const*, std::__1::allocator<boost::sub_match<char const*> > > const&) in cregex.o
  boost::re_detail::cpp_regex_traits_implementation<char>::lookup_collatename(char const*, char const*) const in instances.o
  ...
  "__ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6__initIPKwEENS_9enable_ifIXsr21__is_forward_iteratorIT_EE5valueEvE4typeESA_SA_", referenced from:
  boost::c_regex_traits<wchar_t>::transform(wchar_t const*, wchar_t const*) in wc_regex_traits.o


  boost::c_regex_traits<wchar_t>::lookup_classname(wchar_t const*, wchar_t const*) in wc_regex_traits.o
  boost::re_detail::cpp_regex_traits_implementation<wchar_t>::lookup_collatename(wchar_t const*, wchar_t const*) const in winstances.o
  boost::re_detail::cpp_regex_traits_implementation<wchar_t>::lookup_classname_imp(wchar_t const*, wchar_t const*) const in winstances.o
  boost::re_detail::cpp_regex_traits_implementation<wchar_t>::lookup_classname(wchar_t const*, wchar_t const*) const in winstances.o
ld: symbol(s) not found for architecture x86_64  
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这是否意味着 boost 正则表达式可能与 -libc++ 不兼容?

编辑 2:我尝试使用 std::regex,但我明白了:

Undefined symbols for architecture x86_64:
   "__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initIPKcEENS_9enable_ifIXsr21__is_forward_iteratorIT_EE5valueEvE4typeESA_SA_", referenced from:
  std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::regex_traits<char>::__lookup_collatename<char const*>(char const*, char const*, char) const in main.o
  unsigned int std::__1::regex_traits<char>::__lookup_classname<char const*>(char const*, char const*, bool, char) const in main.o
 ld: symbol(s) not found for architecture x86_64

【问题讨论】:

  • 如果 Lion 然后 Xcode 包含 clang 3.1,那么您使用的是哪个 OSX,如果没有,那么 /usr/include/c++ 不是您想要的
  • Lion 有 clang 3.0,所以我使用的是 MacPorts。我应该在我的包含路径中放入什么以便它不使用 /usr/include/c++?注意:我使用了-I/opt/local/include,并且在编译时从 std::regex 得到了奇怪的移动构造函数错误。
  • 如果 Lion 那么你不需要 macports 来进行 clang - 使用 Xcode 一个 - 然后会发生什么
  • 我不知道 Xcode 有 3.1,但安装了最新的命令行工具,我的项目现在可以编译了! (我猜来自 MacPorts 的库是拙劣的)非常感谢!
  • 不,解决方法是你现在使用的是 Xcode 的 clang - 问题是你的命令行错过了正确的包含和库 - 但是使用 Xcode 更容易

标签: macos boost clang macports


【解决方案1】:

一个有用但不令人满意的答案:libc++ 包含 std::regex,您可以使用它来代替 boost::regex。

【讨论】:

  • 您是否使用 clang -stdlib=libc++ -std=c++11 构建了 boost ?
  • 是的,我做到了:./b2 toolset=clang cxxflags="-I -std=c++11 -stdlib=libc++" linkflags="-stdlib=libc++",无论有没有那个“-I”(因为在构建时看到了同样奇怪的移动构造函数错误)并使用了几次 -aa。
  • 我也确实使用了 std::regex,但随后出现链接错误(请参阅我编辑的帖子)。我的 libc++ 安装会搞砸吗? MacPorts clang 是否甚至附带 libc++ 二进制文件(它显然在 .cpp 文件编译时附带标题)?
  • 你可以在/usr/lib中查看;寻找 libc++.dylib。那是 libc++ 的二进制文件。
  • 注意:如果您使用的是 pcre(perl 兼容的正则表达式),那么您不能切换到 std::regex。
猜你喜欢
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多