1

私の(OSX)プロジェクトの一環として、ダイナミックライブラリとしてboost::regexを構築しています。-fvisibility- inlines -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

ブーストをプロジェクトにリンクしようとすると(ファイル「Regex.o」はブースト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
4

1 に答える 1

2

これはclang3.1のコンパイラのバグであることがわかりました。Boostは、テンプレートのインラインメンバー関数perl_matcher<...>::find()(およびその他)をexternal;として宣言します。ブーストdylibにリンクされているインスタンスのみが外部としてマークされません。インラインであるため、clang3.1はこのインスタンスをdylibのエクスポートテーブルから隠します-fvisibility-inlines-hidden

このバグはclang(3.2.x)の現在のトランクで修正されているようです。それまでは、定義BOOST_REGEX_NO_EXTERNAL_TEMPLATESによってこのバグが回避されます(バイナリにこれらのインライン関数の複数のインスタンスが含まれる可能性がある場合)。それ以外の場合は、boost :: regexにパッチを適用して、whenが定義されているときにboost/regex/v4/instances.hpp使用して定義されたシンボルを明示的にエクスポートすることもできます(上部のハックを参照)。__attribute__ ((visibility("default")))BOOST_REGEX_INSTANTIATE#define templateinstances.hpp

于 2012-06-04T17:34:02.983 に答える