如何动态构建和链接带有隐藏内联的 boost::regex

How to dynamically build and link boost::regex with hidden inlines?

本文关键字:隐藏 regex boost 链接 何动态 动态 构建      更新时间:2023-10-16

作为我(OSX)项目的一部分,我正在构建boost::regex作为一个动态库。当我在没有隐藏 -fvisibility-inline-hidden 的情况下构建和链接时,一切都按预期工作。

但是,要解决另一个外部依赖项中的错误,我需要打开此编译器开关。这样做会导致许多链接器错误,如下所示

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

当我尝试将 boost 链接到我的项目时(文件"Regex.o"是 boost dylib 的一部分)。据我了解 Apple 的文档,限制内联可见性应该只会导致每个动态库获得自己的内联函数实例,但绝不会导致链接器错误。

虚拟方法似乎存在相关的编译器错误,但perl_matcher::find()regex_search()都不是虚拟方法。

有什么建议/想法吗?

$ 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

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

似乎这个错误在当前的 clang (3.2.x) 主干中得到了修复。在此之前,定义BOOST_REGEX_NO_EXTERNAL_TEMPLATES可以解决此错误(如果二进制文件中可能有多个这些内联函数的实例是可以接受的)。否则,修补 boost::regex 以在定义BOOST_REGEX_INSTANTIATE时使用__attribute__ ((visibility("default")))显式导出boost/regex/v4/instances.hpp中定义的符号也应该完成这项工作(请参阅instances.hpp顶部的#define template黑客)。