うまくいかんシリーズ。
boostのregexで、リンクがうまくいかんようなのだ。
使っているboostは、1.47.0。
コンパイラは「gcc バージョン 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3) 」だ。
#include <boost/regex.hpp>int main()
{boost::regex r("");return 0;
}
$ g++ -o tst -I/usr/local/boost/include -L/usr/local/boost/lib -lboost_regex regex.cpp
/tmp/ccaCv8B6.o: In function `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)':
regex.cpp:(.text._ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j[boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)]+0x2a): undefined reference to `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)'
collect2: ld はステータス 1 で終了しました
boost_regexがうまくいってないのかと思ってboost_regeとかにしてみると、ちゃんと「ライブラリがない」エラーが出た。
ってことは、libboost_regexがあることはわかってるんだ。
なのに・・・なぜ・・・。
これがリンクできない、といっているのはわかった。
_ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j
では、ビルドしたファイルのあるboost_1_47_0/bin.v2/libs/regex/build/gcc-4.6.1/release/threading-multiを見てみよう。
$ nm *.o | grep _ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j
確かに、ない。
では、何ならあるんだ?
$ nm *.o | grep _ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traits
U _ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE9do_assignEPKcS7_j
W _ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE5imbueESt6locale
うーん・・・。
ちなみに今は、こんな環境だ。
Linux kurokiri 3.0.0-12-generic #20-Ubuntu SMP Fri Oct 7 14:56:25 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
これを対策できれば、いいんだと思う。
`boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)'
boost::regexは、こういう定義だ。
typedef basic_regex<char> regex;
なので、このエラーはboost::regexのことであることは間違いがない。
では、basic_regexクラスのdo_assign()を見てみよう。
class basic_regex : public regbase{(略)private:
basic_regex& do_assign(const charT* p1,
const charT* p2,
flag_type f);(略)
宣言はある。
では、実装はどこにあるのだろう。
その下にある、これしかなさそうだ。
template <class charT, class traits>basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
const charT* p2,
flag_type f){shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;if(!m_pimpl.get())
{temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
}else
{temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
}temp->assign(p1, p2, f);temp.swap(m_pimpl);return *this;}
ヘッダにdo_assign()定義があるということは、ライブラリうんぬんは関係ないことになる。
なんかおかしい・・・。
とりあえず、プリプロセスを展開させよう。
__extension__ extern template basic_regex<char , boost::regex_traits<char > >&basic_regex<char , boost::regex_traits<char > >::do_assign(const char* p1,const char* p2,flag_type f);
定義がないのは、これ。
boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >
::do_assign(char const*, char const*, unsigned int)
もしcpp_regex_traits<T>がbasic_regexをtypedefしたものだったらいいんだけど、別のclassだ。
確かに、定義はないな。
しかし、変だ。
だって、basic_regex<charT, traits>::do_assign()って書いているのだから、traitsがcpp_regex_traitsから置き換わる、なんてのは考えにくい。
nmでbasic_regexのコンストラクタを見ると、
boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::basic_regex(char const*, unsigned int)
と、cpp_regex_traitsのバージョンしかなさそうだ・・・ん?
似たようなのがあったぞ。
boost::shared_ptr<boost::re_detail::basic_regex_implementation<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > >::shared_ptr()
すまん、もう訳がわからん・・・。
あ、でもこのshared_ptrは、do_assign()の実装で使われているものではなかろうか。
shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;
do_assign()の定義は
template <class charT, class traits>
basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign()
なので、traitsとしてはbasic_regexと同じものが使われるべきで、regex_traitsが急に出てくるのはおかしいような。
でも、そもそもの話が、
typedef basic_regex<char, regex_traits<char> > regex;
なので、regexの定義としてはおかしくないのか。
でも、nmで見ると、regex_traitsは出てこず、cpp_regex_traitsしかないんだよなぁ。
まあ、今日はこの辺にしておこう。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。