MeCabのVisual Studioソリューション


#1.何をするものなのか

https://github.com/k-ayaki/mecab-msvc


https://github.com/k-ayaki/mecab-msvc64


　これは、MeCab Ver.0.996のソースコードを、VisualStudio2019 にてデバッグするためのソリューションファイルの設定を説明するものです。これにより、VisualStudio2019 上で MeCab のソースコードにブレークポイントを設定したり、ソースコードと変数をウオッチしながらステップ実行させることが可能となります。
　自分の調べた範囲では、このようなものは公開されていなかったので、自作しました。x64版も作成しました。

　MeCabの utils.cpp にブレークポイントを設定してデバッグしている画面を以下に示します。
![2021-08-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/43c16ddd-b711-2345-0d5e-a8e1ab5a8a14.png)

　mecab.exe で形態素解析したコンソール画面です。なお、辞書ファイルとその設定ファイルもソリューションに含めていますので、github のファイル一式だけで動作可能です。
![2021-08-28 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/e0d743a2-6e8b-4344-4122-3ac543e46898.png)


#2. MeCabのVisual C++用Makefile
　MeCabのWindows最終版である Ver.0.996 は、https://taku910.github.io/mecab/#download からダウンロード可能です。その中に、以下に示す Visual C++ 用のMakefileが含まれています。
　単に、ソースコードを再ビルドしてインストールするだけならば、Developer Command Prompt for VS 2019を起動して、Nmake makefile.msvc.in を実行すればよいです。但し、これではブレークポイントを設定し、ステップ実行させることができません。

```make:Makefile.msvc.in
CC = cl.exe
CXXC = cl.exe
LINK=link.exe

CFLAGS = /EHsc /O2 /GL /GA /Ob2 /nologo /W3 /MT /Zi /wd4800 /wd4305 /wd4244
LDFLAGS = /nologo /OPT:REF /OPT:ICF /LTCG /NXCOMPAT /DYNAMICBASE /MACHINE:X86 ADVAPI32.LIB
DEFS =  -D_CRT_SECURE_NO_DEPRECATE -DMECAB_USE_THREAD \
        -DDLL_EXPORT -DHAVE_GETENV -DHAVE_WINDOWS_H -DDIC_VERSION=@DIC_VERSION@ \
        -DVERSION="\"@VERSION@\"" -DPACKAGE="\"mecab\"" \
        -DUNICODE -D_UNICODE \
        -DMECAB_DEFAULT_RC="\"c:\\Program Files\\mecab\\etc\\mecabrc\""
INC = -I. -I..
DEL = del

OBJ =   feature_index.obj param.obj  learner.obj string_buffer.obj \
	char_property.obj         learner_tagger.obj    tagger.obj \
	connector.obj             tokenizer.obj \
	context_id.obj            dictionary.obj  utils.obj \
	dictionary_compiler.obj   viterbi.obj \
	dictionary_generator.obj  writer.obj iconv_utils.obj \
	dictionary_rewriter.obj   lbfgs.obj eval.obj nbest_generator.obj

.c.obj:
	$(CC) $(CFLAGS) $(INC) $(DEFS) -c  $<

.cpp.obj:
	$(CC) $(CFLAGS) $(INC) $(DEFS) -c  $<

all: libmecab mecab mecab-dict-index mecab-dict-gen mecab-cost-train mecab-system-eval mecab-test-gen

mecab: $(OBJ) mecab.obj
	$(LINK) $(LDFLAGS) /out:$@.exe mecab.obj libmecab.lib

mecab-dict-index: $(OBJ) mecab-dict-index.obj
	$(LINK) $(LDFLAGS) /out:$@.exe mecab-dict-index.obj libmecab.lib

mecab-dict-gen: $(OBJ) mecab-dict-gen.obj
	$(LINK) $(LDFLAGS) /out:$@.exe mecab-dict-gen.obj libmecab.lib

mecab-cost-train: $(OBJ) mecab-cost-train.obj
	$(LINK) $(LDFLAGS) /out:$@.exe mecab-cost-train.obj libmecab.lib

mecab-system-eval: $(OBJ) mecab-system-eval.obj
	$(LINK) $(LDFLAGS) /out:$@.exe mecab-system-eval.obj libmecab.lib

mecab-test-gen: mecab-test-gen.obj
	$(LINK) $(LDFLAGS) /out:$@.exe mecab-test-gen.obj libmecab.lib

libmecab: $(OBJ) libmecab.obj
	$(LINK) $(LDFLAGS) /out:$@.dll $(OBJ) libmecab.obj /dll

clean:
	$(DEL) *.exe *.obj *.dll *.a *.lib *.o *.exp *.def

```

