Russian Lemmatizer installation on FreeBSD 10.1-RELEASE

弊サイトのプーシキン全集見出語コンコーダンスサービス Конкорданс к тексту А. С. Пушкина は,ロシア語形態素解析ソフトウェア Lemmatizer を用いて単語の見出語形を機械的に判別している。このソフトウェアはアレクセイ・ソキルコ Алексей Сокирко の AOT プロジェクトチームによる成果である。残念なことに,現時点では http://lemmatizer.jooko.net サイトが開設されていながら,ソフトウェアそのものはデッドリンクになってしまっている。私は昔ダウンロードしたアーカイブを大事に仕舞ってあるので困らないわけなんだが,ソフトウェアというは放置すると腐るものなのだ。

このたび弊サイトのプラットフォームを FreeBSD 10.1-RELEASE に更改し,コンコーダンスのリソースも再度ビルドし直すこととなった。まず念頭に飛来したのが,腐りかけのこの Lemmatizer が 64-bit OS 上できちんとコンパイル,稼働可能かということだった。Lemmatizer はコンコーダンスの核なので,これがきちんと動かないと,これまでのコンコーダンスプログラミングの努力が水の泡になってしまう。

さて,かつて Lemmatizer サイトからダウンロードした libMAFSA-0.2.tar.gzlibturglem-0.2.tar.gzturglem-russian-0.2.tar.gz を解凍し,インストール。果たして cmake の実行でまずはワーニングが出た。また,コンパイルエラー,リンクエラーが。今日は,これらの問題の対処とプーシキン全集見出語コンコーダンスサービス Конкорданс к тексту А. С. Пушкина の構築のメモを,あとあとのために残しておく。ビルドに用いたのは cmake version 3.2.3FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512 である。

libMAFSA-0.2 cmake ワーニングの対処

cmake のワーニングは次のようなものである。

% tar zxvf libMAFSA-0.2.tar.gz -C ~/var
% cd ~/var/libMAFSA-0.2
% cmake .
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as
 
    cmake_minimum_required(VERSION 3.2)
 
  should be added at the top of the file...

書いてあるとおりに CMakeLists.txt の先頭に cmake_minimum_required(VERSION 3.2) 行を挿入すれば,ワーニングは消えた。

libMAFSA test.cpp コンパイルエラー

次に clang++ でビルドするも,くだらないコンパイルエラーに見舞われる。

[ 33%] Built target MAFSA
Scanning dependencies of target test_MAFSA_library
[ 66%] Building CXX object CMakeFiles/test_MAFSA_library.dir/test/test.cpp.o
/home/isao/var/libMAFSA-0.2/test/test.cpp:115:3: error: use of undeclared
      identifier 'exit'
                exit(-1);
                ^
/home/isao/var/libMAFSA-0.2/test/test.cpp:166:11: error: use of undeclared
      identifier 'mkstemp'
        int fd = mkstemp(tmp_file_name);
                 ^
/home/isao/var/libMAFSA-0.2/test/test.cpp:167:2: error: use of undeclared
      identifier 'close'
        close(fd);
        ^
/home/isao/var/libMAFSA-0.2/test/test.cpp:180:2: error: use of undeclared
      identifier 'unlink'; did you mean 'inline'?
        unlink(tmp_file_name);
        ^
4 errors generated.

テストプログラムみたいなので,どうでもいいような気がしたが,対処は易しいようであったので手直しすることに。close() やら exit() やらがなんでエラーになるのかと呆れるも,libMAFSA-0.2/test/test.cpp を以下のパッチのとおり変更する。unistd.hstdlib.h のヘッダを追加するのである。

*** test.cpp.orig	2015-07-18 04:01:31.000000000 +0900
--- test.cpp	2015-07-18 04:37:05.000000000 +0900
***************
*** 3,8 ****
--- 3,10 ----
  #include <MAFSA/automaton_int.h>
  #include <MAFSA/automaton_int_pair.h>
  #include "test_charset_adapters.h"
