RMeCabが64bit版だけExceptionする場合の対処
RMeCabが64bit版だけExceptionする。 32bit版は何事もなく動く。
環境
以下環境で発生
- Windows 7 x64 (build 7601) Service Pack 1
- R version 3.4.0 (2017-04-21)
- RStudio Version 1.0.143
- mecab-0.996 (SJIS)
- RMeCab_0.99997
RとRStduioのインストール先
- D:/Program/R
- D:/Program/RStdio
MeCabインストール先
症状
library(RMeCab) res <- RMeCabC("すもももももももものうち") #ここで落ちる
exceptionで特にエラーを吐かず落ちる
イベントログ(下記抜粋)
障害が発生しているアプリケーション名: rsession.exe 障害が発生しているモジュール名: R.dll、バージョン: 3.40.7034.0 例外コード: 0xc0000005 障害オフセット: 0x00000000000f3819
例外コード: 0xc0000005はメモリでアクセス違反だったような気がする。
twitterでの作成者(石田先生?)からの助言(抜粋)
twitterでつぶやいていたら、RMeCabを開発した方とおぼしき方から(石田先生?)有難い助言が!!!
横から失礼します。おっしゃる通りで32/64両方で動作するよう設計されているのですが、差し支えなければWindowsおよびRの環境をお教えいただけないでしょうか?https://t.co/XPXezBP4Lghttps://t.co/CYbuZtbiJs()
— RMeCab (@rmecab) 2017年7月3日
先生の方の64bit版Win7は現象が再現しないとのこと。
先生の貴重な時間を割いて調べて頂けるなんてありがたや。 ここまでやってもらったら、自分でも頑張って少しは手がかりをつかまなくては!
Rを入れなおしてためす
基本に立ち戻り、再インストールから検証
- R 3.4.0 再インストール 結果 ×
Rを最新にしてみる。
- R 3.4.1 インストール 結果 ×
入れ直しでは治らなかった・・・そんな簡単じゃないよね!
Rのdebug機能を試す
アート・オブ・Rプログラミングの13章デバックを参考にどこでエラーが起きるか追いかける。
library(RMeCab) debug(RMeCabC) res <- RMeCabC("すもももももももものうち") debugging in: RMeCabC("すもももももももものうち") debug: { if (!is.character(str)) { str <- as.character(str) } if (nchar(str) < 1) { stop("first argument must be specified") } if (is.null(dic) || is.na(dic)) { dic = "" } else if ((xl <- nchar(dic)) > 0) { dic <- paste(dirname(dic), basename(dic), sep = "/") if (!(file.exists(dic))) { cat("specified dictionary file not found; result by default dictionary.\\n") dic = "" } else { dic <- paste("-u", dic) } } if (is.null(mecabrc) || is.na(mecabrc) || (nchar(mecabrc)) < 2) { mecabrc = "" } else { mecabrc <- paste(dirname(mecabrc), basename(mecabrc), sep = "/") if (!(file.exists(mecabrc))) { cat("specified mecabrc not found; result by default mecabrc.\\n") mecabrc = "" } else { mecabrc <- paste("-r", mecabrc) } } opt <- paste(dic, mecabrc, etc) ret <- .Call("RMeCabC", as.character(str), as.integer(mypref), as.character(opt), PACKAGE = "RMeCab") return(ret) } Browse[2]> n debug: if (!is.character(str)) { str <- as.character(str) } Browse[2]> n debug: if (nchar(str) < 1) { stop("first argument must be specified") } Browse[2]> n debug: if (is.null(dic) || is.na(dic)) { dic = "" } else if ((xl <- nchar(dic)) > 0) { dic <- paste(dirname(dic), basename(dic), sep = "/") if (!(file.exists(dic))) { cat("specified dictionary file not found; result by default dictionary.\\n") dic = "" } else { dic <- paste("-u", dic) } } Browse[2]> n debug: if ((xl <- nchar(dic)) > 0) { dic <- paste(dirname(dic), basename(dic), sep = "/") if (!(file.exists(dic))) { cat("specified dictionary file not found; result by default dictionary.\\n") dic = "" } else { dic <- paste("-u", dic) } } Browse[2]> n debug: if (is.null(mecabrc) || is.na(mecabrc) || (nchar(mecabrc)) < 2) { mecabrc = "" } else { mecabrc <- paste(dirname(mecabrc), basename(mecabrc), sep = "/") if (!(file.exists(mecabrc))) { cat("specified mecabrc not found; result by default mecabrc.\\n") mecabrc = "" } else { mecabrc <- paste("-r", mecabrc) } } Browse[2]> n debug: mecabrc = "" Browse[2]> n debug: opt <- paste(dic, mecabrc, etc) Browse[2]> n
ということで、以下の部分に行く前に落ちることが分かった。
ret <- .Call("RMeCabC", as.character(str), as.integer(mypref), as.character(opt), PACKAGE = "RMeCab")
.Callはc++のDLLを呼ぶ関数。 やはり、c++のDLLを呼ぶところでエラーになるらしい。
ソースがないのでこれ以上追えない。
ソースからコンパイルする準備
Rtools34.exeをインストール
https://cran.r-project.org/bin/windows/Rtools/
から
Rtools34.exe R 3.3.x and later
をダウンロードして実行
インストール場所は
D:\Program\Rtools
(※本当は標準のc:\Rtoolsに入れた方が楽)
Edit the system PATH.は Save version information to registry にチェック
次のSystem Path の編集は 64bitマシンなら 3行目を
D:\Program\R\R-3.4.1\bin D:\Program\Rtools\bin D:\Program\Rtools\mingw_32\bin ↓↓↓ 変更 D:\Program\R\R-3.4.1\bin D:\Program\Rtools\bin D:\Program\Rtools\mingw_64\bin
に変更
RのMakeconfを変更
※ 標準のc:\Rtoolsに入れた場合はこの作業はいらない。
D:\Program\R\R-3.4.1\etc\x64\Makeconf"
# 以下の二つ書き換え #BINPREF ?= c:/Rtools/mingw_64/bin/ BINPREF ?= D:/Program/Rtools/mingw_64/bin/ #LOCAL_SOFT = d:/Compiler/gcc-4.9.3/local330 LOCAL_SOFT = D:/Program/Rtools/mingw_64
同じように編集32bit用も編集
D:\Program\R\R-3.4.1\etc\i386\Makeconf"
# 以下の二つ書き換え #BINPREF ?= c:/Rtools/mingw_64/bin/ BINPREF ?= D:/Program/Rtools/mingw_64/bin/ #LOCAL_SOFT = d:/Compiler/gcc-4.9.3/local330 LOCAL_SOFT = D:/Program/Rtools/mingw_64
この後、一旦R再起動
RでPATHを確認
Sys.getenv('PATH') [1] "D:\\Program\\Rtools\\bin;D:\\Program\\Rtools\\mingw_64\\bin";
コンパイラがRから呼び出せるか確認
system('g++ -v') Using built-in specs. COLLECT_GCC=D:\Program\Rtools\mingw_64\bin\G__~1.EXE COLLECT_LTO_WRAPPER=D:/Program/Rtools/mingw_64/bin/../libexec/gcc/x86_64-w64-mingw32/4.9.3/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../src/gcc-4.9.3/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64 --with-gxx-include-dir=/mingw64/x86_64-w64-mingw32/include/c++ --enable-static --disable-shared --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-mpc=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-isl=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-cloog=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='x86_64-posix-seh, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64/opt/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-zlib-static/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64/opt/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-zlib-static/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64/opt/lib -L/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-zlib-static/lib -L/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static/lib ' Thread model: posix gcc version 4.9.3 (x86_64-posix-seh, Built by MinGW-W64 project)
RでMAKEがどこに設定されているか確認
system('where make') D:\Program\Rtools\bin\make.exe
ソースからコンパイル
その1
一旦既存のパッケージは削除
MacやLinuxと同じタイプでやってみる。
remove.packages("RMeCab") install.packages("RMeCab", repos = "http://rmecab.jp/R", type = "source") D:/Program/Rtools/mingw_32/bin/../lib/gcc/i686-w64-mingw32/4.9.3/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lmecab collect2.exe: error: ld returned 1 exit status DLLは生成されませんでした ERROR: compilation failed for package 'RMeCab' * removing 'D:/Program/R/R-3.4.1/library/RMeCab' ダウンロードされたパッケージは、以下にあります ‘C:\Users\kuma\AppData\Local\Temp\RtmpOWFHXp\downloaded_packages’ 警告メッセージ: 1: 命令 '"D:/Program/R/R-3.4.1/bin/x64/R" CMD INSTALL -l "D:\Program\R\R-3.4.1\library" C:\Users\kuma\AppData\Local\Temp\RtmpOWFHXp/downloaded_packages/RMeCab_0.99997.tar.gz' の実行は状態 1 を持ちました 2: install.packages("RMeCab", repos = "http://rmecab.jp/R", type = "source") で: パッケージ ‘RMeCab’ のインストールは、ゼロでない終了値をもちました
失敗、インストールできなかった。
その2
ソースのダウンロード
https://github.com/IshidaMotohiro/RMeCab
D:\RMeCabに解凍しておく
パッケージのチェック コマンドプロンプトで以下実行
cd /d D:\ R CMD check RMeCab --no-manual --no-install * using log directory 'D://RMeCab.Rcheck' * using R version 3.4.1 (2017-06-30) * using platform: x86_64-w64-mingw32 (64-bit) * DONE Status: 4 WARNINGs, 2 NOTEs See 'D://RMeCab.Rcheck/00check.log' for details.
WARNINGがいくつかあるが、Errorはないので平気? D://RMeCab.Rcheck/00check.logにログが残る。
パッケージのビルド
R CMD build RMeCab * checking for file 'RMeCab/DESCRIPTION' ... OK * preparing 'RMeCab': * checking DESCRIPTION meta-information ... OK * cleaning src * checking for LF line-endings in source and make files * checking for empty or unneeded directories * building 'RMeCab_0.99997.tar.gz'
tar.gzファイルができる。
R CMD INSTALL --build RMeCab_0.99997.tar.gz ///途中省略 D:/Program/Rtools/mingw_32/bin/g++ -shared -s -static-libgcc -o RMeCab.dll tmp.d ef Ngram.o NgramDF.o NgramDF2.o RMeCab.o RMeCabC.o RMeCabDoc.o RMeCabFreq.o RMeC abMx.o RMeCabText.o collocate.o docDF.o docMatrix2.o docMatrixDF.o docNgram2.o d ocNgramDF.o setMeCabMap.o -lmecab -LD:/Program/Rtools/mingw_32/lib/i386 -LD:/Pro gram/Rtools/mingw_32/lib -LD:/Program/R/R-3.4.1/bin/i386 -lR D:/Program/Rtools/mingw_32/bin/../lib/gcc/i686-w64-mingw32/4.9.3/../../../../i68 6-w64-mingw32/bin/ld.exe: cannot find -lmecab collect2.exe: error: ld returned 1 exit status DLLヘカャウワケナオス ERROR: compilation failed for package 'RMeCab' * removing 'D:/Program/R/R-3.4.1/library/RMeCab'
最後にコンパイルがこける。 エラーメッセージからMeCabのDLLを探しているらしいので
mecabのインストール先から “C:\Program Files (x86)\MeCab\bin\libmecab.dll” をコピーして以下にコピー D:\Program\R\R-3.4.1\bin\i386
ただし、このままだと64bit版のMeCabのDLLがない。
64bit版MeCabのDLL作成
以下記事を参考に作成 (ちなみに思考停止して作成したので内容はよくわかってないです。) http://qiita.com/tobesan/items/6b6f3a025fdd177ef52a
MeCabのソースをダウンロード
https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE
事前準備
事前に準備でコピー
ダウンロードしたmecab-0.996.tar.gz を展開します。 ここでは以下に展開しました。 - D:\Download\mecab-0.996
MeCabソースの修正、ビルド
mecab-0.996/srcフォルダ内のいくつかのファイルを修正します。 (旧)以下を(新)以下に変更してください
Makefile.msvc.in 内を Windows 7 64bit用に修正 6行目 /MACHINE:X86 → /MACHINE:X64
(旧)LDFLAGS = /nologo /OPT:REF /OPT:ICF /LTCG /NXCOMPAT /DYNAMICBASE /MACHINE:X86 ADVAPI32.LIB (新)LDFLAGS = /nologo /OPT:REF /OPT:ICF /LTCG /NXCOMPAT /DYNAMICBASE /MACHINE:X64 ADVAPI32.LIB
8行目 -DDIC_VERSION=@DIC_VERSION@ → -DDIC_VERSION=102
(旧)-DDLL_EXPORT -DHAVE_GETENV -DHAVE_WINDOWS_H -DDIC_VERSION=@DIC_VERSION@ \ (新)-DDLL_EXPORT -DHAVE_GETENV -DHAVE_WINDOWS_H -DDIC_VERSION=102 \
9行目 -DVERSION=“\”@VERSION@“\”“ → -DVERSION=”\“0.996\”"
(旧) -DVERSION="\"@VERSION@\"" -DPACKAGE="\"mecab\"" \ (新) -DVERSION="\"0.996\"" -DPACKAGE="\"mecab\"" \
11行目 "\“c:\Program Files\mecab\etc\mecabrc\”“ → ”\“c:\mecab\etc\mecabrc\”"
mecabrcの場所を指定してください (旧) -DMECAB_DEFAULT_RC="\"c:\\Program Files\\mecab\\etc\\mecabrc\"" (新) -DMECAB_DEFAULT_RC="\"c:\\mecab\\etc\\mecabrc\""
356行目 size_t → unsigned int
feature_index.cpp (旧)case 't': os_ << (size_t)path->rnode->char_type; break; (新)case 't': os_ << (unsigned int)path->rnode->char_type; break;
writer.cpp 260行目 size_t → unsigned int
(旧)case 'L': *os << (size_t)lattice->size(); break; (新)case 'L': *os << (unsigned int)lattice->size(); break;
mecab.h 1125行目 #ifndef SIWG → #ifndef SWIG
(旧) #ifndef SIWG (新) #ifndef SWIG
common.h include部分に追記 #include
(新) #include <iterator>
Build Tools for Visual Studio 2017
コンパイルに必要なので以下ダウンロードしてインストール https://www.visualstudio.com/ja/thank-you-downloading-visual-studio/?sku=BuildTools&rel=15
ツールを実行し、Visual C++ Build Toolsを選択して
場所は(サイズが3.39GBとでかすぎるので)
D:\Program\Microsoft Visual Studio\2017\BuildTools
に変更してインストール
コンパイル
コマンドプロンプトを管理者権限で立ち上げて以下実行
cd /d D:\Download\mecab-0.996\src call "D:\Program\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 nmake -f Makefile.msvc.in
これで、直下にlibmecab.dllができるので、以下にコピー
D:\Program\R\R-3.4.1\bin\x64
ふたたびRMeCabコンパイル
D:\Program\R\R-3.4.1\bin\x64にコンパイルした64bitのlibmecab.dll
D:\Program\R\R-3.4.1\bin\i386にはMeCabに元からある32bitのlibmecab.dll
があるのを確認後、ビルド
cd /d D:\ R CMD INSTALL --build RMeCab_0.99997.tar.gz # 最後に以下のような表示になればインストール成功 ** R ** preparing package for lazy loading ** help *** installing help indices ** building package indices ** testing if installed package can be loaded *** arch - i386 *** arch - x64 * MD5 sums packaged installation of 'RMeCab' as RMeCab_0.99997.zip * DONE (RMeCab)
動作確認
Rの64ビット版で以下実行
library(RMeCab) res <- RMeCabC("すもももももももものうち") res [[1]] 名詞 "すもも" [[2]] 助詞 "も" [[3]] 名詞 "もも" [[4]] 助詞 "も" [[5]] 名詞 "もも" [[6]] 助詞 "の" [[7]] 名詞 "うち"
うごいた!
まとめ
RMeCabの64bit版は64bit用にコンパイルしたMeCabが使われている。 したがって、32bitと64bitでは違うDLLなので、 32bit版だけ動いて64bit版だけ動かないのは有りうる。
機種依存の原因はわからなかったが、 RMeCabの方のソースはいじっていないので、 おそらくコンパイラのバージョンが違うとかMeCabのコンパイラの仕方が 違うなどが原因として考えられる。
けどまあ、初学者なので自分はっきりいって、
|\ /| |\\ //| : ,> `´ ̄`´ < ′ . V V . i{ ● ● }i 八 、_,_, 八 わけがわからないよ . / 个 . _ _ . 个 ', _/ il ,' '. li ',__
おしまい