- 技術 💻
CMakeとは?使い方とCMakeLists.txtの書き方|実測とエラー原文つき
結論
CMakeは、CMakeLists.txt に書いた「何をどう作るか」から、Make や Ninja などのビルド用ファイルを作るツールです。コンパイルそのものはしません。使い方は cmake -S . -B build → cmake --build build → ctest の3つが基本です。
この記事でわかること
- 実行ファイル・ライブラリ・テストを含む CMakeLists.txt の書き方と、各コマンドの出力
- Debug と Release の速さの差(手元で約17倍)と、Ninja と Make の差の実測
- 「CMake Error at…」「Could NOT find…」「Compatibility with CMake < 3.5」などのエラー原文と直し方
CMake は「設計図からビルドの手順書を作る係」です。実際にコンパイラを呼ぶのは、CMake が作った手順書を読む Make や Ninja です。
flowchart TD
A[CMakeLists.txt<br>何をどう作るか] --> B[cmake -S . -B build<br>構成 configure]
B --> C[build/Makefile か<br>build/build.ninja]
C --> D[cmake --build build<br>make や ninja が動く]
D --> E[g++ / clang / MSVC<br>コンパイルとリンク]
E --> F[実行ファイル・ライブラリ]
F --> G[ctest でテスト<br>cmake --install で配置]
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| CMakeとは | C/C++ のビルド設定を OS やコンパイラに依存しない形で書き、Make・Ninja・Visual Studio 用のファイルを作るツール | CMakeとは |
| CMakeの使い方(最短) | cmake -S . -B build、cmake --build build、ctest --test-dir build |
CMakeの使い方 |
| CMakeLists.txt の書き方 | cmake_minimum_required → project → add_executable / add_library → target_link_libraries | CMakeLists.txtの書き方 |
| ヘッダーが見つからない | target_include_directories を PUBLIC で付け、target_link_libraries でつなぐ | target_link_libraries |
| 外部ライブラリを使う | find_package で探し、ZLIB::ZLIB のようなターゲット名でリンク |
find_package |
| Debug と Release の違い | Release は -O3。手元の計算は 3,360ms → 202ms | DebugとReleaseの違い |
| Ninja と Make どちら | 迷ったら Ninja(変更なしの再ビルドが 103ms → 23ms) | NinjaとMakeの違い |
| Compatibility with CMake < 3.5 のエラー | CMake 4 で削除された。cmake_minimum_required の数字を 3.5 以上に上げる | CMake 4の最低バージョンエラー |
確認環境:Ubuntu 24.04.5 LTS(2 CPU)の上で、apt で入っている CMake 3.28.3、GCC 13.3.0(g++)、GNU Make 4.3、Ninja 1.11.1 を使いました。CMake 4 の挙動は、作業用の Python 仮想環境に PyPI の cmake パッケージ(CMake 4.4.4)を入れて確かめています。題材は自作の小さな C++17 プロジェクト(ライブラリ mathx・実行ファイル calc・テスト2本、zlib を使用)で、configure・build・ctest・install、5種類のビルドタイプ、Unix Makefiles・Ninja・Ninja Multi-Config の3つのジェネレーター、CMakePresets.json、FetchContent(手元の tar.gz を指定)を動かしました。比較のため、同じプロジェクトを手書きの Makefile と Meson 1.12.1 でもビルドしています。並列数は -j2 です。Windows・macOS と Visual Studio は CMake 公式サイトと Microsoft Learn、Bazel は公式ドキュメントで確かめた範囲です。出力の中の作業フォルダーのパスは /work に置き換えています。図は mermaid 11.16.0 で描画を確かめています(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「CMakeとは?使い方とCMakeLists.txtの書き方|実測とエラー原文つき」
CMakeとは(Makeとの違い・何をするツールか)
この節では、CMake が何をするツールで、Make とどう役割が分かれているのかが分かります。
CMake は「ビルドシステムを作るためのツール」です。公式ドキュメントでも、CMake はプロジェクトのビルド方法を記述し、ネイティブのビルドツール(Make・Ninja・Visual Studio など)用のファイルを生成するもの、と説明されています。C/C++ のコードを直接コンパイルするのは、生成されたファイルを読む Make や Ninja、その先のコンパイラです。
Make だけで書く場合は、コンパイラの名前・オプション・OS ごとの違い(ライブラリの拡張子 .a と .lib など)を Makefile に自分で書き分けます。CMake では「calc という実行ファイルを main.cpp から作り、mathx と zlib をリンクする」という意図だけを書き、OS やコンパイラに合わせた具体的なコマンドは CMake が作ります。
CMake がすること
CMakeLists.txt を読み、コンパイラを見つける
外部ライブラリ(zlib など)の場所を探す
Makefile・build.ninja・Visual Studio のプロジェクトを作る
Make・Ninja がすること
変更のあったファイルだけをコンパイルする
依存の順番どおりにリンクする
並列でコンパイラを呼ぶ(-j2 など)
CMake は Kitware 社が中心のオープンソースで、LLVM・OpenCV・llama.cpp などのビルドに使われています。Visual Studio・CLion・VS Code(CMake Tools 拡張)が CMakeLists.txt を直接開けるのも利点です。
| 比べる点 | Makefile を直接書く | CMake |
|---|---|---|
| 書くもの | コマンドそのもの(g++ -O3 -c …) | ターゲットと依存関係 |
| Windows(MSVC) | 別に書き直しが要る | 同じ CMakeLists.txt で Visual Studio 用を生成 |
| 外部ライブラリ探し | パスを手で書く・pkg-config を呼ぶ | find_package で探す |
| ヘッダーの依存追跡 | -MMD -MP と -include を自分で書く | 自動 |
| テスト・インストール | ターゲットを自分で書く | ctest・cmake --install が付いてくる |
Makefile そのものの書き方は、関連記事「Makefileの書き方|自動変数一覧とタスクランナー用テンプレート」で扱っています。この記事は C/C++ のビルド設定としての CMake に絞ります。
CMakeのインストールとバージョン確認(Windows・Mac・Linux)
この節では、OS ごとの CMake の入れ方と、入ったかどうかの確かめ方が分かります。
入ったかどうかは cmake --version で確かめます。手元の Ubuntu 24.04 では apt の版が 3.28.3、PyPI の版が 4.4.4 でした。
$ cmake --version
cmake version 3.28.3
CMake suite maintained and supported by Kitware (kitware.com/cmake).
$ ~/venv/bin/cmake --version
cmake version 4.4.4
2026年10月29日時点で、公式サイトの最新リリースは 4.4.5、候補版は 4.5.0-rc2 です。OS ごとの入れ方は次のとおりです(Windows・macOS は公式のダウンロードページで提供形式を確かめた範囲です)。
| OS | 入れ方 | 注意 |
|---|---|---|
| Windows | 公式の .msi インストーラー(x64・ARM64)か .zip。Visual Studio の「C++ によるデスクトップ開発」にも CMake が含まれる | インストーラーで PATH に追加する選択肢を選ぶ |
| macOS | 公式の .dmg か tar.gz(Universal)。Homebrew なら brew install cmake |
.dmg 版は CMake.app。コマンドを使うには PATH の設定が要る |
| Ubuntu・Debian | sudo apt install cmake |
OS の版に合わせた少し前の版になる(24.04 は 3.28) |
| Linux で最新版 | 公式の .sh か tar.gz を展開 | 展開先の bin を PATH に足す |
| どの OS でも | pip install cmake(PyPI) |
仮想環境に入れるとプロジェクトごとに版を固定できる |
「'cmake' は内部コマンドまたは外部コマンドとして認識されていません」(Windows)や cmake: command not found(Linux・Mac)は、CMake の bin フォルダーが PATH に入っていないときの表示です。PATH の考え方は関連記事「Linux環境変数PATHの設定方法|exportと.bashrcの使い分け早見表」で扱っています。Windows で Linux と同じ手順を使いたい場合は、関連記事「WSL2環境構築|Ubuntu開発環境をコマンドだけで整える手順」の環境に apt で入れる方法もあります。
CMakeの使い方:configure・build・testの3コマンド
この節では、CMake でビルドするときの基本の流れと、各コマンドで実際に何が出力されるのかが分かります。
CMake の操作は「構成(configure)」「ビルド」「テスト」の3段です。ソースと生成物を分けるため、ビルド用のフォルダー(ここでは build)を -B で指定します。これを out-of-source ビルドと呼びます。
構成する:cmake -S . -B build
-S はソース(CMakeLists.txt のある場所)、-B はビルド用フォルダー。コンパイラの検出、find_package、Makefile の生成までを行う。
ビルドする:cmake --build build -j2
中で make か ninja が動く。make と直接打っても同じだが、cmake --build ならジェネレーターを問わず同じ書き方で済む。
テストする:ctest --test-dir build
add_test で登録したテストを順に動かす。失敗したときは --output-on-failure を付けると中身が見える。
必要なら配置する:cmake --install build --prefix 先
install() で指定したファイルを決まった場所にコピーする。
手元のプロジェクトで構成したときの出力です。コンパイラの種類と版、見つかった zlib の場所が分かります。
$ cmake -S . -B build
-- The CXX compiler identification is GNU 13.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.3")
-- Configuring done (1.3s)
-- Generating done (0.0s)
-- Build files have been written to: /work/proj/build
続けてビルドすると、ライブラリ → テスト → 実行ファイルの順に、依存の順番を守って作られます(2つずつ並列)。
$ cmake --build build -j2
[ 16%] Building CXX object CMakeFiles/mathx.dir/src/mathx.cpp.o
[ 33%] Linking CXX static library libmathx.a
[ 33%] Built target mathx
[ 50%] Building CXX object CMakeFiles/calc.dir/app/main.cpp.o
[ 66%] Building CXX object CMakeFiles/test_mathx.dir/tests/test_mathx.cpp.o
[ 83%] Linking CXX executable test_mathx
[ 83%] Built target test_mathx
[100%] Linking CXX executable calc
[100%] Built target calc
$ ./build/calc 1000
2+3=5
primes<=1000: 168
time_ms: 0
zlib 1.3.1.zlib-ng
ソースのフォルダーで cmake . と打つと、生成物がソースと混ざります。手元で試すと、CMakeCache.txt・CMakeFiles・Makefile・cmake_install.cmake・CTestTestfile.cmake の5つがソースの横にできました。消すときに間違えやすく、Git の管理も面倒になるため、ビルド用フォルダーを分けます。
$ ls
CMakeLists.txt app include src tests
$ cmake .
$ ls
CMakeCache.txt CMakeFiles CMakeLists.txt CTestTestfile.cmake Makefile
app cmake_install.cmake include src tests
ほかによく使うコマンドを表にまとめます。どれも手元で動かしたものです。
| やりたいこと | コマンド | メモ |
|---|---|---|
| 1つのターゲットだけ作る | cmake --build build --target calc |
依存する mathx も作られる |
| 実際のコンパイルコマンドを見る | cmake --build build --verbose |
-I や -O の付き方を確かめるときに使う |
| 生成物を消す | cmake --build build --target clean |
キャッシュは残る |
| キャッシュから作り直す | cmake --fresh -S . -B build |
3.24 以降。フォルダーごと消しても同じ |
| 設定値の一覧 | cmake -L build |
-LH で説明つき |
| 使えるジェネレーター | cmake --help の最後 |
Linux の既定は Unix Makefiles |
| ターゲットの一覧 | cmake --build build --target help |
Makefile 生成時。all・clean・install・test など |
CMakeLists.txtの書き方(実行ファイル・ライブラリ・テスト)
この節では、実行ファイル・ライブラリ・テスト・インストールを含む CMakeLists.txt を、1行ずつ意味が分かる形で書けるようになります。
題材のフォルダー構成です。ライブラリ(mathx)と、それを使う実行ファイル(calc)と、テスト(test_mathx)があります。
proj/
├── CMakeLists.txt
├── include/mathx/mathx.hpp … 公開するヘッダー
├── src/mathx.cpp … ライブラリの本体
├── app/main.cpp … 実行ファイル
└── tests/test_mathx.cpp … テスト
CMakeLists.txt の全文です(30行)。この1ファイルで、ここまでの出力すべてが作られています。
cmake_minimum_required(VERSION 3.20)
project(calc VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# ライブラリ
add_library(mathx src/mathx.cpp)
target_include_directories(mathx PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
# 実行ファイル
add_executable(calc app/main.cpp)
target_link_libraries(calc PRIVATE mathx)
# 外部ライブラリ(zlib)
find_package(ZLIB REQUIRED)
target_link_libraries(calc PRIVATE ZLIB::ZLIB)
# テスト
enable_testing()
add_executable(test_mathx tests/test_mathx.cpp)
target_link_libraries(test_mathx PRIVATE mathx)
add_test(NAME add_works COMMAND test_mathx add)
add_test(NAME primes_works COMMAND test_mathx primes)
# インストール
install(TARGETS calc mathx)
install(DIRECTORY include/ DESTINATION include)
| 命令 | 意味 | 書き忘れると |
|---|---|---|
cmake_minimum_required |
この版以上の CMake を求め、その版の動き(ポリシー)にそろえる | 警告が出る。必ず1行目に書く |
project |
プロジェクト名・版・言語(CXX は C++) | コンパイラが検出されない |
CMAKE_CXX_STANDARD |
C++ の規格(17 なら -std=gnu++17 が付いた) | コンパイラの既定の規格になる |
add_library |
ライブラリを作る(既定は静的 .a) | ― |
add_executable |
実行ファイルを作る | ― |
target_include_directories |
ヘッダーを探す場所をターゲットに付ける | No such file or directory |
target_link_libraries |
リンクするライブラリと、ヘッダーの場所などをまとめて引き継ぐ | undefined reference |
enable_testing・add_test |
ctest で動かすテストを登録する | No tests were found |
install |
cmake --install でコピーするものを決める | 何もコピーされない |
-std=gnu++17 になったのは、CMAKE_CXX_EXTENSIONS の既定が ON だからです。 GCC の拡張を使わず -std=c++17 にそろえたい場合は、set(CMAKE_CXX_EXTENSIONS OFF) を足します。compile_commands.json で確かめた、Release のときの実際のコマンドは次のとおりでした。
/usr/bin/c++ -I/work/proj/include -O3 -DNDEBUG -std=gnu++17 -o CMakeFiles/calc.dir/app/main.cpp.o -c /work/proj/app/main.cpp
CMakeLists.txt を書くときに見直す点をまとめます。
- 11行目が cmake_minimum_required かCMake 4 では 3.5 未満がエラー。手元の版に近い数字にする
- 2設定は target_ で始まる命令で書いたかinclude_directories などフォルダー全体に効く命令は避ける
- 3PUBLIC・PRIVATE を考えたかヘッダーで使うなら PUBLIC、.cpp の中だけなら PRIVATE
- 4外部ライブラリは :: 付きの名前でリンクしたかZLIB::ZLIB など。ヘッダーの場所も一緒に付く
- 5-O3 や -g を手で書いていないかCMAKE_BUILD_TYPE に任せる
- 6ビルド用フォルダーを .gitignore に入れたかbuild/・out/ をコミットしない
target_link_librariesとinclude_directoriesの違い(PUBLIC・PRIVATE)
この節では、target_link_libraries と include_directories・target_include_directories の違いと、PUBLIC・PRIVATE・INTERFACE の使い分けが分かります。
今の CMake では、設定を「ターゲット」に付け、target_link_libraries で引き継ぐのが基本です。 mathx に PUBLIC で付けたヘッダーの場所は、target_link_libraries(calc PRIVATE mathx) と書いた calc にも自動で渡ります。これを公式ドキュメントでは「使用要件(usage requirements)」と呼んでいます。
| 指定 | 自分に効く | リンクした側に渡る | 使う場面 |
|---|---|---|---|
PRIVATE |
はい | いいえ | .cpp の中でだけ使う |
PUBLIC |
はい | はい | 公開ヘッダーの中で使う |
INTERFACE |
いいえ | はい | ヘッダーだけのライブラリ |
手元で、わざと2通りに壊して確かめました。まず target_link_libraries(calc PRIVATE mathx) を消すと、リンクの前にコンパイルで止まりました。ヘッダーの場所(-I)も target_link_libraries で渡っていたためです。コンパイルのコマンドに -I が無いことが分かります。
FAILED: CMakeFiles/calc.dir/app/main.cpp.o
/usr/bin/c++ -std=gnu++17 -MD -MT CMakeFiles/calc.dir/app/main.cpp.o -MF CMakeFiles/calc.dir/app/main.cpp.o.d -o CMakeFiles/calc.dir/app/main.cpp.o -c /work/p2/app/main.cpp
/work/p2/app/main.cpp:5:10: fatal error: mathx/mathx.hpp: No such file or directory
5 | #include "mathx/mathx.hpp"
| ^~~~~~~~~~~~~~~~~
compilation terminated.
ninja: build stopped: subcommand failed.
次に、以前の書き方の include_directories(include) だけを足してリンクを書かないと、今度はコンパイルは通り、リンクで undefined reference になりました。ヘッダー(宣言)は見つかっても、中身(定義)の入った libmathx.a がリンクされていないためです。
FAILED: calc
: && /usr/bin/c++ CMakeFiles/calc.dir/app/main.cpp.o -o calc /usr/lib/x86_64-linux-gnu/libz.so && :
/usr/bin/ld: CMakeFiles/calc.dir/app/main.cpp.o: in function `main':
main.cpp:(.text+0x62): undefined reference to `mathx::count_primes(unsigned long)'
/usr/bin/ld: main.cpp:(.text+0x9a): undefined reference to `mathx::add(int, int)'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
避けたい書き方と、その代わりをまとめます。
ヘッダーの場所
include_directories() でフォルダー全体に足すtarget_include_directories(mathx PUBLIC …)そのフォルダーの全ターゲットに効き、どこで要るのかが分からなくなる
最適化のオプション
set(CMAKE_CXX_FLAGS "-O3") を CMakeLists.txt に書く-DCMAKE_BUILD_TYPE=Release を構成時に渡すDebug でビルドしたいときにも -O3 が付いてしまう
ソースの列挙
file(GLOB SRCS src/*.cpp) だけで集めるCONFIGURE_DEPENDS を付ける)ファイルを足しても構成し直すまで気づかれない。公式ドキュメントも GLOB でのソース収集は勧めていない
ビルドの場所
cmake .cmake -S . -B build生成物がソースに混ざり、Debug と Release を並べて持てない
find_packageで外部ライブラリを使う(FetchContentも)
この節では、find_package で外部ライブラリを探す仕組みと、見つからないときのエラーの読み方、FetchContent で取り込む方法が分かります。
find_package は、ライブラリの場所を探し、ZLIB::ZLIB のような「インポートされたターゲット」を作ります。あとは自分のターゲットと同じく target_link_libraries でつなぐだけで、ヘッダーの場所とライブラリのファイルが両方付きます。探し方には2通りあります。
Module モード(FindXXX.cmake)
CMake に付いてくる探し方の台本を使う
ZLIB・Threads・OpenSSL など
失敗すると「Could NOT find XXX」
Config モード(XXXConfig.cmake)
ライブラリ側が配る設定ファイルを読む
fmt・Qt6・最近の多くのライブラリ
失敗すると「Could not find a package configuration file」
手元で、入っていないライブラリを探させたときの原文です。Boost は Module モード(3.28 では FindBoost.cmake)で探され、ヘッダーが無いことが missing: の後に出ます。
CMake Error at /usr/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find Boost (missing: Boost_INCLUDE_DIR filesystem)
Call Stack (most recent call first):
/usr/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-3.28/Modules/FindBoost.cmake:2393 (find_package_handle_standard_args)
CMakeLists.txt:3 (find_package)
fmt のように Find モジュールが無いものは Config モードで探され、探したファイル名と直し方が書かれた長いエラーになります。
CMake Error at CMakeLists.txt:3 (find_package):
By not providing "Findfmt.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "fmt", but
CMake did not find one.
Could not find a package configuration file provided by "fmt" with any of
the following names:
fmtConfig.cmake
fmt-config.cmake
Add the installation prefix of "fmt" to CMAKE_PREFIX_PATH or set "fmt_DIR"
to a directory containing one of the above files. If "fmt" provides a
separate development package or SDK, be sure it has been installed.
直し方は「開発用パッケージを入れる」か「入れた場所を教える」の2つです。Ubuntu なら libboost-filesystem-dev や libfmt-dev のように末尾が -dev のパッケージにヘッダーと設定ファイルが入っています(手元では Boost の実行用ライブラリだけが入っていて、ヘッダーが無いため失敗しました)。自分で別の場所に入れた場合は -DCMAKE_PREFIX_PATH=/opt/fmt か -Dfmt_DIR=…/lib/cmake/fmt を渡します。Windows では vcpkg などのパッケージマネージャーと組み合わせる方法が Microsoft Learn で案内されています。
ライブラリをソースごと取り込むなら FetchContent です。ネットワークに出ないよう、手元で作った tar.gz を file:// で指定して試しました(ふつうは https の URL か Git のリポジトリを書きます)。
cmake_minimum_required(VERSION 3.24)
project(app LANGUAGES CXX)
include(FetchContent)
FetchContent_Declare(greet
URL file:///work/greet-1.0.tar.gz
URL_HASH SHA256=f2f4d9604389fa2db0041646c09dc695dc86853c34074ccc48abaac74e5a8efb
DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
FetchContent_MakeAvailable(greet)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE greet)
構成すると build/_deps に greet-src・greet-build・greet-subbuild の3つができ、hello, cmake と表示されました。URL_HASH を1文字変えると、取得したファイルを検証して止まります。取り込むものの中身が差し替わっていないかを確かめられるため、URL で取るときはハッシュを付けておくと安全です。
CMake Error at greet-subbuild/greet-populate-prefix/src/greet-populate-stamp/verify-greet-populate.cmake:29 (message):
error: SHA256 hash of
/work/greet-1.0.tar.gz
does not match expected value
expected: '00f4d9604389fa2db0041646c09dc695dc86853c34074ccc48abaac74e5a8efb'
actual: 'f2f4d9604389fa2db0041646c09dc695dc86853c34074ccc48abaac74e5a8efb'
FetchContent で取り込んで CMake でビルドする実例は、関連記事「llama.cppとは|使い方・ビルド・GGUF量子化とllama-server」の CMake でのビルド手順でも見られます。
ctestでテストを動かし、cmake --installで配置する
この節では、ctest の結果の読み方と、失敗したテストの中身の出し方、cmake --install で何がどこに入るのかが分かります。
ctest は add_test で登録したコマンドを動かし、終了コードが 0 なら Passed とします。テストの枠組み(GoogleTest など)が無くても、終了コードを返す実行ファイルがあれば使えます。
$ cd build && ctest
Test project /work/proj/build
Start 1: add_works
1/2 Test #1: add_works ........................ Passed 0.00 sec
Start 2: primes_works
2/2 Test #2: primes_works ..................... Passed 0.00 sec
100% tests passed, 0 tests failed out of 2
Total Test time (real) = 0.01 sec
テストの期待値をわざと 26 に変えて失敗させると、--output-on-failure を付けたときだけ、テストが出したメッセージ(expected 26, got 25)が表示されました。ctest の終了コードは 8 でした。CI では 0 以外を失敗として扱えます。
$ ctest --output-on-failure
Start 2: primes_works
2/2 Test #2: primes_works .....................***Failed 0.00 sec
expected 26, got 25
50% tests passed, 1 tests failed out of 2
The following tests FAILED:
2 - primes_works (Failed)
Errors while running CTest
| やりたいこと | コマンド |
|---|---|
| 名前で絞る | ctest -R primes |
| 失敗したものだけやり直す | ctest --rerun-failed --output-on-failure |
| 並列で動かす | ctest -j2 |
| ビルドフォルダーの外から | ctest --test-dir build |
| 構成を指定する(Visual Studio・Ninja Multi-Config) | ctest -C Release |
インストールは、install() に書いたものを --prefix の下に決まった形で並べます。bin・lib・include の振り分けは CMake が行います。
$ cmake --install build --prefix /work/inst
-- Install configuration: ""
-- Installing: /work/inst/bin/calc
-- Installing: /work/inst/lib/libmathx.a
-- Installing: /work/inst/include
-- Installing: /work/inst/include/mathx
-- Installing: /work/inst/include/mathx/mathx.hpp
1行目の Install configuration: "" は、ビルドタイプが空のままビルドしたという意味です。次の節のとおり、空のときは最適化が付きません。配る実行ファイルは Release で作ります。
DebugとReleaseの違い(サイズと速さを実測)
この節では、CMAKE_BUILD_TYPE の5つの値で付くオプションと、実行速度・ファイルサイズがどれだけ変わるのかが分かります。
CMAKE_BUILD_TYPE を指定しないと、-O も -g も付かないビルドになります。Makefile や Ninja のような「1つのフォルダーに1つの構成」のジェネレーターでは、構成時に -DCMAKE_BUILD_TYPE=Release を渡します。5つの値で同じプロジェクトをビルドし、compile_commands.json で付いたオプションを確かめ、エラトステネスのふるいで 3,000万以下の素数(1,857,859個)を数える時間を5回ずつ測りました。
| CMAKE_BUILD_TYPE | 付いたオプション | 時間(中央値) | calc の大きさ | libmathx.a |
|---|---|---|---|---|
| (指定なし) | なし | 3,069ms | 25,720B | 23,532B |
| Debug | -g | 3,360ms | 85,800B | 82,428B |
| Release | -O3 -DNDEBUG | 202ms | 16,888B | 2,456B |
| RelWithDebInfo | -O2 -g -DNDEBUG | 205ms | 85,856B | 82,424B |
| MinSizeRel | -Os -DNDEBUG | 557ms | 17,200B | 4,606B |
読み取れることは3つです。1つ目に、指定なしと Debug はどちらも最適化が無く、ほぼ同じ遅さでした。std::vector<bool> の添字アクセスのような小さな関数呼び出しが、最適化しないとそのまま残るためです。2つ目に、RelWithDebInfo は Release とほぼ同じ速さで、デバッグ情報のぶん大きくなります。本番でクラッシュしたときに関数名と行番号を追いたい場合に向きます。3つ目に、MinSizeRel は小さくなる代わりに Release より遅くなりました。
なお、最初に「割り算で素数を判定する」版で測ったときは、指定なし 669ms・Release 663ms でほとんど差が出ませんでした。時間のほとんどが CPU の割り算命令で、最適化で減らせる部分が少なかったためです。差の大きさはコードによって変わるため、自分のコードで測って判断します。
Visual Studio や Ninja Multi-Config のような「1つのフォルダーに複数の構成」を持つジェネレーターでは、構成時ではなくビルド時に --config で選びます。手元の Ninja Multi-Config では Debug・Release・RelWithDebInfo のフォルダーが並び、-C を付けずに ctest を動かすと次のように全テストが Not Run になりました。
$ cmake -S . -B mc -G "Ninja Multi-Config"
$ cmake --build mc --config Release -j2
[6/6] Linking CXX executable Release/test_mathx
$ cd mc && ctest
Test not available without configuration. (Missing "-C <config>"?)
1/2 Test #1: add_works ........................***Not Run 0.00 sec
$ ctest -C Release
100% tests passed, 0 tests failed out of 2
NinjaとMakeの違い(ジェネレーターの選び方)
この節では、CMake のジェネレーター(Unix Makefiles・Ninja)の違いと、どちらを選ぶかの目安が実測で分かります。
ジェネレーターは -G で選びます。Linux の既定は Unix Makefiles で、-G Ninja にすると build.ninja が作られます。CMakeLists.txt は同じまま切り替えられます。.cpp を81個に増やした練習用のプロジェクトで、両方を -j2 で比べました。
| 測ったもの | Unix Makefiles | Ninja |
|---|---|---|
| 構成(cmake -S -B) | 0.22〜0.27秒 | 0.19〜0.30秒 |
| 全体のビルド(2回) | 24.0秒・24.2秒 | 33.4秒・17.2秒 |
| 何も変えずに再ビルド(5回の中央値) | 103ms(83〜630ms) | 23ms(22〜27ms) |
| 1ファイルだけ変えて再ビルド | 0.63〜0.85秒 | 0.54〜0.55秒 |
差がはっきり出たのは「変更が少ないときの再ビルド」で、Ninja が約4分の1でした。全体のビルドは時間のほとんどがコンパイラで、手元は他の処理と CPU を分け合う環境だったため、Ninja の1回目は遅く、2回目は速いというばらつきが出ました。全体のビルドの速さでどちらが上かは、この測定からは言えません。毎日の開発では「少し直して再ビルド」を何百回も繰り返すため、そこが速い Ninja が向いています。
| 比べる点 | Unix Makefiles | Ninja |
|---|---|---|
| 入っているか | Linux・Mac ではたいてい入っている | 別に入れる(apt の ninja-build、pip の ninja など) |
| 並列数の既定 | 1(-j を付けないと1つずつ) | CPU の数をもとに自動で決まる |
| 進み具合の表示 | [ 50%] の割合 | [3/6] の件数。1行で上書き |
| 失敗したときの表示 | gmake: *** [Makefile:…] Error 1 | FAILED: の後にコマンド全文 |
| 複数構成 | 不可 | Ninja Multi-Config で可 |
同じビルド用フォルダーでジェネレーターを変えるとエラーになります。CMakeCache.txt に前のジェネレーターが記録されているためです。フォルダーを分けるか、消してから作り直します。
$ cmake -S . -B build -G Ninja
CMake Error: Error: generator : Ninja
Does not match the generator used previously: Unix Makefiles
Either remove the CMakeCache.txt file and CMakeFiles directory or choose a different binary directory.
CMakePresets.jsonで設定をそろえる
この節では、CMakePresets.json を使ってチームや CI と同じ構成・ビルド・テストを1語で呼び出す方法が分かります。
CMakePresets.json は、長い -G や -D の組み合わせに名前を付けてリポジトリに入れておくファイルです。Microsoft Learn でも、Visual Studio 2019 バージョン 16.10 以降で推奨される構成ファイルとされ、Visual Studio・VS Code・CI・コマンドラインから同じ設定でビルドできると説明されています。手元で使ったものです。
{
"version": 6,
"configurePresets": [
{
"name": "debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/debug",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" }
},
{
"name": "release",
"inherits": "debug",
"binaryDir": "${sourceDir}/out/release",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
}
],
"buildPresets": [
{ "name": "debug", "configurePreset": "debug" },
{ "name": "release", "configurePreset": "release" }
],
"testPresets": [
{ "name": "release", "configurePreset": "release", "output": { "outputOnFailure": true } }
]
}
$ cmake --list-presets
Available configure presets:
"debug"
"release"
$ cmake --preset release
Preset CMake variables:
CMAKE_BUILD_TYPE="Release"
CMAKE_EXPORT_COMPILE_COMMANDS="ON"
...
-- Build files have been written to: /work/proj/out/release
$ cmake --build --preset release -j 2
[6/6] Linking CXX executable test_mathx
$ ctest --preset release
100% tests passed, 0 tests failed out of 2
先頭の "version" は、読める CMake の版を決めます。公式ドキュメントでは、version 6 は CMake 3.25 以降(Workflow Presets を追加)、8 は 3.28 以降、10 は 3.31 以降です。チームの最も以前の CMake に合わせます。個人の設定(自分だけのコンパイラのパスなど)は CMakeUserPresets.json に書き、公式ドキュメントのとおりこちらはバージョン管理に入れません。
CMAKE_EXPORT_COMPILE_COMMANDS を ON にすると、ビルド用フォルダーに compile_commands.json ができます。VS Code の C/C++ 拡張や clangd が、これを読んでヘッダーの場所を正しく理解します。
CMakeのよくあるエラーと直し方(CMake Error at…の原文)
この節では、CMake でよく出るエラーの原文と、どこを直せばよいのかが分かります。
「CMake Error at CMakeLists.txt:3 (add_executable):」は、「CMakeLists.txt の3行目の add_executable で止まった」という意味です。まずファイル名・行番号・命令名を見て、その下の英文を読みます。Call Stack が付いているときは、いちばん下の行が自分の CMakeLists.txt です。エラーを読む順番は次のとおりです。
- 1どの段階か → CMake Error なら構成、FAILED や error: ならビルド構成のエラーは CMakeLists.txt、ビルドのエラーはソースかリンクの設定
- 2どこか → at ファイル名:行番号 (命令名)Call Stack はいちばん下が自分のファイル
- 3何が無いか → missing: や names: の後Boost_INCLUDE_DIR、fmtConfig.cmake など
- 4どう直すと書いてあるか → Add / Update / Tell CMake で始まる文CMake のエラーは直し方まで書いてあることが多い
- 5直らなければキャッシュを消す → cmake --fresh一度失敗した探し物の結果が CMakeCache.txt に残ることがある
手元で起こしたエラーを原文のまま並べます。
| 表示(原文) | 原因 | 直し方 |
|---|---|---|
| The source directory "…" does not appear to contain CMakeLists.txt. | -S の場所が違う・ファイル名の綴り違い | CMakeLists.txt(L は大文字・複数形の s)のあるフォルダーを指定 |
| Cannot find source file: main.cpp / No SOURCES given to target: app | add_executable に書いたファイルが無い | ファイル名とパス(CMakeLists.txt からの相対)を直す |
| Unknown CMake command "add_executible". | 命令名の打ち間違い | add_executable に直す |
| Could NOT find Boost (missing: Boost_INCLUDE_DIR filesystem) | 開発用パッケージ(ヘッダー)が無い | -dev パッケージを入れる・CMAKE_PREFIX_PATH を渡す |
| Could not find a package configuration file provided by "fmt" | Config ファイルが見つからない | 入れる。別の場所なら fmt_DIR を渡す |
| Cannot specify include directories for target "app" which is not built by this project. | add_executable より前に target_ 命令を書いた | ターゲットを作る行より後ろに移す |
| The CMAKE_CXX_COMPILER: /usr/bin/g++-99 is not a full path to an existing compiler tool. | コンパイラが無い・パス違い | g++ や clang を入れる。CXX 環境変数を見直す |
| CMake 3.30 or higher is required. You are running version 3.28.3 | 手元の CMake が、求められた版より前 | CMake を上げる(pip・公式の版) |
| Does not match the generator used previously | 同じフォルダーで -G を変えた | フォルダーを分けるか消す |
| fatal error: mathx/mathx.hpp: No such file or directory | -I が付いていない | target_include_directories と target_link_libraries |
| undefined reference to `mathx::add(int, int)' | ライブラリをリンクしていない | target_link_libraries を足す |
cmake_minimum_required を書かずに project() から始めると、次の警告が出ました。-Wno-dev で隠すより、1行目に cmake_minimum_required を足して直します。
CMake Warning (dev) at CMakeLists.txt:1 (project):
cmake_minimum_required() should be called prior to this top-level project()
call. Please see the cmake-commands(7) manual for usage documentation of
both commands.
This warning is for project developers. Use -Wno-dev to suppress it.
CMake 4の最低バージョンエラー(Compatibility with CMake < 3.5)
この節では、CMake 4 に上げたら以前のプロジェクトが構成できなくなるエラーの原因と、正しい直し方が分かります。
CMake 4.0 で、3.5 より前の版との互換性が削除されました。公式のリリースノートには「Compatibility with versions of CMake older than 3.5 has been removed.」とあり、cmake_minimum_required でそれより前の版を指定するとエラーになります。cmake_minimum_required(VERSION 2.8) と書いたプロジェクトを、2つの版で構成した結果です。
$ cmake --version # 3.28.3
$ cmake -S . -B b
CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
Compatibility with CMake < 3.5 will be removed from a future version of
CMake.
...
-- Configuring done (0.2s)
$ cmake --version # 4.4.4
$ cmake -S . -B b4
CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
Compatibility with CMake < 3.5 has been removed from CMake.
Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
to tell CMake that the project requires at least <min> but has been updated
to work with policies introduced by <max> or earlier.
Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try configuring anyway.
-- Configuring incomplete, errors occurred!
3.28 では警告(will be removed)、4.4 ではエラー(has been removed)です。apt の CMake で動いていたプロジェクトが、pip や Homebrew で新しい CMake に上がった途端に止まるのは、この違いのためです。
| 立場 | 直し方 | 手元の結果 |
|---|---|---|
| 自分のプロジェクト | cmake_minimum_required(VERSION 3.20) など、確かめた版に上げる |
エラーも警告も消えた |
| 新旧の CMake で動かしたい | cmake_minimum_required(VERSION 3.5...3.31) の範囲指定 |
公式のエラー文が勧める書き方 |
| 他人のプロジェクトを今すぐ構成したい | -DCMAKE_POLICY_VERSION_MINIMUM=3.5 を付ける |
構成は通り、3.10 未満の警告に変わった |
| 上の方法が使えない | CMake 3.x を pip で入れて使う | 例:pip install "cmake<4" |
CMAKE_POLICY_VERSION_MINIMUM は「とりあえず試す」ための逃げ道です。公式のリリースノートでも、パッケージを作る人や利用者が既存のプロジェクトを構成してみるために追加された、と説明されています。4.4.4 で付けて構成すると、今度は「Compatibility with CMake < 3.10 will be removed from a future version of CMake.」という警告が出ました。次の版でまた止まる可能性があるため、元のプロジェクトの cmake_minimum_required を直すのが本筋です。依存しているライブラリの側が以前の数字を書いている場合は、そのライブラリの新しい版に上げるか、作者に報告します。
Makefile直書き・Meson・Bazelとの判断表
この節では、CMake・Makefile を直接書く方法・Meson・Bazel のどれを選ぶかの目安が、同じプロジェクトを書き比べた結果と合わせて分かります。
同じプロジェクトを Makefile と Meson でも書き、ビルドとテストが通ることを確かめました。行数は、CMakeLists.txt が30行(コメント・空行込み)、Makefile が24行、meson.build が11行でした。Makefile は短く見えますが、ヘッダーの依存追跡(-MMD -MP)・テストの仕組み・インストール・Windows 対応を自分で書く必要があり、Makefile 版にはインストールも Windows 対応も入っていません。
$ make -j2
g++ -O3 -DNDEBUG -std=c++17 -Iinclude -MMD -MP -c -o app/main.o app/main.cpp
g++ -O3 -DNDEBUG -std=c++17 -Iinclude -MMD -MP -c -o src/mathx.o src/mathx.cpp
g++ -O3 -DNDEBUG -std=c++17 -Iinclude -MMD -MP -c -o tests/test_mathx.o tests/test_mathx.cpp
ar rcs libmathx.a src/mathx.o
g++ -o calc app/main.o libmathx.a -lz
g++ -o test_mathx tests/test_mathx.o libmathx.a
project('calc', 'cpp', version : '1.0.0',
default_options : ['cpp_std=c++17', 'buildtype=release'])
inc = include_directories('include')
mathx = static_library('mathx', 'src/mathx.cpp', include_directories : inc)
zdep = dependency('zlib')
executable('calc', 'app/main.cpp', include_directories : inc,
link_with : mathx, dependencies : zdep)
t = executable('test_mathx', 'tests/test_mathx.cpp',
include_directories : inc, link_with : mathx)
test('add_works', t, args : ['add'])
test('primes_works', t, args : ['primes'])
Meson は meson setup mb で zlib を pkg-config から見つけ(Run-time dependency zlib found: YES 1.3)、Ninja でビルドし、meson test で2本とも OK でした。Meson は Linux では Ninja でビルドします(--backend で Visual Studio・Xcode 用のファイルも作れます)。
| 状況 | 向くもの | 理由 |
|---|---|---|
| C/C++ のライブラリを人に配る・使う | CMake | find_package・Config ファイルで多くのライブラリとつながる。vcpkg・Conan も CMake 前提の案内が多い |
| Visual Studio・CLion・VS Code で同じものを開く | CMake | 3つとも CMakeLists.txt を直接開ける |
| Linux だけの小さなツール、タスクの実行 | Makefile | make だけで動き、追加のツールが要らない |
| 新しく始める C/C++ で、書きやすさを優先 | Meson | 文法が単純で行数が少ない。GNOME・systemd などが採用 |
| 多言語の巨大なリポジトリ、再現性とキャッシュ重視 | Bazel | 依存をすべて宣言し、リモートキャッシュで差分だけ作る。導入の手間は大きい |
| 既存プロジェクトが CMake | CMake | 乗り換えの費用に見合う理由が無い限りそのまま |
迷ったら C/C++ は CMake + Ninja を選ぶと、資料・IDE・ライブラリの対応がもっとも多く、困りにくい組み合わせです。GitHub Actions などの CI で cmake --preset と ctest --preset を呼ぶ形にしておくと、手元と CI で同じ手順になります。CI の考え方は関連記事「CI/CDとは|GitHub Actionsで最初のパイプラインを作るまで」で扱っています。
よくある質問
この節では、CMake について検索されることの多い疑問への短い答えが分かります。
Q. CMakeとMakeの違いは何ですか? A. Make は Makefile の手順どおりにコンパイラを呼ぶツール、CMake は CMakeLists.txt から Makefile(や build.ninja)を作るツールです。CMake を使うときも、実際のビルドは Make か Ninja が行います。
Q. CMakeLists.txt はどこに置きますか?
A. プロジェクトのいちばん上のフォルダーに置きます。サブフォルダーにも CMakeLists.txt を置き、上から add_subdirectory(src) で読み込むと、大きなプロジェクトを分けて書けます。ファイル名は大文字小文字まで CMakeLists.txt です。
Q. cmake .. と cmake -S . -B build は何が違いますか?
A. cmake .. は「build フォルダーに cd してから、親のソースを指定する」以前からの書き方です。-S と -B(3.13 以降)なら cd が要らず、どちらが何かが一目で分かります。結果は同じです。
Q. ビルドをやり直したいときは、build フォルダーを消してよいですか?
A. 消して問題ありません。build にはソースから作り直せるものしか入りません(手元では 568KB でした)。キャッシュだけを作り直すなら cmake --fresh も使えます。
Q. CMAKE_BUILD_TYPE を指定しないとどうなりますか? A. Makefile・Ninja では、最適化もデバッグ情報も付かないビルドになります。手元では Release の約15倍遅くなりました。何を作るかに合わせて Debug か Release を指定します。
Q. -j はいくつにすればよいですか?
A. CPU の数(nproc で分かる)が目安です。メモリが少ない環境で大きな C++ をビルドすると、並列数が多すぎてメモリが足りなくなることがあります。そのときは数を減らします。Ninja は指定しなくても CPU の数に合わせます。
Q. Windows でコンパイラが見つからないと言われます。 A. Visual Studio の C++ コンパイラと CMake の連携は、Visual Studio の「C++ によるデスクトップ開発」ワークロードに含まれる「Windows 用 C++ CMake ツール」が担います。Microsoft Learn では、[ファイル] > [開く] > [フォルダー] で CMakeLists.txt のあるフォルダーを開くと、Visual Studio が構成まで行うと案内されています。まずこのワークロードが入っているかを確かめます。
Q. C言語でも使えますか?
A. 使えます。project(xxx LANGUAGES C) と書き、C のコンパイラを検出させます。C と C++ が混ざるなら LANGUAGES C CXX です。CUDA・Fortran・Swift なども対応しています。
Q. 以前の書き方と今の書き方は、どう見分けますか? A. 目安は「target_ で始まる命令を使っているか」です。include_directories・link_directories・add_definitions・CMAKE_CXX_FLAGS の直接編集はフォルダー全体に効く以前の書き方で、target_include_directories・target_link_libraries・target_compile_definitions・target_compile_options に置き換えられます。
まとめ
- CMake は CMakeLists.txt から Make・Ninja・Visual Studio 用のファイルを作るツール。コンパイルは Make や Ninja とコンパイラが行う。
- 使い方は
cmake -S . -B build→cmake --build build→ctest --test-dir build。ビルド用フォルダーをソースと分ける。 - CMakeLists.txt は cmake_minimum_required → project → add_library・add_executable → target_link_libraries。設定は target_ の命令で付け、PUBLIC・PRIVATE で引き継ぐ範囲を決める。
- CMAKE_BUILD_TYPE を付けないと最適化が付かない。手元の計算は Debug 3,360ms、Release 202ms(約17倍)。変更が少ない再ビルドは Ninja が Make の約4分の1だった。
- CMake 4 では cmake_minimum_required が 3.5 未満だとエラー。CMAKE_POLICY_VERSION_MINIMUM は一時しのぎで、数字を上げるのが本筋。
参考・出典
確認日はいずれも 2026年10月29日です。
- CMake「Download」(最新リリース・提供形式):https://cmake.org/download/
- CMake「CMake 4.0 Release Notes」:https://cmake.org/cmake/help/latest/release/4.0.html
- CMake「cmake(1)」:https://cmake.org/cmake/help/latest/manual/cmake.1.html
- CMake「cmake-buildsystem(7)」(ターゲットと使用要件):https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html
- CMake「cmake-presets(7)」:https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
- CMake「cmake_minimum_required」:https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html
- CMake「find_package」:https://cmake.org/cmake/help/latest/command/find_package.html
- CMake「FetchContent」:https://cmake.org/cmake/help/latest/module/FetchContent.html
- CMake「CMAKE_BUILD_TYPE」:https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
- CMake「file(GLOB)」:https://cmake.org/cmake/help/latest/command/file.html
- Microsoft Learn「Visual Studio の CMake プロジェクト」:https://learn.microsoft.com/ja-jp/cpp/build/cmake-projects-in-visual-studio?view=msvc-170
- Microsoft Learn「CMake プリセットを使用した構成とビルド」:https://learn.microsoft.com/ja-jp/cpp/build/cmake-presets-vs?view=msvc-170
- Ninja「The Ninja build system」:https://ninja-build.org/manual.html
- Meson「The Meson Build system」:https://mesonbuild.com/
- Bazel「Bazel overview」:https://bazel.build/about/intro
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「CMakeとは?使い方とCMakeLists.txtの書き方|実測とエラー原文つき」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。