Visual Studio 2022 を用いて CMake プロジェクトから Boost 1.81.0 を利用


Visual Studio 2022 を使用して C++ のプロジェクトを CMake で作成する方法を紹介しています。今回は find_package() によって Boost C++ Libraries ([https://www.boost.org/](https://www.boost.org/)) を利用するやり方を報告します。

# 環境
* 開発環境として、Visual Studio 2022（Community）の「C++デスクトップ環境」がインストールされていること。
* Git for Windows（[https://gitforwindows.org/](https://gitforwindows.org/) ）もしくは互換ソフトがインストールされ、コマンドラインから git が使用できること。[^1]
* CMake (最新版を推奨）がインストールされ、コマンドラインから cmake が実行できること。[^2]
* 環境変数の設定ができること。[^3]
* コマンドラインでの作業には「Developer Command Prompt for VS 2022」を使用すること。[^4]
[^1]: Git from the command line and also from 3rd-party software にチェックを入れてインストールする。
[^2]: [https://cmake.org/](https://cmake.org/)  にある Latest Release の Windows x64 Installer を実行して 「Add CMake to the system PATH for all users」にチェックを入れてインストールする。
[^3]: 環境変数は、設定の「システム」＞「バージョン情報」＞「システムの詳細設定」から変更できます。```> set``` で環境変数の一覧が見れるので、設定が反映されていない場合には一旦 Windows からサインアウトしてサインインし直してください。
[^4]: スタートメニューの「Visual Studio 2022」フォルダ内にショートカットがあります。「ターミナル」の設定を変更し、「既定のプロファイル」に「Developer Command Prompt for VS 2022」を登録しておくと、エクスプローラーで作業するディレクトリを開き、コンテキストメニューから「ターミナルで開く」ことができて便利です。

# ディレクトリ構成
この記事では、ダウンロードしたソース、コンパイルされたライブラリなどは c:\dev にいれることにします。これは任意の場所に変更することができます。
```
dev/
├── boost
    ├── include
        ├── boost-1_81
    ├── lib
├── make
    ├── boost-1.81.0
```
* ソースコードは c:\dev\make\boost-1.81.0 にダウンロードします。
* c:\dev\boost にビルドしたライブラリがインストールされます。
* インストール後、 c:\dev\make\boost-1.81.0 は削除できます。サイズが大きいので削除することを推奨します。

# Boost のインストール
ディレクトリ ```C:\dev\make``` がなければ作成し、Developer Command Prompt for VS 2022 で以下を実行する。
```DOS
> cd \dev\make
> git clone --depth 1 --recursive --shallow-submodules https://github.com/boostorg/boost -b boost-1.81.0 boost-1.81.0 
> cd boost-1.81.0
> .\bootstrap.bat
> .\b2 link=static threading=multi runtime-link=shared address-model=64 cxxflags="/utf-8" --prefix=c:\dev\boost install
```
```b2``` で指定したオプションの意味を以下に示す。
* ```link=static``` 静的ライブラリを作成する。ライブラリにパスを通す必要がないので簡単。好みで変更して良い。
* ```threading=multi runtime-link=shared``` Visual C++ のデフォルトのリンク方式である "/MD" に合わせる。
* ```address-model=64``` ライブラリは x64 が主流なので合わせる。
* ```cxxflags="/utf-8"``` インストール時に一部のライブラリで警告がでるのを避ける。指定しなくても問題はない。

# 環境変数の設定
次のうちいずれかを行う。上にある設定が優先される。
* 環境変数 ```BOOST_ROOT``` に ```c:\dev\boost``` を設定する。
* 環境変数 ```Boost_DIR``` に ```c:\dev\boost\lib\cmake\Boost-1.81.0``` もしくは `c:\dev` を設定する。
* 環境変数 `CMAKE_PREFIX_PATH` に ```c:\dev``` を設定する。
* 環境変数 `Path` に `c:\dev\bin` を追加する。

 
# ライブラリの使用方法
## ヘッダファイルのみのライブラリ
簡単な例で使い方を説明する。作業用の適当なディレクトリを用意して、以下の内容で ```lambda.cpp``` と ```CMakeLists.txt``` を作成する。
```lambda.cpp
#include <boost/lambda2.hpp>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <array>

int main() {
    using namespace boost::lambda2;

    std::array<int, 10> ar;
    std::iota(ar.begin(), ar.end(), 0);
    std::sort(ar.begin(), ar.end(), _1 > _2);

    for (int a : ar) {
        std::cout << a << ", ";
    }
    return 0;
}
```
```CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(test_boost CXX)

set(CMAKE_CXX_STANDARD 14)

find_package(Boost 1.81.0 REQUIRED COMPONENTS headers)

add_executable(lambda lambda.cpp)
target_link_libraries(lambda Boost::headers)
```
Developer Command Prompt から
```
> md build
> cd build
> cmake ..
```
とすることで Visual Studio のプロジェクトである ```build\lambda.proj``` とソリューションである ```build\test_boost.sln``` が作成される。いずれかを Visual Studio で開くことで IDE を用いた開発ができる。あるいは IDE を使わずに、コマンドラインから
```
> cmake --build . --config Release
> Release\lambda.exe
9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
```
としてコンパイル・実行することもできる。

## リンクが必要なライブラリ
リンクが必要なライブラリである Boost.Regex を使う例を示す。ビルドの仕方は同じなので省略する。
```regex.cpp
#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main() {
	// Search for regular expressions 
	boost::regex  r("{[^}]+}");
	boost::smatch m;
	std::string s1 = "x^2 + 2xy + y^2 = {x+y}^2  ";

	if (boost::regex_search(s1, m, r)) {
		std::cout << "found (pos=" << m.position() << ")" << std::endl;
		std::cout << m.str() << std::endl;
	}

	// Enclose the found numbers with {}
	boost::regex r2("[0-9]+");
	std::string s2 = "2023/03/23 16:00:15";

    std::cout << boost::regex_replace(
		s2, r2, "{$0}", boost::format_all) << std::endl;
	return 0;
}
```
```CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(test_cmake CXX)

set(CMAKE_CXX_STANDARD 14)

find_package(Boost 1.81.0 REQUIRED COMPONENTS regex)

add_executable(regex regex.cpp)
target_link_libraries(regex Boost::regex)
```