CMakeで作るようにした既存のVisualStudioプロジェクトに、GoogleTestを追加する

# 概要
既存のCMakeで構築するVisualStudio Projectに対して、GoogleTestを追加してみます。
既存プロジェクトとしては
[CMakeを使って、FreeRTOS最小構成のVisualStudioプロジェクト作る](https://qiita.com/azuki_bar/items/fc7ee06dad935a466779)
を使います。

[Google Test勉強録 (1) CMakeでのビルド](https://qiita.com/ktrmnm/items/667a7b7c93cd3fb78419)　が洗練されていると思いますが、
ここではGoogle Testでビルドしたlibを自分のプロジェクト内に置きます。

# Google Testをプロジェクトに追加する
## Google Testのダウンロード
https://github.com/google/googletest
からダウンロードする。
自身のプロジェクト内で管理するのでzipで落とす。

## ビルド
unzipしたgoogletestフォルダ内にbuildフォルダを作ってcmakeします。
buildフォルダをShift押しながら右クリックするとpowershellが開けるので便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/3c5e1bf4-0f61-6dca-b8b2-a521eb88bd54.png)
でpowershellを開いて
\> cmake ..
と入力する。

buildフォルダ内にできた `googletest-distribution.sln` を起動して、ビルドしましょう。Release, Debug両方しておきます。
ビルドが完了するとbuildフォルダ内にライブラリが生成されます。

```text:
|-- lib
|   |-- Debug
|   |   |-- gmock_maind.lib
|   |   |-- gmockd.lib
|   |   |-- gtest_maind.lib
|   |   `-- gtestd.lib
|   `-- Release
|       |-- gmock.lib
|       |-- gmock_main.lib
|       |-- gtest.lib
|       `-- gtest_main.lib
```
## 自身のプロジェクトに取り込む
プロジェクト直下にgtestフォルダを掘りました。
includeには、googletestのヘッダーファイルを置き、libフォルダにビルドしたlibを置きます。

```text:
Root
|-- CMakeLists.txt ※1
|-- ...
|-- gtest
|   |-- CMakeLists.txt ※2
|   |-- include
|   |   `-- gtest
|   |       |-- gtest.h
|   |       |-- gtest_pred_impl.h
|   |       |-- gtest_prod.h
|   |       |-- gtest-death-test.h
|   |       |-- gtest-matchers.h
|   |       |-- gtest-message.h
|   |       |-- gtest-param-test.h
|   |       |-- gtest-printers.h
|   |       |-- gtest-spi.h
|   |       |-- gtest-test-part.h
|   |       |-- gtest-typed-test.h
|   |       `-- internal
|   |           |-- custom
|   |           |   |-- gtest.h
|   |           |   |-- gtest-port.h
|   |           |   |-- gtest-printers.h
|   |           |   `-- README.md
|   |           |-- gtest-death-test-internal.h
|   |           |-- gtest-filepath.h
|   |           |-- gtest-internal.h
|   |           |-- gtest-param-util.h
|   |           |-- gtest-port.h
|   |           |-- gtest-port-arch.h
|   |           |-- gtest-string.h
|   |           `-- gtest-type-util.h
|   |-- lib
|   |   |-- gmock_maind.lib
|   |   |-- gmockd.lib
|   |   |-- gtest_maind.lib
|   |   `-- gtestd.lib
```

## CMake対応
### ※1のCMakeLists.txtの修正
#### gtestの追加

```cmake
`add_subdirectory(./gtest)`
```

####  unicode形式のWarning
自分のプロジェクトにあるFreeRTOSファイルで発生したのエラー。（Warningをコンパイルエラーとしている）

> 重大度レベル	コード	説明	プロジェクト	ファイル	行	抑制状態
警告	C4819	ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
重大度レベル	コード	説明	プロジェクト	ファイル	行	抑制状態
エラー	C2220	次の警告はエラーとして処理されます	gtest_main	F:\git-work\cmake_freertos_visualstudio_gtest\FreeRTOS\Source\include\task.h	2065

UTF-8になのが問題
http://tech.hikware.com/article/20171020a.html
を参考にして、CMakeList.txtに`add_definitions(/source-charset:utf-8)`を追加。

```
if (MSVC)
    add_definitions(/source-charset:utf-8)
endif()
```

で、ほぼ解消しましたが、なぜか1つだけWarningが残ってしまった。。
とりあえず、Warningにはするが、コンパイルエラーとはしない対応にした。

```cmake
if (MSVC)
    # warning level 4 and all warnings as errors
    add_compile_options(/W4 /WX-)
else()
    # lots of warnings and all warnings as errors
    add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()
```

↓の設定と同じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/ab88bb85-2eb6-c708-b5c7-8d426c159e4a.png)


### 「RuntimeLibrary' の不一致が検出されました」の対応
https://sgry.jp/blog/2017/05/27/4465/
で解決できた

```cmake:
# 
if(MSVC)
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_DEBUG            ${CMAKE_C_FLAGS_DEBUG})
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_MINSIZEREL       ${CMAKE_C_FLAGS_MINSIZEREL})
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE          ${CMAKE_C_FLAGS_RELEASE})
    string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO   ${CMAKE_C_FLAGS_RELWITHDEBINFO})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_DEBUG          ${CMAKE_CXX_FLAGS_DEBUG})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_MINSIZEREL     ${CMAKE_CXX_FLAGS_MINSIZEREL})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE        ${CMAKE_CXX_FLAGS_RELEASE})
    string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
endif(MSVC)
```

↓の設定と同じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/b235d52a-deb6-ec26-a6ef-76a98468154a.png)

### ※2のCMakeLists.txtの修正

```
cmake_minimum_required(VERSION 3.1)

# lib方式.
include_directories(./include)  # #include "gtest/gtest.h"をするため
...  ※あとのincludeは自身のプロジェクトに合わせる

link_directories(./lib) # Google Testのライブラリをリンク
add_executable(TestSample1 test_sample1.cpp test_freertos.c)

target_link_libraries(TestSample1
 $<TARGET_OBJECTS:freertos>)
target_link_libraries(TestSample1 debug gtestd)      #Debugモード時のリンク
target_link_libraries(TestSample1 optimized gtest)   #Releaseモード時のリンク
```

※gtest.libをDebugモードですると
>重大度レベル	コード	説明	プロジェクト	ファイル	行	抑制状態
エラー	LNK2038	'_ITERATOR_DEBUG_LEVEL' の不一致が検出されました。値 '0' が 2 の値 'test_sample1.obj' と一致しません。	TestSample1	F:\git-work\cmake_freertos_visualstudio_gtest\build\test\gtest.lib(gtest-all.obj)	1	

となります。
https://ja.stackoverflow.com/questions/9699/debug%E7%89%88%E3%81%A8release%E7%89%88%E3%81%A7%E5%90%8C%E3%81%98lib%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95
にあるように別にする必要があります。（Debug時はgtestd.libを使う）