使用 Boost、GMP 和 OpenMP 在 Mac OS X 中编译的未定义符号

Undefined symbols compiling in Mac OS X with Boost, GMP, and OpenMP

我在按照 these instructions 编译名为 SDPB 的程序时遇到问题。总而言之,我正在 Mac OS X Yosemite 上安装需要 Boost、GMP 和 OpenMP 的程序。所有单独的代码片段都可以编译,但是当它到达 link 时,我得到 Undefined symbols for architecture x86_64。 我的问题与 this question 基本相同。但是,我无法在那里找到适合我的答案。我仍然遇到同样的错误。

经过多方搜索,我看到有类似问题的人得到的答案都指向 clang 和 gcc 之间的冲突。更具体地说,混合库 libstdc++ 和 libc++ 存在问题。

因此,我确保使用 gcc 重新编译 Boost 和 GMP,以便使用 libstdc++ 构建所有内容。那没有帮助。然后我下载了一个与 OpenMP 兼容的 clang 实现,并尝试仅使用 libc++ 构建所有内容。那也没有用。然后我尝试了各种使用 clang 和 -stdlib=libstdc++ 标志的排列等等。似乎没有任何效果。错误的细节似乎随着各种排列而有所改变。我将 post 下面的一些片段。当然,我总是使用更新后的 makefile 来编译 SDPB,并且我总是使用 --enable-cxx 标志配置 GMP,正如上面 linked 所说的那样。

这里是我在用 gcc 编译 GMP 和 Boost 之后用 gcc 编译 SDPB 时收到的错误片段。

Undefined symbols for architecture x86_64:
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::find(char const*, unsigned long, unsigned long) const", referenced from:
      boost::date_time::time_facet<boost::posix_time::ptime, char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, boost::posix_time::time_duration const&) const in SDPSolverIO.o
      boost::date_time::time_facet<boost::posix_time::ptime, char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, boost::posix_time::ptime const&) const in main.o
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const", referenced from:
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::_M_get_insert_unique_pos(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in SDPSolverIO.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in SDPSolverIO.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::_M_insert_unique_(std::_Rb_tree_const_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> const&) in SDPSolverIO.o
      std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::timer::cpu_timer, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::operator[](std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in SDPSolverIO.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::program_options::variable_value>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::program_options::variable_value> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::program_options::variable_value> > >::find(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const in main.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_get_insert_unique_pos(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in main.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in main.o
      ... 

在这里,我使用带有 -stdlib=libstdc++ 标志的 clang 编译了 GMP 和 Boost,并使用 gcc 编译了 SDPB。

Undefined symbols for architecture x86_64:
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::find(char const*, unsigned long, unsigned long) const", referenced from:
      boost::date_time::time_facet<boost::posix_time::ptime, char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, boost::posix_time::time_duration const&) const in SDPSolverIO.o
      boost::date_time::time_facet<boost::posix_time::ptime, char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, boost::posix_time::ptime const&) const in main.o
  "std::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const", referenced from:
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::_M_get_insert_unique_pos(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in SDPSolverIO.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in SDPSolverIO.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::_M_insert_unique_(std::_Rb_tree_const_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> const&) in SDPSolverIO.o
      std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::timer::cpu_timer, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::timer::cpu_timer> > >::operator[](std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in SDPSolverIO.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::program_options::variable_value>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::program_options::variable_value> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, boost::program_options::variable_value> > >::find(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const in main.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_get_insert_unique_pos(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in main.o
      std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in main.o
      ...

在这里,我使用带有 -stdlib=libstdc++ 标志的 clang 编译了 Boost、GMP 和 SDPB。

Undefined symbols for architecture x86_64:
  "std::string::find(char const*, unsigned long, unsigned long) const", referenced from:
      boost::date_time::time_facet<boost::posix_time::ptime, char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, boost::posix_time::time_duration const&) const in SDPSolverIO.o
      boost::date_time::time_facet<boost::posix_time::ptime, char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, boost::posix_time::ptime const&) const in main.o
  "std::logic_error::what() const", referenced from:
      vtable for boost::gregorian::bad_day_of_year in main.o
      vtable for boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::gregorian::bad_day_of_year> > in main.o
      vtable for boost::exception_detail::error_info_injector<boost::gregorian::bad_day_of_year> in main.o
      vtable for std::out_of_range in main.o
      vtable for boost::gregorian::bad_day_of_month in main.o
      vtable for boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::gregorian::bad_day_of_month> > in main.o
      vtable for boost::exception_detail::error_info_injector<boost::gregorian::bad_day_of_month> in main.o
      ...

在这里,我使用 clang 编译了所有内容,但只编译了带有 -stdlib=libstdc++ 标志的 SDPB。

Undefined symbols for architecture x86_64:
  "bootstrapSDP(std::vector<__gmp_expr<__mpf_struct [1], __mpf_struct [1]>, std::allocator<__gmp_expr<__mpf_struct [1], __mpf_struct [1]> > > const&, std::vector<PolynomialVectorMatrix, std::allocator<PolynomialVectorMatrix> > const&)", referenced from:
      parseBootstrapSDP(tinyxml2::XMLElement*) in parse.o
  "RpotrfStabilized(char const*, int, __gmp_expr<__mpf_struct [1], __mpf_struct [1]>*, int, int*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<__gmp_expr<__mpf_struct [1], __mpf_struct [1]>, std::__1::allocator<__gmp_expr<__mpf_struct [1], __mpf_struct [1]> > >&, double)", referenced from:
      choleskyDecompositionStabilized(Matrix&, Matrix&, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<__gmp_expr<__mpf_struct [1], __mpf_struct [1]>, std::__1::allocator<__gmp_expr<__mpf_struct [1], __mpf_struct [1]> > >&, double) in Matrix.o
  "boost::program_options::to_internal(std::string const&)", referenced from:
      std::vector<std::string, std::allocator<std::string> > boost::program_options::to_internal<std::string>(std::vector<std::string, std::allocator<std::string> > const&) in main.o
  "boost::program_options::basic_parsed_options<char> boost::program_options::parse_config_file<char>(std::basic_istream<char, std::char_traits<char> >&, boost::program_options::options_description const&, bool)", referenced from:
      _main in main.o
  "boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)", referenced from:
      _main in main.o

每当我尝试使用带有 OpenMP 支持的修改后的 clang 版本在没有 -stdlib=libstdc++ 的情况下编译 SDPB 时,我将 运行 保留为许多

error: 'value_type' is a private member of '__gmp_expr<mpf_t, mpf_t>'
    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr::value_type>,
                                                          ^
src/serialize.h:48:10: note: while substituting deduced template arguments into function template 'operator<<' [with _Expr = __gmp_expr<mpf_t, mpf_t>]
      os << f;

如果有人能提供帮助,我们将不胜感激。

Mac OS X Installation 说明已更新,如果我只是盲目地严格按照说明操作,现在一切正常。