1

As part of my (OSX) project, I am building boost::regex as a dynamic library. When I build and link without -fvisibility-inlines-hidden, everything works as expected.

To work around a bug in another external dependency, I need to turn this compiler switch on, however. Doing so results in lots of linker errors like this one

Undefined symbols for architecture x86_64:
  "boost::re_detail::perl_matcher<__gnu_cxx::__normal_iterator<char const*, 
  std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<
  char const*, std::string> > >, boost::regex_traits<char, 
  boost::cpp_regex_traits<char> > >::find()", referenced from:
      bool boost::regex_search<__gnu_cxx::__normal_iterator<char const*, 
  std::string>, std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<
  char const*, std::string> > >, char, boost::regex_traits<char, 
  boost::cpp_regex_traits<char> > >(__gnu_cxx::__normal_iterator<char const*, 
  std::string>, __gnu_cxx::__normal_iterator<char const*, std::string>, 
  boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::string>, 
  std::allocator<boost::sub_match<__gnu_cxx::__normal_iterator<char const*, 
  std::string> > > >&, boost::basic_regex<char, boost::regex_traits<char, 
  boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags,
  __gnu_cxx::__normal_iterator<char const*, std::string>) in Regex.o

when I try to link boost to my project (the file "Regex.o" is part of the boost dylib). As I understand Apple's documentation, limiting inline visibility should just cause every dynamic lib to get its own instance of the inlined function, but should never cause linker errors.

It seems there is a related compiler bug for virtual methods, but neither perl_matcher::find() nor regex_search() are virtual methods.

Any suggestions/ideas?

$ clang --version
Apple clang version 3.1 (tags/Apple/clang-318.0.58) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix
4

1 回答 1

2

事实证明,这是 clang 3.1 中的编译器错误。Boost 将模板内联成员函数perl_matcher<...>::find()(和其他)声明为external; 只有链接到 boost dylib 的实例未被标记为外部。因为它是内联的,所以 clang 3.1 将这个实例从 dylib 的导出表中隐藏了-fvisibility-inlines-hidden.

似乎这个 bug 已在当前的 clang (3.2.x) 主干中修复。在那之前,围绕这个错误定义BOOST_REGEX_NO_EXTERNAL_TEMPLATES工作(如果在你的二进制文件中可能有这些内联函数的多个实例是可以接受的)。boost/regex/v4/instances.hpp否则,修补 boost::regex 以显式导出using __attribute__ ((visibility("default")))when is defined中定义的符号BOOST_REGEX_INSTANTIATE也应该可以完成这项工作(参见#define template顶部的 hack instances.hpp)。

于 2012-06-04T17:34:02.983 回答