+ #include <unistd.h>
+ #include <stdlib.h>
   
  void test1(const char *fn)
  {

これでビルドは成功した。

% gmake
[ 33%] Built target MAFSA
Scanning dependencies of target test_MAFSA_library
[ 66%] Building CXX object CMakeFiles/test_MAFSA_library.dir/test/test.cpp.o
Linking CXX executable test_MAFSA_library
[100%] Built target test_MAFSA_library
% sudo gmake install  
...(略)

libturglem-0.2 については上記 cmake ワーニング対処だけですんなりインストールできた。

turglem-russian-0.2 リンクエラー

turglem-russian-0.2 は上記 cmake ワーニング対策だけでは不十分である。gmake でリンクエラーが出てしまうのである。

% gmake
[ 50%] Built target turglem-russian
Linking CXX executable morph_compiler_russian
/usr/bin/ld: cannot find -lexpat
CC: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeFiles/morph_compiler_russian.dir/build.make:87: recipe for target 'morph_compiler_
russian' failed

libexpat(Expat XML Parser)ライブラリが見つからないと。CMakeFiles/morph_compiler_russian.dir/link.txt のなかの -lexpat の前に -L/usr/local/lib を追加することでうまく通った。

/usr/bin/CC   -O3 -Wall -fomit-frame-pointer -funroll-loops -pedantic -Wno-long-long
-fPIC CMakeFiles/morph_compiler_russian.dir/morph_compiler_russian.cpp.o  -o morph_
compiler_russian libturglem-russian.a /usr/local/lib/libtxml.a -L/usr/local/lib
-lexpat
% gmake
Please wait, compiling dictionaries!
Flexias loaded and saved in binary mode
Lemmas loaded
Dictionary and prediction saved!
[100%] Built target morph_compiler_russian

ここで実行されるロシア語形態素辞書の生成は,それなりに時間がかかる。

前提ソフトウェアの組込みとコンコーダンスプログラムの構築

Lemmatizer のほかに,プーシキン見出語コンコーダンスプログラムの前提ソフトウェアとして,boost C++ クラスライブラリ,Wt C++ Toolkit クラスライブラリがある。後者はさらにその前提ライブラリがある。Wt Toolkit 以外は FreeBSD pkg でインストール可能である。Wt C++ Tooklit は http://www.webtoolkit.eu/wt/download から wt-3.3.4.tar.gz をダウンロードしてビルドする。

% sudo pkg install boost-all libharu GraphicsMagick pango fcgi-devkit ap24-mod_fcgid
% tar zxvf wt-3.3.4.tar.gz -C ~/var
% cd wt-3.3.4
% mkdir -p build
% cd build
% cmake ../
% gmake
% sudo gmake install

最後にプーシキン見出語コンコーダンスプログラムのインストールとコーパスメモリデータベース(共有メモリ上のプーシキン全集テクストと単語二分木)の構築である。

% cd ~/src/pushkin
% gmake modules
% sudo gmake init
% sudo gmake install
% cd ~/src/rcdscript
% sudo cp pushkin_concordance /usr/local/etc/rc.d
% sudo echo pushkin_concordance_enable=\"YES\" >> /etc/rc.conf
% sudo service pushkin_concordance start
% sudo apachectl restart

sudo gmake install で,プログラムをインストールするとともに,FastCGI のコンフィグを Apache24 の構成定義ディレクトリにコピーする。システム起動時に自動的にアプリケーションの動作環境を設定するために rc.d スクリプトを所定の位置にコピーするオペレーションも入れてある。

FastCGI コンフィグを下に掲げておく。ここで,/usr/local/www/pushkin/ 下に格納した Web アプリケーション一式を http://yasuda.homeip.net/pushkin/lemmatized/ URL でアクセスできるようにする Apache24 のロケーション設定も同時に行っている。

LoadModule fastcgi_module libexec/apache24/mod_fastcgi.so
<Directory "/usr/local/www/pushkin">
    order allow,deny
    allow from all
</Directory>
<IfModule mod_fastcgi.c>
    Alias /pushkin/lemmatized/ /usr/local/www/pushkin/
    FastCgiConfig -idle-timeout 600 -maxClassProcesses 20 -maxProcesses 60
-killInterval 1200 -autoUpdate -initial-env WT_AP_ROOT=/etc/wt
    Fastcgiserver /usr/local/www/pushkin/concordance
</IfModule>

データベースが構築されたかを確認し,Web でアクセスしてみる。動いた。64-bit FreeBSD でもなんとか動かすことが出来,ほっとしている。でも,腐り掛けの Lemmatizer。そのうち使えなくなることを鑑み,別のロシア語形態素解析ソフトウェアを探さなくてはならなくなりそうである。

% cat /var/pushkin_concordance/daemon.log
CorpusLoader starting.
CorpusLoader daemon started. PID: 73512
CorpusLoader Corpus Shared Memory Construction.
CorpusLoader Corpus:  /usr/local/etc/pushkin/pushkin.txt
CorpusLoader TitleDB: /usr/local/etc/pushkin/titledb.txt
CorpusLoader    Corpus  58537 lines constructed.
CorpusLoader            8.42188 sec elapsed.
CorpusLoader    TitleDB 1989 lines constructed.
CorpusLoader            0.210938 sec elapsed.
CorpusLoader    Corpus handle:  232
CorpusLoader    TitleDB handle: 16532136
CorpusLoader waiting for termination signals: SIGINT, SIGTERM, SIGHUP, SIGQUIT.
WordTreeBuilder starting.
WordTreeBuilder daemon started. PID: 73523
WordTreeBuilder Word Tree Shared Memory Construction.
WordTreeBuilder Corpus: /usr/local/etc/pushkin/pushkin.txt
WordTreeBuilder shared memory segment attached.
WordTreeBuilder shared memory allocated.
WordTreeBuilder Shared Memory pointer origin:  0x805c000c0
WordTreeBuilder Lemmatized form Word Tree:
WordTreeBuilder 10000 lines proceeded.
WordTreeBuilder 20000 lines proceeded.
WordTreeBuilder 30000 lines proceeded.
WordTreeBuilder 40000 lines proceeded.
WordTreeBuilder 50000 lines proceeded.
WordTreeBuilder Word Tree elapsed   7.34375 sec.
WordTreeBuilder Word Tree proceeded 58537 lines.
WordTreeBuilder Word Tree proceeded 766045 words.
WordTreeBuilder Word Tree built     39409 words.
WordTreeBuilder Shared Memory pointer current: 0x8075c36ec
WordTreeBuilder Word Tree entry address: 0x805c000c0
WordTreeBuilder Address difference:      19c362c (27014700)
WordTreeBuilder Lemmatized form Word Tree handle:  192
WordTreeBuilder Appearance form Word Tree:
WordTreeBuilder 10000 lines proceeded.
WordTreeBuilder 20000 lines proceeded.
WordTreeBuilder 30000 lines proceeded.
WordTreeBuilder 40000 lines proceeded.
WordTreeBuilder 50000 lines proceeded.
WordTreeBuilder Word Tree elapsed   5.10156 sec.
WordTreeBuilder Word Tree proceeded 58537 lines.
WordTreeBuilder Word Tree proceeded 766045 words.
WordTreeBuilder Word Tree built     95352 words.
WordTreeBuilder Shared Memory pointer current: 0x809307c0b
WordTreeBuilder Word Tree entry address:  0x8075c36ec
WordTreeBuilder Address difference:       1d4451f (30688543)
WordTreeBuilder Appearance form Word Tree handle:  27014892
WordTreeBuilder waiting for termination signals: SIGINT, SIGTERM, SIGHUP, SIGQUIT.
20150723a-pushkin.png
Конкорданс к тексту А. С. Пушкина