MongoDB C++ Driverのビルド(windows)

mongoDBをC++のアプリから使うためのライブラリである`mongocxx`と `bsoncxx`をビルドしてインストールする。
手順は[公式](http://mongocxx.org/mongocxx-v3/installation/)を元に進めた。

##環境
* windows8.1(64bit)
* Visual Studio Community 2017
* cmake 3.9.0

##手順
### mongoDB C Driver
mongocxx driverは**mongoDB C Driver**に依存しているのでまずそちらをインストールする。方法は[公式](http://mongoc.org/libmongoc/current/installing.html)を参考にした。筆者も別に[記事](https://qiita.com/exp/items/c82a4f4807c579d3a847)を書いている。
ここでは`C:\mongo-c-driver`に`bin`や`include`などが入るようにインストールされたと想定する。

### Boost
mongocxx driverはC++17の機能を使っている。C++17を使わずにコンパイルするにはwindowsでは**Boost**を使うとのこと。
**Boost**のインストールは別の記事に書く予定。(※[ここ](https://qiita.com/exp/items/f9be7b4029476ce5b2fe)に書いた)
ここでは`C:\local\boost_1_69_0`に`include`と`lib`が入るようにインストールしたと想定する。

##mongocxx
最終的にインストールされるものはヘッダファイルや`.dll`。
適当な場所にソースをクローンする

```language:powershell
git clone https://github.com/mongodb/mongo-cxx-driver.git --branch releases/stable --depth 1
cd mongo-cxx-driver/build
```

VisualStudio2017でビルドするように設定

* ここでは最終的にライブラリが`C:\mongo-cxx-driver`にインストールされる。
* **DBOOST_ROOT**に指定するBoostのパスに注意。**includeの中**にあるboost-1_69を指定する。
* ちなみに最初VisualStudio2015でやってみたが、`No CMAKE_CXX_COMPILER could be found.`
となって失敗。C++がインストールされていないということで再インストールするも上手くいかなかった。


```language:powershell
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=C:\mongo-cxx-driver -DCMAKE_PREFIX_PATH=C:\mongo-c-driver -DBOOST_ROOT=C:\local\boost_1_69_0\include\boost-1_69 ..
```

ビルド

```language:powershell
msbuild.exe ALL_BUILD.vcxproj
```

>75 個の警告
 0 エラー
 経過時間 00:05:18.93

警告は
>warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。

みたいな感じだった。未解決だがそのまま進めた。
インストール

```language:powershell
msbuild.exe INSTALL.vcxproj
```

> ビルドに成功しました。
     0 個の警告
     0 エラー
経過時間 00:00:10.03

以上でインストールされた。

##インストールされたか検証
###プロジェクト作成
適当な場所にVisualC++の`win32コンソールアプリケーション`のプロジェクトを作る。

筆者は知らなかったが、[こちら](https://imagingsolution.net/program/opencv/no-opencv-dll-file/)によると`.dll`は、

>1. アプリケーション(*.exe)と同じフォルダ
2. カレントディレクトリ
3. システムディレクトリ（C:\Windows\System32 など）
4. 16Bitシステムディレクトリ（C:\Windows\System など）
5. Windowsディレクトリ（C:\Windows など）
6. PATH環境変数に列挙されているディレクトリ

のような場所に置かないと認識してくれない。
今回は`.vcproj`があるフォルダと同じ階層に必要な`.dll`を入れた。
コピー元のフォルダと必要なファイルは次のとおり。

**C:\mongo-cxx-driver\bin**
`bsoncxx.dll`
`mongocxx.dll`

**C:\mongo-cxx-driver\lib**
`bsoncxx.lib`
`mongocxx.lib`

**C:\mongo-c-driver\bin**
`libbson-1.0.dll`
`libmongoc-1.0.dll`

**binで共通なファイル**
`concrt140.dll`
`msvcp140.dll`
`vcruntime140.dll`

（`.lib`はスタティックリンクライブラリらしい。ないとエラーになる）

###プロジェクト設定
VisualStudioの**[プロジェクト->プロパティ]**から、次を設定する。
**環境**
`PATH=c:/mongo-c-driver/bin`
**追加のライブラリディレクトリ**
`C:\mongo-cxx-driver\lib`
`C:\mongo-c-driver\lib`
`C:\local\boost_1_69_0\lib`
**追加のインクルードディレクトリ**
`C:\mongo-cxx-driver\include\mongocxx\v_noabi`
`C:\mongo-cxx-driver\include\bsoncxx\v_noabi`
`C:\local\boost_1_69_0\include\boost-1_69`
`C:\mongo-c-driver\include\libmongoc-1.0`
`C:\mongo-c-driver\include\libbson-1.0`
**追加の依存ファイル**
`bsoncxx.lib`
`mongocxx.lib`
`mongoc-1.0.lib`
`bson-1.0.lib`

###コード
**testdb**に**testcollection**を作成して、**hello:world**というドキュメントをインサートするコード。
**実行前にmongoDBがインストールされていて、デフォルト（localhost:27017）で起動していること。**

```c++:ConsoleApplication.cpp
#include "stdafx.h"
#include <iostream>
 
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
 
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>

#include <mongoc/mongoc.h>
 
int main(int, char**) {
    mongocxx::instance inst{};
    mongocxx::client conn{ mongocxx::uri{} };
 
    bsoncxx::builder::stream::document document{};
 
    auto collection = conn["testdb"]["testcollection"];
    document << "hello" << "world";
 
    collection.insert_one(document.view());
    auto cursor = collection.find({});
 
    for (auto&& doc : cursor) {
        std::cout << bsoncxx::to_json(doc) << std::endl;
    }
    Sleep(10000);
}

```


###実行
mongoDBの起動はこんな感じ(mongodコマンドのある場所(C:\Program Files\MongoDB\Server\4.0\binなど)にパスが通っている)

```language:powershell
mongod --dbpath c:\data\db
```

VisualStudioで上記の検証コードを実行
>{ "_id" : { "$oid" : "5c7f9d78cf5f0000e9004d62" }, "hello" : "world" }

あとは**MongoDB Compass**等で確かにインサートされたか確認する。