研究ブログ

MacPortsでMecabをインストールした場合のRMeCabのインストール

■ はじめに

MacPortsを使ってmecabをインストールした場合、標準的な方法でRMeCabをインストールしてもうまく動かないようです。ただ、この後説明するように、問題を回避できたので、まとめておきます。説明に使うバージョンは以下の通りで、いずれもMacPortsからインストールしています。

  • R 3.6.1
  • mecab 0.996
  • mecab-ipadic 2.7.0

■ 標準的なインストール

まず、こちらのサイトを参考に、RからRMeCabをインストールしてみます。
> install.packages ("RMeCab", repos = "http://rmecab.jp/R", type = "source")

上のサイトにあるように、MacやLinuxでは、typeとしてsourceを指定しないといけません。つまり、コンパイルする必要がありますが、コマンドライン・ツールのインストールなどを含め、上記サイトには丁寧に解説してあります。

このコマンドを入力すると、コンパイル作業が始まり、その様子が表示されますが、最後のほうは以下のようになります。


(略)
clang++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG -I. -I/usr/local/include -fPIC -Wall -g -O2 -c docNgramDF.cpp -o docNgramDF.o
clang++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG -I. -I/usr/local/include -fPIC -Wall -g -O2 -c setMeCabMap.cpp -o setMeCabMap.o
clang++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o RMeCab.so Ngram.o NgramDF.o NgramDF2.o RMeCab.o RMeCabC.o RMeCabDoc.o RMeCabFreq.o RMeCabMx.o RMeCabText.o collocate.o docDF.o docMatrix2.o docMatrixDF.o docNgram2.o docNgramDF.o setMeCabMap.o -L/usr/local/lib -lmecab -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
installing to /Library/Frameworks/R.framework/Versions/3.4/Resources/library/RMeCab/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (RMeCab)

"clang++"というのがコンパイラで、1つの行が1つのファイルをコンパイルしていて、最後の長い行(clang++ -dynamiclibで始まる行)が、それまでにコンパイルした各ファイル(RMeCabC.oのように、拡張子が.oのファイル)を全て集めて、RMeCab.soというファイルを作ります。

コンパイルする時には既存のライブラリを用いることが多いのですが、ライブラリには、OSに最初から付属しているインストールされているライブラリ(標準ライブラリなどと呼びます)と、後からユーザがインストールしたものがあります。標準ライブラリは、インストールされる場所が決まっており、コンパイラがライブラリを探す時は、これらの場所から目的のライブラリを探しますが、ユーザがインストールしたライブラリを用いる場合は、どこにインストールしてあるかその場所をコンパイラに教える必要があります。そのオプションが-Lです。例えば、-L/usr/local/libというのが、RMeCab.soをコンパイルしている行にありますが、これはコンパイラに/usr/local/libというディレクトリを探してね、という指示です。このオプションは複数指定でき、ある場所になければ、他に指定された場所も調べます。

インストールされたRMeCab.soが、どのライブラリを使っているかは、以下のように調べます。まず、以下のようにして、R内で利用されるライブラリのインストール先を調べます。
> .libPaths()
[1] "/Library/Frameworks/R.framework/Versions/3.4/Resources/library"

ターミナルで、以下のように入力すると、これまでにインストールしたライブラリの名前がディレクトリとして表示されると思います。ここにRMeCabがあるはずです。
% ls -1 /Library/Frameworks/R.framewok/Versions/3.4/Resources/library
KernSmooth
MASS
Matrix
RMeCab
Rcpp
(以下、略)

さらに、RMeCabの中を確認すると、いくつかのサブディレクトリがあり、この中のlibsの舌にRMeCab.soがあります。このRMeCab.soというファイルに対して、以下のようにotoolというコマンドを用いると、どのライブラリが使われているか分かりますが、最初のほうに書いたように/usr/lib/libmecab.dylibが使われていることが分かります。

% otool -L /Library/Frameworks/R.framework/Versions/3.4/Resources/library/RMeCab/libs/RMeCab.so
/Library/Frameworks/R.framework/Versions/3.4/Resources/library/RMeCab/libs/RMeCab.so:
RMeCab.so (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libmecab.dylib (compatibility version 1.0.0, current version 883.0.0)
/Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libR.dylib (compatibility version 3.4.0, current version 3.4.1)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1673.126.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.7.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)

このようにしてコンパイル、インストールが済んだら
> library(RMeCab)
> RMeCabC("テスト")
とRMeCabを実行できるはずなのですが、以下の画像のようなエラーがでます。

Exception:/BuildRoot/Library/Caches/com.apple.xbs/Sources/Mecabra/Mecabra-883.1.1/src/tokenizer/tagger.cpp(110) [load_dictionary_resource(param)] /BuildRoot/Library/Caches/com.apple.xbs/Sources/Mecabra/Mecabra-883.1.1/src/param.cpp(130) [ifs] no such file or directory: ./dicrc

エラーメッセージを見ると、設定ファイルが見つからないと言っているようにも見えますが、今回の場合は、後述するように、設定ファイルは関係なかったようです。

■ 回避策

今回紹介する回避策はRMeCab掲示版のこちらの書き込みを元に、もう少し詳しく手順を書いたものです。

RMeCabをインストールする前に、Mecabをインストールする必要がありますが、MacPortsでインストールしました。これによってlibmecab.dylibというライブラリがインストールされ、このライブラリを用いてRMeCabが動作しますが、MacにはOSに付属してlibmecab.dylibという同名のライブラリが存在します。このライブラリは、RMeCabが要求するものではないのですが、コンパイル時の設定によりこちらが使われているようです。そのため、回避策の骨子は、RMeCabのソースをダウンロードし、libmecab.dylibを読み込むディレクトリを指定した上でコンパイルしてインストール、となります。

まず、ソースファイルのダウンロードは以下のようにします。
> download.packages ("RMeCab", destdir = "~/Downloads", repos = "http://rmecab.jp/R", type = "source")
destdir の値は適当に修正してください。

ダウンロードしたRMeCabは、~/Downloads/RMeCab_0.99999.tar.gzなどとなります。バージョンが異なれば、~/Downloads/RMeCab_1.04.tar.gzとなったりします。

このファイルを展開した上で、RMeCab/src/Makevars内の
MECAB = -L/usr/local/lib -lmecab
を、以下のように変更します。
MECAB = -L/opt/local/lib -lmecab
MacPortsは/opt/local/lib以下にlibmecab.dylibをインストールするので、上のように変更しましたが、Homebrewなど/usr/local/libにインストールされる場合は、問題は起きないでしょう。

この後、修正したファイルを、再度tar.gzに固めた上で、以下のようにしてインストールします。
> install.packages("~/Downloads/RMeCab_0.99999.tar.gz", repos=NULL, type="source")

今度は、コンパイルの最後のところで、-L/opt/local/libとなっていると思います。otoolで調べてみると


% otool -L /Library/Frameworks/R.framework/Versions/3.4/Resources/library/RMeCab/libs/RMeCab.so
/Library/Frameworks/R.framework/Versions/3.4/Resources/library/RMeCab/libs/RMeCab.so:
RMeCab.so (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libmecab.2.dylib (compatibility version 3.0.0, current version 3.0.0)
/Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libR.dylib (compatibility version 3.4.0, current version 3.4.1)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1673.126.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.7.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)

となって、今度は /opt/local/lib/ 以下にある /opt/local/lib/libmecab.2.dylib が使われていることが分かります。ここまでくれば、RMeCabが使えるようになります。といっても、簡単にチェックしただけですが...