Cygwinでbayonをコンパイルした時のメモ
環境
$ uname -srv CYGWIN_NT-5.1 1.7.9(0.237/5/3) 2011-03-29 10:10 $ g++ -v (略) gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) $ pwd /cygdrive/c/home/src/bayon-0.1.0
作業ログ(失敗とその対処)
# google-sparsehash 1.10はインストール済み $ ./configure --prefix=/usr/local (略) $ make g++ -c -I. -I/usr/local/include/bayon -I/cygdrive/c/home/include -I/usr/local/include -D_GNU_S OURCE=1 -DHAVE_CONFIG_H -Wall -fPIC -O3 bayon.cc bayon.cc:1: warning: -fPIC ignored for target (all code is position independent) /usr/local/include/google/sparsehash/hashtable-common.h: In member function `SizeType sh_hashtable_settings<Key, HashFunc, SizeType, HT_MIN_BUCKETS>::hash(const Key&) const [with Key = std::string, HashFunc = __gnu_cxx::hash<std::string>, SizeType = size_t, int HT_MIN_BUCKETS = 4]': /usr/local/include/google/sparsehash/densehashtable.h:1213: instantiated from `typename Alloc::rebind<Value>::other::size_type google::dense_hashtable<Value, Key, HashFcn, ExtractKey, SetKey, EqualKey, Alloc>::hash(const Key&) const [with Value = std::pair<const std::string, double>, Key = std::string, HashFcn = __gnu_cxx::hash<std::string>, ExtractKey = google::dense_hash_map<std::string, double, __gnu_cxx::hash<std::string>, std::equal_to<std::string>, google::libc_allocator_with_realloc<std::pair<const std::string, double> > >::SelectKey, SetKey = google::dense_hash_map<std::string, double, __gnu_cxx::hash<std::string>, std::equal_to<std::string>, google::libc_allocator_with_realloc<std::pair<const std::string, double> > >::SetKey, EqualKey = std::equal_to<std::string>, Alloc = google::libc_allocator_with_realloc<std::pair<const std::string, double> >]' /usr/local/include/google/sparsehash/densehashtable.h:812: instantiated from `std::pair<typename Alloc::rebind<Value>::other::size_type, typename Alloc::rebind<Value>::other::size_type> google::dense_hashtable<Value, Key, HashFcn, ExtractKey, SetKey, EqualKey, Alloc>::find_position(const Key&) const [with Value = std::pair<const std::string, double>, Key = std::string, HashFcn = __gnu_cxx::hash<std::string>, ExtractKey = google::dense_hash_map<std::string, double, __gnu_cxx::hash<std::string>, std::equal_to<std::string>, google::libc_allocator_with_realloc<std::pair<const std::string, double> > >::SelectKey, SetKey = google::dense_hash_map<std::string, double, __gnu_cxx::hash<std::string>, std::equal_to<std::string>, google::libc_allocator_with_realloc<std::pair<const std::string, double> > >::SetKey, EqualKey = std::equal_to<std::string>, Alloc = google::libc_allocator_with_realloc<std::pair<const std::string, double> >]' /usr/local/include/google/sparsehash/densehashtable.h:968: instantiated from `Value& google::dense_hashtable<Value, Key, HashFcn, ExtractKey, SetKey, EqualKey, Alloc>::find_or_insert(const Key&) [with DefaultValue = google::dense_hash_map<std::string, double, __gnu_cxx::hash<std::string>, std::equal_to<std::string>, google::libc_allocator_with_realloc<std::pair<const std::string, double> > >::DefaultValue, Value = std::pair<const std::string, double>, Key = std::string, HashFcn = __gnu_cxx::hash<std::string>, ExtractKey = google::dense_hash_map<std::string, double, __gnu_cxx::hash<std::string>, std::equal_to<std::string>, google::libc_allocator_with_realloc<std::pair<const std::string, double> > >::SelectKey, SetKey = google::dense_hash_map<std::string, double, __gnu_cxx::hash<std::string>, std::equal_to<std::string>, google::libc_allocator_with_realloc<std::pair<const std::string, double> > >::SetKey, EqualKey = std::equal_to<std::string>, Alloc = google::libc_allocator_with_realloc<std::pair<const std::string, double> >]' /usr/local/include/google/dense_hash_map:270: instantiated from `T& google::dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>::operator[](const typename google::dense_hashtable<std::pair<const _Key, _Tp>, Key, HashFcn, google::dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>::SelectKey, google::dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>::SetKey, EqualKey, Alloc>::key_type&) [with Key = std::string, T = double, HashFcn = __gnu_cxx::hash<std::string>, EqualKey = std::equal_to<std::string>, Alloc = google::libc_allocator_with_realloc<std::pair<const std::string, double> >]' /usr/local/include/google/dense_hash_map:270: instantiated from `T& google::dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>::operator[](const typename google::dense_hashtable<std::pair<const _Key, _Tp>, Key, HashFcn, google::dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>::SelectKey, google::dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>::SetKey, EqualKey, Alloc>::key_type&) [with Key = std::string, T = double, HashFcn = __gnu_cxx::hash<std::string>, EqualKey = std::equal_to<std::string>, Alloc = google::libc_allocator_with_realloc<std::pair<const std::string, double> >]' bayon.cc:272: instantiated from here /usr/local/include/google/sparsehash/hashtable-common.h:65: error: `operator()' is not a member of `__gnu_cxx::hash<std::string>' make: *** [bayon.o] Error 1
Google Code Archive - Long-term storage for Google Code Project Hosting.によれば、 __gnu_cxx::hash
bayonのutil.hでは
/* hash function of string key for __gnu_cxx::hash_map */ #if (defined(_WIN32) || !defined(HAVE_GOOGLE_DENSE_HASH_MAP)) && defined(HAVE_EXT_HASH_MAP) namespace __gnu_cxx { template<> struct hash<std::string> { size_t operator() (const std::string &x) const { return hash<const char *>()(x.c_str()); } };
となってるので、対策はされてるもののCygwinのことは考慮されてない模様。
条件部を
/* hash function of string key for __gnu_cxx::hash_map */ -#if (defined(_WIN32) || !defined(HAVE_GOOGLE_DENSE_HASH_MAP)) && defined(HAVE_EXT_HASH_MAP) +#if 1 || (defined(_WIN32) || !defined(HAVE_GOOGLE_DENSE_HASH_MAP)) && defined(HAVE_EXT_HASH_MAP) namespace __gnu_cxx {
として対処した(ひどいが、もっとましなやりかたを思いつかなかった……)。
で、ふたたびmakeする。
$ make LD_RUN_PATH=.:/lib:/usr/lib:/usr/local/lib:/cygdrive/c/home/lib:/usr/local/lib:/usr/local/lib g++ -Wall -fPIC -O3 -o bayon bayon.o -L. -L/usr/local/lib -L/cygdrive/c/home/lib -L/usr/local/lib -lbayon bayon.o:bayon.cc:(.text+0x7c70): undefined reference to `bayon::Classifier::VECID_EMPTY_KEY' bayon.o:bayon.cc:(.text+0x7c82): undefined reference to `bayon::Classifier::VECID_EMPTY_KEY' collect2: ld returned 1 exit status make: *** [bayon] Error 1
これは、classifier.hの
Classifier() { init_hash_map(VECID_EMPTY_KEY, vectors_); init_hash_map(VECID_EMPTY_KEY, inverted_index_);
が悪さしてる(なぜだ……)ので、定数を展開する。
Classifier() { - init_hash_map(VECID_EMPTY_KEY, vectors_); - init_hash_map(VECID_EMPTY_KEY, inverted_index_); + // VECID_EMPTY_KEY = -1 + init_hash_map(-1, vectors_); + init_hash_map(-1, inverted_index_); }
で、とりあえずコンパイルは通ったのでインストールしてみる(googletest導入法調べてないのでテストは割愛……)
$ make install
チュートリアルのサンプルを動かしてみる
$ bayon -n 3 -p data/test2.tsv 1 田村 0.987737 小島 0.987737 2 青柳 0.928262 阿佐田 0.928262 3 三輪 0.922401 古川 0.922401
イエス!!!
(おわり)