CFLAGS:
 C++コンパイラのフラグです。

| フラグ名   | 意味                                   |
|:-----------|:--------------------------------------|
| /EHsc      | extern "C" は既定の nothrow になる     |
| /O2        | 最大限の最適化 (速度を優先)             |
| /GL        | リンク時のコード生成を有効にする         |
| /GA        | Windows アプリケーション用の最適化を行う |
| /Ob2       | インライン展開 (既定値 n=0)             |
| /nologo    |  著作権メッセージを表示しない            |
| /W3        |  警告レベル３                           |
| /MT        |  LIBCMT.LIB でリンクする                |
| /Zi        |  デバッグ情報を有効にします              |
| /wd4800    | 警告4800を無効にします                   |
| /wd4305    | 警告4305を無効にします                   |
| /wd4244    | 警告4244を無効にします                   |


DEFS:
 C++コンパイラのフラグのうち、マクロ定義に係るものです。

| フラグ名    | 意味                                   |
|:-----------|:--------------------------------------|
| -D \<name>\=\<text\>         | マクロを定義します     |


| マクロ名とテキスト   | 意味                         |
|:-----------|:--------------------------------------|
| -D_CRT_SECURE_NO_DEPRECATE | strcpy, strcat, sprintf のような標準Cの文字列操作関数の利用時の警告を抑止するコンパイラスイッチです。 |
| -DMECAB_USE_THREAD | スレッドを使うためのMeCabのスイッチです。 |
| -DDLL_EXPORT | DLLをエクスポートするためのMeCabのスイッチです。 |
| -DHAVE_GETENV | 環境変数による辞書パス設定を許可するMeCabのスイッチです。 |
| -DHAVE_WINDOWS_H | |
| -DDIC_VERSION=@DIC_VERSION@  | 辞書バージョンを設定するマクロです。 |
| -DVERSION="\"@VERSION@\"" | MeCabバージョンを設定するマクロです。 |
| -DPACKAGE="\"mecab\""  | パッケージ名を設定するマクロです |
| -DUNICODE | |
| -D_UNICODE | |
| -DMECAB_DEFAULT_RC="\"c:\\Program Files\\mecab\\etc\\mecabrc\""　 | mecabarcのパスを設定するマクロです。 |

LDFLAGS:
 link.exe （リンカー）のフラグです。

| フラグ名                   | 意味                                  |
|:--------------------------|:--------------------------------------|
| /nologo                   | 開始メッセージを表示しません。           |
| /OPT:REF                  | 参照されない関数とデータを排除します。   |
| /OPT:ICF                  | ICF イテレーション を使用します。       |
| /LTCG                     | リンク時のコード生成を指定します。       |
| /NXCOMPAT                 | Windows データ実行防止機能との互換性が確認済みとして実行可能ファイルをマークします。 |
| /DYNAMICBASE              | アドレス空間レイアウトのランダム化 (ASLR) 機能を使用して、読み込み時に再配置される実行可能イメージを生成するかどうかを指定します。 |
| /MACHINE:X86 ADVAPI32.LIB | ターゲット プラットフォームを指定します。 |

#3. MeCabのVisualStudio2019用プロジェクト

　libmecab.dll のVisualStudio 2019 のプロジェクトの設定のうち、上記フラグを反映する部分を以下に示します。

・構成プロパティー詳細
　文字セットを「設定なし」とします。 
![2021-08-25 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/97a6ab83-8691-1dc4-f7d5-3c2a8b194a49.png)


・C/C++ ー 全般

以下を設定すると共に、追加のインクルードディレクトリに ..\inc を設定します。

|            | フラグ名   | 意味                                   |
|:-----------|:-----------|:--------------------------------------|
|著作権情報の非表示| /nologo    |  著作権メッセージを表示しない            |
|警告レベル| /W3        |  警告レベル３                           |


![2021-08-25 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/9e4dc72d-3347-32eb-97bc-adfd05baff1b.png)

・C/C++ ー 最適化
　構成に応じた最適化フラグを設定します。

