Mosquitto を Windows でビルドする

# Mosquittoとは
[Mosquitto](https://mosquitto.org/)は[Eclipse Foundation](https://www.eclipse.org/org/foundation/)によってオープンソースで開発されている[MQTT](https://mqtt.org/)(Message Queue Telemetry Transport)の実装です。
MQTTはPub/Sub型のメッセージングプロトコルで、他のメッセージングプロトコルと比べて軽量なため、IoTの分野でよく使われています。

# 前提条件
[GitHub](https://github.com/eclipse/mosquitto/)に[コンパイルのためのREADME](https://github.com/eclipse/mosquitto/blob/v2.0.12/README-compiling.md)と[WindowsのためのREADME](https://github.com/eclipse/mosquitto/blob/v2.0.12/README-windows.txt)があるのですが、ビルドの__手順__は書かれていませんでした。
以下の環境を用いてSSL、マルチスレッドを有効にしてビルドしました。

- Windows 10 Pro 21H1 64bit
- Mosquitto v2.0.12
- Visual Studio 2019 Community Edition Version 16.11.3
- CMake 3.21.3
- OpenSSL 1.1.1L
- Pthreads 2.9.1

# 事前準備
Mosquittoのビルドに必要な開発環境、ライブラリをインストールします。

- Visual Studio 2019
  インストーラに従ってインストールします。「C/C++によるデスクトップ開発」にチェックを入れます。

- CMake
  Visual Studio付属のCMakeではソリューションを生成できません。[公式](https://cmake.org/)からダウンロードしてインストールします。

- OpenSSL
  OpenSSLの公式ではソースしか配布していません(libがありません)。バイナリを配布しているサイトはいくつかあるのですが、Mosquittoでは[Shining Light Productions版](https://slproweb.com/products/Win32OpenSSL.html)でしかビルドが通りません。Win64 OpenSSL(Liteが付かない方)をダウンロードしてインストールします。

- Pthreads
  MosquittoはWindowsのネイティブスレッドに対応していません([Issue 1509](https://github.com/eclipse/mosquitto/issues/1509))。そのため、[PthreadsのWindows版](ftp://sourceware.org/pub/pthreads-win32)をダウンロードしてインストールします。[CMakeLists.txt](https://github.com/eclipse/mosquitto/blob/v2.0.12/CMakeLists.txt)を見ると、C:\pthreadsに配置する前提になっているので合わせるとよいでしょう。Windows版の名前はPthreads for Win32ですが、x64でビルドできます。

# Mosquittoのビルド
### ソリューションファイルの生成
CMakeでVisual Studioのソリューションファイルを生成します。

```
cd C:\path\to\mosquitto
cmake . -DOPENSSL_ROOT_DIR="C:\path\to\OpenSSL-Win64"
```

### プロジェクトファイルの修正
生成されたmosquitto.slnをVisual Studioで開きます。(まだビルドしません)

- struct型の再定義を修正します
  - 「libmosquitto」プロジェクトを右クリックして「プロパティ」を開きます
  - 「構成プロパティ」-「C/C++」-「プリプロセッサ」に **HAVE_STRUCT_TIMESPEC** を追加します。Debug、Releaseともに修正するとよいでしょう

      ![libmosquitto.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23358/fd268f90-c5a7-bf61-7ffa-af651920f720.png)

- ソースコードに含まれる"∞"を扱えるように修正します
  - 「mosquitto_pub」「mosquitto_rr」「mosquitto_sub」プロジェクトをまとめて選択して右クリック、プロパティを開きます
  - 「構成プロパティ」-「C/C++」-「コマンドライン」に **/utf-8** を追加します。Debug、Releaseともに修正するとよいでしょう。

      ![mosquitto_pub_rr_sub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23358/f3534ad7-593a-0c1f-3e75-acf0475bc5f9.png)

### ソリューションのビルド
「ビルド」-「ソリューションのビルド」でビルドします。以下のフォルダにEXEとDLLが出力されます

```
src\{Debug,Release}
  mosquitto.exe
lib\{Debug,Release}
  mosquitto.dll
client\{Debug,Release}
  mosquitto_pub.exe
  mosquitto_rr.exe
  mosquitto_sub.exe
```

# 動作確認

### DLLの配置

mosquitto.exeと同じ場所に以下のDLLをコピーします。

- OpenSSLのDLL
  - libssl-1_1-x64.dll、libcrypto-1_1-x64.dll

mosquitto_sub.exe、mosquitto_rr.exe、mosquitto_pub.exeと同じ場所に以下のDLLをコピーします。

- OpenSSLのDLL
  - libssl-1_1-x64.dll、libcrypto-1_1-x64.dll、
- PthreadsのDLL
  - pthreadVC2.dll
- Mosquitto本体のDLL
  - mosquitto.dll

### Mosquittoの実行
コマンドプロンプトを複数立ち上げて、Mosquittoを実行します。

```console:Broker
mosquitto -v
```
```console:Subscriber
mosquitto_sub -d -h localhost -p 1883 -t test_topic
```
```console:Publisher
mosquitto_pub -d -h localhost -p 1883 -t test_topic -m "test message"
```

Subscriberに **test message** が表示されれば成功です。