C++のためのvcpkgとCMake(Linux)

# はじめに
　本記事はライブラリを簡単に使用するためvcpkgの使い方を紹介します。また、C++のコンパイルを簡単化するため、vcpkgを絡めてCMakeの使い方を紹介します。

# vcpkgとは
　vcpkgはMicrosoft社が開発したC++のライブラリ管理ツールです。このツールを使用するとプロジェクトに使用するさまざまなライブラリをインストールし、管理することができます。多くはVisualStudioのために使われますが、本記事はLinuxでの使用法を説明します。

# CMakeとは
　CMakeはクロスプラットフォームのビルド自動化ツールです。CMkaeはプロジェクトのソースコードを解析し、適切なビルド手順を生成するため、ビルド手順の記述が簡単であり、プラットフォーム間の移植性が高いという特徴を持ちます。

# ディレクトリ構成

　本記事は提示するコマンドをプロジェクトのルートディレクトリで実行し続ければ、以下のようなディレクトリ構成となります。

```
ProjectRoot/
├── build/
├── vcpkg/
├── CMakeLists.txt
├── main.cpp
├── vcpkg-configuration.json
└── vcpkg.json
```

# デモンストレーションの準備
　本記事ではvcpkgとCMakeの使い方を説明するため、デモンストレーションのコードを用意します。以下がそのコードです。このコードは[vcpkgのチュートリアル](https://learn.microsoft.com/en-us/vcpkg/get_started/get-started?pivots=shell-bash)から引用しています。

 ```c++:main.cpp
#include <fmt/core.h>

int main()
{
    fmt::print("Hello World!\n");
    return 0;
}
 ```

# インストール方法
## vcpkgのインストール
　vcpkgをインストールを行い、ブートストラップを実行します。

 ```
git clone https://github.com/microsoft/vcpkg.git
./vcpkg/bootstrap-vcpkg.sh
 ```

## CMakeのインストール
　aptのアップデートを行った後、CMakeをインストールします。

 ```
sudo apt update
sudo apt install cmake
 ```

# vcpkgの使い方
## 環境変数の定義

　まずはvcpkgを使用するため臨時の環境変数を定義するためコマンドを実行します。
　この環境変数はセッション中のみ有効ですので気を付けてください。

```
export VCPKG_ROOT=./vcpkg
export PATH=$VCPKG_ROOT:$PATH
```

## マニュフェストファイルの作成
　マニフェストファイル（manifest file）は、ソフトウェアを動作させるために必要な設定や資源についての情報を記述したファイルです。 次のコマンドで自動的に作成されます。

 ```
vcpkg new --application
 ```

　vcpkg-configuration.jsonとvcpkg.jsonの2ファイルが生成されます。

## ライブラリのインストール

　vcpkgを使用してライブラリをインストールしてみましょう。
　例としてfmtのライブラリをインストールします。

```
vcpkg add port fmt
```

　コマンドの実行に成功すると、vcpkg.jsonファイル内fmtについての情報が追記されます。

# CMakeの使い方
## CMakeLists.txtの作成
　プロジェクトのルートディレクトリにCMakeLists.txtを作成します。以下はその例です。

```CMakeLists.txt
cmake_minimum_required(VERSION 3.16)

set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file")

project(HelloWorld CXX)

find_package(fmt CONFIG REQUIRED)

add_executable(HelloWorld main.cpp)

target_link_libraries(HelloWorld PRIVATE fmt::fmt fmt::fmt)
```

各行について解説します。

 ### cmake_minimum_required
 　cmake_minimum_requiredはCMakeの最小バージョンを指定します。このプロジェクトではCMakeバージョン3.16以上が必要です。

### project
　projectはプロジェクト名と使用するプログラム言語を設定します。このプロジェクトではプロジェクト名はHelloWorldとしています。CXXはC++言語を使用することを指定しています。

### find_package
　find_packageはパッケージを探索します。このプロジェクトで使用するライブラリはfmtですので、find_packageはfmtを指定しています。指定するための情報はほとんどのライブラリはGitHubのvcpkgリポジトリにあるportsディレクトリの対象ライブラリ内usageファイルに書いてあります。例えばfmtのusageは[このURL](https://github.com/microsoft/vcpkg/blob/master/ports/fmt/usage)から知れます。
　以下はfmtの場合のusageファイル内容です。

 ```usage
The package fmt provides CMake targets:

    find_package(fmt CONFIG REQUIRED)
    target_link_libraries(main PRIVATE fmt::fmt)

    # Or use the header-only version
    find_package(fmt CONFIG REQUIRED)
    target_link_libraries(main PRIVATE fmt::fmt-header-only)
 ```

### add_executable
　コンパイルするプログラムコードのファイル名とコンパイル後の実行可能ファイル名を指定します。

### target_lik_libraries
　ターゲットにvcpkgで解決されたライブラリをリンクします。この場合はfmt::fmtと書いてありますが、この語彙もfind_packageと同じく[usage](https://github.com/microsoft/vcpkg/blob/master/ports/fmt/usage)に書いてあるので、ライブラリをインストールする際はusageを確認しましょう。

### **追記**
　find_packageやtarget_link_librariesのライブラリを指定するキーワードの検索方法は最も簡単な方法を知ったので追記しておきます。ライブラリのインストールにて示したコマンドを実行した後、以下のコマンドを実行することでキーワードは表示されるようです。ちゃんと確認をしていませんが、情報元によると2回ほどコマンドを実行する必要があるようです。(私の環境では1回で問題ありませんでしたが…)

 ```
vcpkg install
 ```

https://stackoverflow.com/questions/64454052/how-to-retrieve-cmake-target-names-from-vcpkg

## CMakeの実行

　CMakeを実行します。

```
cmake -B build -S .
```

## ビルド

　CMakeによりビルドを行います。

```
cmake --build build
```

# HelloWorld

　以上でbuildディレクトリ内にHelloWorld実行可能ファイルが作成されます。
　実行して確認しましょう。

 ```
./build/HelloWorld
 ```

 　以下は結果です。

  ```
Hello World!
  ```

  # 参考
  
  https://learn.microsoft.com/en-us/vcpkg/get_started/get-started?pivots=shell-bash

  https://github.com/microsoft/vcpkg/tree/master/ports

  https://github.com/miredirex/cmake-vcpkg-example/tree/master