|              | フラグ名   | 意味                                   |
|:-------------|:-----------|:--------------------------------------|
|最適化(Debug)  | /Od        | 無効                                  |
|最適化(Release)| /O2        | 最大限の最適化 (速度を優先)             |

![2021-08-25 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/94ddedf9-1497-e6ba-b97c-446383db323e.png)

・C/C++ ー プリプロセッサ
　構成がDebugのとき、プリプロセッサの定義は以下としてください。WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;MECAB_USE_THREAD;DLL_EXPORT;HAVE_GETENV;HAVE_WINDOWS_H;DIC_VERSION=102;VERSION="\"@VERSION@\"";PACKAGE="\"mecab\"";UNICODE;_UNICODE;MECAB_DEFAULT_RC="\"c:\\Program Files (x86)\\mecab\\etc\\mecabrc\"";%(PreprocessorDefinitions) 

　構成がRelease の時は以下です。
WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;MECAB_USE_THREAD;DLL_EXPORT;HAVE_GETENV;HAVE_WINDOWS_H;DIC_VERSION=102;VERSION="\"@VERSION@\"";PACKAGE="\"mecab\"";MECAB_DEFAULT_RC="\"c:\\Program Files\\mecab\\etc\\mecabrc\"";%(PreprocessorDefinitions)

![2021-08-25 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/471e867e-6d3f-3a83-9d53-7d556fe89a8b.png)

・C/C++ ー コード生成

|                    | フラグ名   | 意味                                   |
|:-------------------|:-----------|:--------------------------------------|
|C++の例外を有効にする| /EHsc      | extern "C" は既定の nothrow になる     |
|ランタイムライブラリ(Debug)| /MDd  |  マルチスレッドデバッグDLL             |
|ランタイムライブラリ(Release)| /MD  |  マルチスレッドDLL                   |

![2021-08-25 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/1fe708ae-e9d3-b1eb-2575-9aa6a7897241.png)

・C/C++ ー プリコンパイル済みヘッダー
　「プリコンパイル済みヘッダ―を使用しない」に設定します。

![2021-08-25 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/b2cc16f1-c3ff-02f1-7fd7-0f2ce8dd0331.png)

・C/C++ ー 詳細設定
　呼び出し規約は、__cdecl としてください。

![2021-08-25 (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/e903b2fd-1b51-3e7f-869a-86da08ce48ad.png)

・リンカー　－　全般

|                    | フラグ名                   | 意味                                  |
|:--|:--------------------------|:--------------------------------------|
|著作権情報の非表示| /nologo                   | 開始メッセージを表示しません。           |

![2021-08-25 (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/0730011d-c126-723a-860f-ef989939a74a.png)

・リンカー　－　詳細設定

| 　　　　　　　　　　　　　　　| フラグ名                   | 意味                                  |
|:--------------------------|:--------------------------|:--------------------------------------|
|ランダム化されたベースアドレス| /DYNAMICBASE              | アドレス空間レイアウトのランダム化 (ASLR) 機能を使用して、読み込み時に再配置される実行可能イメージを生成するかどうかを指定します。 |
|データ実行防止(DEP)| /NXCOMPAT                 | Windows データ実行防止機能との互換性が確認済みとして実行可能ファイルをマークします。 |
|対象コンピュータ| /MACHINE:X86 ADVAPI32.LIB | ターゲット プラットフォームを指定します。 |

![2021-08-25 (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266273/3bd6b545-9054-5f4d-d486-29d2a1a2e719.png)

#3. 制限事項と現在の仕様
　・警告の4800,4305,4244 を抑止していないので、コンパイル時の警告が色々と出ますが気にしないでください。
　・c++ファイルとヘッダファイルは、mecab-0.996.tar.gz のままです。
　・Windows版のMeCabをインストールしていると、その辞書ファイルを読みに行きます。これはMeCabの仕様です。
　・このソリューションにも mecabrc （MeCabの設定ファイル）を含めています。libmecab.dll の相対パス ..\dic\ipadic を辞書ファイルとするように設定しています。
　・MeCabの辞書ファイルパスと辞書バージョンについては、別途記事が必要とおもいます。少々お待ちください。
　こちらに記事を作成しました。

 https://qiita.com/kenichiro_ayaki/items/c717a6d382afffc6e97f

　また、vb.net への移植版を過去に作成しました。よろしければこちらもお使いください。

 https://qiita.com/kenichiro_ayaki/items/bd65dbcff46b50460811