MSYS2 + CMake で GoogleTest を導入する

# MSYS2 のインストール
1. https://www.msys2.org/ から、https://github.com/msys2/msys2-installer/releases/download/2022-09-04/msys2-x86_64-20220904.exe をダウンロードする
1. インストーラーを起動して、`C:\msys2` にインストールする（基本的に、サイトの手順通りにすれば良い）
1. 自動的に MSYS MINGW64 が起動する

# ツールのインストール
次のコマンドを実行して必要なツールをインストールします。

```
$ pacman -S --needed mingw-w64-x86_64-gcc
$ pacman -S --needed git mingw-w64-x86_64-cmake
```

執筆時点では、以下のバージョンが入りました。

```
$ g++ --version
g++.exe (Rev1, Built by MSYS2 project) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cmake --version
cmake version 3.24.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).

$ git --version
git version 2.37.2
```

# CMake プロジェクトの作成
例として、ソースファイルのディレクトリー構成を以下の様にします。

* test
  * test_something.cpp
* CMakeLists.txt

[Google Test 公式の CMake のサンプル](https://google.github.io/googletest/quickstart-cmake.html) と、[CMake の FetchContent モジュールの例](https://cmake.org/cmake/help/latest/module/FetchContent.html)を参考に、`CMakeLists.txt` を以下のようにしました。

```CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(example_gtest)

# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 14)

include(FetchContent)
FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        release-1.12.1
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()

add_executable(
  example_gtest
  test/test_something.cpp
)
target_link_libraries(
  example_gtest
  gtest_main
)

include(GoogleTest)
gtest_discover_tests(example_gtest)
```

テストコードです。

```test_something.cpp
#include "gtest/gtest.h"

TEST(HelloTest, BasicAssertions) {
  EXPECT_EQ(1 + 1, 3);
}
```


ちなみに、GoogleTest は `FetchContent_Declare` を以下のようにするのが好みで、

```
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
```

CMake は以下のようにするのが好みのようですが、

```
FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)
```

好きなやり方で良いでしょう。

なお、執筆時点での GoogleTest の最新バージョンは 1.12.1 でした。

# テストの実行
まずビルドします。

```sh
$ cmake -S . -B build
-- Building for: Ninja
-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Python: C:/Program Files/Python310/python.exe (found version "3.10.6") found components: Interpreter
-- Configuring done
-- Generating done
-- Build files have been written to: C:/msys64/home/mitayuki6/gtest-example/build

$ cmake --build build
[1/10] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.obj
[2/10] Building CXX object CMakeFiles/example_gtest.dir/test/test_something.cpp.obj
[3/10] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.obj
[4/10] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.obj
[5/10] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.obj
[6/10] Linking CXX static library lib\libgtest.a
[7/10] Linking CXX static library lib\libgtest_main.a
[8/10] Linking CXX static library lib\libgmock.a
[9/10] Linking CXX static library lib\libgmock_main.a
[10/10] Linking CXX executable example_gtest.exe
```

テストを実行します。

```
$ (cd build && ctest --output-on-failure)
Test project C:/msys64/home/mitayuki6/gtest-example/build
    Start 1: HelloTest.BasicAssertions
1/1 Test #1: HelloTest.BasicAssertions ........***Failed    0.01 sec
Running main() from C:/msys64/home/mitayuki6/gtest-example/build/_deps/googletest-src/googletest/src/gtest_main.cc
Note: Google Test filter = HelloTest.BasicAssertions
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from HelloTest
[ RUN      ] HelloTest.BasicAssertions
C:/msys64/home/mitayuki6/gtest-example/test/test_something.cpp:4: Failure
Expected equality of these values:
  1 + 1
    Which is: 2
  3
[  FAILED  ] HelloTest.BasicAssertions (0 ms)
[----------] 1 test from HelloTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] HelloTest.BasicAssertions

 1 FAILED TEST


0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.02 sec

The following tests FAILED:
          1 - HelloTest.BasicAssertions (Failed)
Errors while running CTest
```

ちゃんとエラーを検出してくれました！
続いて、修正してみます。

```test_something.cpp
#include "gtest/gtest.h"

TEST(HelloTest, BasicAssertions) {
  EXPECT_EQ(1 + 1, 2);
}
```

```
$ cmake --build build
[1/2] Building CXX object CMakeFiles/example_gtest.dir/test/test_something.cpp.obj
[2/2] Linking CXX executable example_gtest.exe

$ (cd build && ctest --output-on-failure)
Test project C:/msys64/home/mitayuki6/gtest-example/build
    Start 1: HelloTest.BasicAssertions
1/1 Test #1: HelloTest.BasicAssertions ........   Passed    0.01 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.02 sec
```

問題なさそうです。