CMake で msvc と mingw-w64 向けにビルドをする

CMake で、共通のソースと CMakeLists.txt を使って msvc と mingw-w64 向けにビルドをすることができます。

msvcの開発には Visual Studio 2022 Community を入れてください。
mingw(g++) 開発に必要な環境は、scoop (https://scoop.sh/) で mingw-winlibs を入れることで整います。

* mingw-winlibs (gcc, g++, cmake, make, mingw32-make, ninja 等が入ります)
* msvc および g++ のビルドに必要な cmake にもパスが自動的に通ります(scoop で mingw-winlibs をインストールすることで)。

----

以下のように CMake を使うことでいくつかメリットがあります：

* Visual Studio 2022 がインストールされていれば、vcvarsall.bat 等で cl.exe や nmake.exe にパスを通しておかなくてもビルドできる(g++ や ninja はパスが通ってないといけませんが、scoop で mingw-winlibs を入れることで自動的にパスが通ります)
* build フォルダを自分で作ったり、cd したりしなくて済む。
* コンパイラを指定してあげることで、間違ったコンパイラでコンパイルしようとしてしまう問題を回避できる。

```batch:vc2022.cmd
rmdir /s /q build
cmake -G "Visual Studio 17 2022" -A "x64" -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -B build -S .
cmake --build build --config Release
```

```batch:mingw64.cmd
rmdir /s /q build
cmake -G "Ninja" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -B build -S .
cmake --build build --config Release
```

上記の2つのコマンドを使い分けることで、同じ CMakeLists.txt で g++ と msvc 用にビルドできます。
ビルドディレクトリを別々にするのも一つの手ですね。

```
if (MSVC)
    ...
else()
    ...
endif()
```

・・・を使って msvc と g++ で異なる設定をしなければならないこともあると思います。
以下にサンプルの CMakeLists.txt を張り付けておきます。(参考になれば)

```text:CMakeLists.txt のサンプル
cmake_minimum_required(VERSION 3.5)

project(main LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CompilerFlags
        CMAKE_CXX_FLAGS
        CMAKE_CXX_FLAGS_DEBUG
        CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_MINSIZEREL
        CMAKE_CXX_FLAGS_RELWITHDEBINFO
        CMAKE_C_FLAGS
        CMAKE_C_FLAGS_DEBUG
        CMAKE_C_FLAGS_RELEASE
        CMAKE_C_FLAGS_MINSIZEREL
        CMAKE_C_FLAGS_RELWITHDEBINFO
        )
foreach(CompilerFlag ${CompilerFlags})
    string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
    set(${CompilerFlag} "${${CompilerFlag}}" CACHE STRING "msvc compiler flags" FORCE)
    message("MSVC flags: ${CompilerFlag}:${${CompilerFlag}}")
endforeach()

if (MSVC)
    set(BOOST_ROOT "C:/ProgramData/.software/boost-vc")
else()
    add_link_options("-static")
    set(BOOST_ROOT "C:/ProgramData/.software/boost")
endif()
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
find_package(Boost REQUIRED COMPONENTS atomic chrono container context contract coroutine date_time exception fiber filesystem graph headers iostreams json locale log log_setup math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l nowide prg_exec_monitor program_options python random regex serialization stacktrace_noop stacktrace_windbg stacktrace_windbg_cached system test_exec_monitor thread timer type_erasure unit_test_framework url wave wserialization)

include_directories("C:/ProgramData/.repo/home/common/include")
include_directories("C:/ProgramData/.repo/home/common/.cpp/include")
link_directories("C:/ProgramData/.repo/home/common/.cpp/lib")
link_libraries(".cpp")
include_directories(${Boost_INCLUDE_DIRS})
link_libraries(${Boost_LIBRARIES})
if (MSVC)
    include_directories("C:/ProgramData/.software/wxWidgets-vc/include")
    include_directories("C:/ProgramData/.software/wxWidgets-vc/lib/vc_x64_lib/mswu")
    link_directories("C:/ProgramData/.software/wxWidgets-vc/lib/vc_x64_lib")
else()
    include_directories("C:/ProgramData/.software/wxWidgets/include")
    include_directories("C:/ProgramData/.software/wxWidgets/lib/gcc_lib/mswu")
    link_directories("C:/ProgramData/.software/wxWidgets/lib/gcc_lib")
endif()

link_libraries(wxexpat wxmsw32u wxpng wxscintilla wxzlib wxjpeg wxmsw32u_gl wxregexu wxtiff ole32 uuid shlwapi comctl32 uxtheme oleacc version comdlg32 winspool oleaut32 gdi32 shell32 rpcrt4 user32 advapi32)

include_directories(C:/ProgramData/.software/zulu17-jdk/include C:/ProgramData/.software/zulu17-jdk/include/win32)

file(GLOB SRCS "*.cpp")
add_executable(mainC ${SRCS})
```

それでは！