はじめに
前回の記事では、WSL2上のDocker EngineをVSCodeのDevContainerから使うC++環境を構築し、Hello Worldまで動かしました。
今回はそこからステップアップして、実際のプロジェクトで使える構成を整えます。
この記事でできること
- CMakeでプロジェクトを構成する
- vcpkgで外部ライブラリを管理する
- 以下の3ライブラリを導入して動作確認する
- fmt — モダンな文字列フォーマット
- Eigen — 行列・線形代数演算
- Google Test — ユニットテスト
シリーズ構成
| 回 | 内容 |
|---|---|
| 第1弾 | 環境構築 → Hello World |
| 第2弾(本記事) | CMake + vcpkg で本格プロジェクト |
| 第3弾 | C#編(.NET + DevContainer) |
完成後のフォルダ構成
hello-cpp/
├── .devcontainer/
│ └── devcontainer.json
├── src/
│ └── main.cpp
├── tests/
│ └── test_main.cpp
├── CMakeLists.txt
└── vcpkg.json
Step 1: devcontainer.jsonを更新する
前回のdevcontainer.jsonに変更を加えます。
{
"name": "C++ Development",
"image": "mcr.microsoft.com/devcontainers/cpp:1-ubuntu-24.04",
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cmake-tools",
"xaver.clang-format"
],
"settings": {
"editor.formatOnSave": true
}
}
},
"postCreateCommand": "gcc --version && cmake --version && vcpkg --version"
}
前回からの変更点
-
postCreateCommandにvcpkgのバージョン確認を追加しました
補足:
mcr.microsoft.com/devcontainers/cppイメージにはvcpkgがあらかじめ/usr/local/vcpkgにインストールされています。追加のセットアップは不要です。vcpkgのバージョンは以下の通りです。vcpkg package management program version 2025-07-21-d4b65a2b83ae6c3526acd1c6f3b51aff2a884533
Step 2: vcpkg.jsonを作成する
プロジェクトルートに vcpkg.json を作成します。
これがvcpkgの「依存関係定義ファイル」で、npmの package.json に相当するものです。
{
"name": "hello-cpp",
"version": "0.1.0",
"dependencies": [
"fmt",
"eigen3",
"gtest"
]
}
CMakeのビルド時にvcpkgが自動でこのファイルを読み取り、必要なライブラリをダウンロード・ビルドします。
Step 3: CMakeLists.txtを作成する
プロジェクトルートに CMakeLists.txt を作成します。
各行にコメントで意味を説明します。
# CMakeの最低バージョンを指定(3.21以上でvcpkgのManifestモードが安定して動く)
cmake_minimum_required(VERSION 3.21)
# プロジェクト名とバージョン、使用言語を宣言
project(hello-cpp VERSION 0.1.0 LANGUAGES CXX)
# C++23を使用する
set(CMAKE_CXX_STANDARD 23)
# C++23に非対応のコンパイラでエラーにする(黙って古い規格にフォールバックさせない)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# vcpkgがインストールしたパッケージを検索できるようにする
# find_package() がvcpkgのインストール先を参照するために必要
find_package(fmt CONFIG REQUIRED)
find_package(Eigen3 CONFIG REQUIRED)
find_package(GTest CONFIG REQUIRED)
# ===== メインの実行ファイル =====
# src/main.cpp からビルドする実行ファイル名を "hello" とする
add_executable(hello src/main.cpp)
# hello に必要なライブラリをリンクする
# PRIVATE = helloの内部実装だけで使う(外部に公開しない)という意味
target_link_libraries(hello
PRIVATE
fmt::fmt # fmtライブラリ
Eigen3::Eigen # Eigenライブラリ(ヘッダオンリーなのでリンクはシンボリック)
)
# ===== テスト =====
# CTestを有効化する(cmake --build後に ctest コマンドでテストを実行できるようになる)
enable_testing()
# tests/test_main.cpp からビルドするテスト実行ファイル名を "hello_test" とする
add_executable(hello_test tests/test_main.cpp)
# hello_test に必要なライブラリをリンクする
target_link_libraries(hello_test
PRIVATE
GTest::gtest_main # Google Testのmain関数込みのライブラリ
Eigen3::Eigen
fmt::fmt
)
# hello_test をCTestに登録する
# これにより ctest コマンドでGoogle Testのテストが実行される
include(GoogleTest)
gtest_discover_tests(hello_test)
Step 4: ソースファイルを作成する
src/main.cpp
fmt・Eigenの動作確認を兼ねたサンプルです。
#include <iostream>
#include <fmt/core.h>
#include <Eigen/Dense>
int main() {
// fmtによる文字列フォーマット
fmt::print("Hello, {}!\n", "fmt");
// Eigenによる行列演算
Eigen::Matrix2d A;
A << 1, 2,
3, 4;
Eigen::Matrix2d B;
B << 5, 6,
7, 8;
Eigen::Matrix2d C = A * B;
fmt::print("\nA =\n{}\n", A); // Eigenの行列はそのままfmtで出力できる
fmt::print("\nB =\n{}\n", B);
fmt::print("\nA * B =\n{}\n", C);
return 0;
}
tests/test_main.cpp
Google Testによるサンプルテストです。
#include <gtest/gtest.h>
#include <Eigen/Dense>
#include <fmt/core.h>
// 行列乗算の結果を検証するテスト
TEST(EigenTest, MatrixMultiplication) {
Eigen::Matrix2d A;
A << 1, 2,
3, 4;
Eigen::Matrix2d B;
B << 5, 6,
7, 8;
Eigen::Matrix2d C = A * B;
// 期待値と比較(行列の各要素を検証)
EXPECT_DOUBLE_EQ(C(0, 0), 19.0);
EXPECT_DOUBLE_EQ(C(0, 1), 22.0);
EXPECT_DOUBLE_EQ(C(1, 0), 43.0);
EXPECT_DOUBLE_EQ(C(1, 1), 50.0);
}
// fmtの動作確認テスト
TEST(FmtTest, FormatString) {
std::string result = fmt::format("Hello, {}!", "world");
EXPECT_EQ(result, "Hello, world!");
}
Step 5: DevContainerを再ビルドして起動する
devcontainer.json を変更したので、コンテナを再ビルドします。
- VSCodeの左下のリモートメニュー(
><アイコン)をクリック - コンテナーのリビルド を選択
完了したらターミナルでvcpkgが使えることを確認します。
vcpkg --version
vcpkg package management program version 2025-07-21-d4b65a2b83ae6c3526acd1c6f3b51aff2a884533
vcpkgはイメージに組み込み済みのため、追加のインストールなしですぐに使えます。
Step 6: ビルドして実行する
ビルド
# ビルドディレクトリを作成してcmakeを実行
cmake -B build -DCMAKE_TOOLCHAIN_FILE=/usr/local/vcpkg/scripts/buildsystems/vcpkg.cmake
# ビルド実行
cmake --build build
-DCMAKE_TOOLCHAIN_FILE はvcpkgのライブラリ検索パスをCMakeに伝えるためのオプションです。
メインプログラムの実行
./build/hello
Hello, fmt!
A =
1 2
3 4
B =
5 6
7 8
A * B =
19 22
43 50
テストの実行
ctest --test-dir build --output-on-failure
Internal ctest changing into directory: /workspaces/hello-cpp/build
Test project /workspaces/hello-cpp/build
Start 1: EigenTest.MatrixMultiplication
1/2 Test #1: EigenTest.MatrixMultiplication ... Passed 0.01 sec
Start 2: FmtTest.FormatString
2/2 Test #2: FmtTest.FormatString ............. Passed 0.01 sec
100% tests passed, 0 tests failed out of 2
Total Test time (real) = 0.05 sec
全テストがPassedになれば完了です。
まとめ
| 項目 | 内容 |
|---|---|
| ビルドシステム | CMake 3.21以上 |
| パッケージマネージャ | vcpkg(Manifestモード) |
| 導入ライブラリ | fmt / Eigen / Google Test |
| C++規格 | C++23 |
vcpkgの Manifestモード(vcpkg.json で依存を管理する方式)を使うことで、プロジェクトごとにライブラリのバージョンを独立して管理できます。
チームで開発する場合も vcpkg.json をGitで共有するだけで全員が同じライブラリを使えるのが大きなメリットです。
次回予告
第3弾 では、同じDevContainerの仕組みを使ってC#(.NET)の開発環境を作ります。