CMakeで複数ディレクトリ構成を作る方法|add_subdirectoryの使い方
◎ 本記事は「CMake講座」シリーズの第3回です。
前回 -> 【第2回】CMakeLists.txtの基本を理解しよう 〜主要コマンドと構成の基礎〜
次回 ->【第4回】CMakeでビルドタイプとコンパイルオプションを管理しよう!〜Debug/Releaseの理解〜○ シリーズ全体の構成はこちら: CMake講座トップページ
【第3回】CMakeで複数ディレクトリ構成を作ろう!〜モジュール分割の基本〜
これまでの記事では、単一の CMakeLists.txt で小規模なC++プロジェクトを構築してきました。
実際の開発では、コードを複数のディレクトリに分けて整理することが一般的です。
今回は、CMakeで複数ディレクトリ構成を扱う方法を学びます。
1. ディレクトリを分割する
プロジェクトが大きくなると、ソースコードやライブラリをディレクトリ単位で整理する必要が出てきます。
例として以下のような構成を考えます。
MyProject/
├── CMakeLists.txt
├── app/
│ ├── CMakeLists.txt
│ └── main.cpp
└── lib/
├── CMakeLists.txt
├── util.cpp
└── util.hppこの構成では、アプリケーション部分 (app/) とライブラリ部分 (lib/) を分けています。
それぞれのフォルダに独立した CMakeLists.txt を配置することで、管理しやすくなります。
また、トップレベル(MyProject/)にも CMakeLists.txt を配置することを忘れないようにしましょう。
2. トップレベルのCMakeLists.txt
プロジェクトのルートにある CMakeLists.txt は、全体の構成をまとめる役割を持ちます。
cmake_minimum_required(VERSION 3.10)
project(MyProject LANGUAGES CXX)
add_subdirectory(lib)
add_subdirectory(app)add_subdirectory() は、指定したフォルダ内の CMakeLists.txt を読み込みます。
これにより、モジュールごとにビルド設定を分割できます。
3. lib/CMakeLists.txt(ライブラリ側)
次に、ライブラリ側の設定を記述します。
add_library(MyLib STATIC util.cpp)
target_include_directories(MyLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})ここでは MyLib という静的ライブラリを作成し、ヘッダーファイル (util.hpp) があるディレクトリを公開しています。
| 設定 | 内容 |
|---|---|
add_library() | ライブラリの生成 |
target_include_directories() | ヘッダの探索パスを設定 |
${CMAKE_CURRENT_SOURCE_DIR} というのは、現在の CMakeLists.txt が配置されている場所を指しています。
この変数は自動的にCMakeによって生成されるため、特に宣言する必要はありません。
4. app/CMakeLists.txt(アプリケーション側)
アプリケーション部分は、ライブラリをリンクして実行ファイルを生成します。
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE MyLib)このように書くことで、MyApp が MyLib を利用できるようになります。
さらに、MyLib では util.hpp が配置されているヘッダのインクルードディレクトリを公開しているため、main.cpp に対してさらに target_include_directories() などをする必要がありません。
5. main.cpp と util.cpp の内容例
app/main.cpp:
#include <iostream>
#include "util.hpp"
int main() {
std::cout << "Sum: " << add(2, 3) << std::endl;
return 0;
}
lib/util.cpp:
#include "util.hpp"
int add(int a, int b) {
return a + b;
}
lib/util.hpp:
#pragma once
int add(int a, int b);6. ビルド手順
ルートディレクトリでビルドを行います。
cmake -S ./ -B ./build
cmake --build ./buildビルドが完了すると、build/app/MyApp が生成されます。
実行すると以下のように出力されます。
Sum: 57. 仕組みの整理
add_subdirectory() によって、サブディレクトリ内の CMakeLists.txt が順に処理されます。
| 処理順 | 内容 |
|---|---|
| 1 | lib/ のライブラリを生成 |
| 2 | app/ の実行ファイルを生成 |
| 3 | app が MyLib にリンクされる |
この仕組みにより、大規模なプロジェクトでも構成を分かりやすく整理できます。
8. よくあるエラーと対処法
| エラー内容 | 原因 | 対処法 |
|---|---|---|
Cannot find source file | ファイルパスが間違っている | 相対パスを確認 |
Target MyLib not found | add_subdirectory(lib) が抜けている | ルートの CMakeLists.txt を確認 |
Include file not found | ヘッダのパスが設定されていない | target_include_directories() を追加 |
9. まとめ
| 目的 | コマンド | 役割 |
|---|---|---|
| 複数フォルダの統合 | add_subdirectory() | サブディレクトリの読み込み |
| ライブラリ定義 | add_library() | 再利用可能なモジュール化 |
| アプリケーション構成 | add_executable() | 実行ファイル生成 |
| 依存関係設定 | target_link_libraries() | ライブラリを接続 |
◎ CMakeのディレクトリ構成を理解すると、チーム開発や長期保守に強いプロジェクト設計が可能になります。
10. 次回予告
次回は「ビルドタイプとコンパイルオプション」を扱います。
Debug / Release ビルドや最適化オプションの指定方法を整理して、
開発と配布の両方で活用できる設定を構築します。
◇CMake基礎講座
←(第2回:CMakeLists.txtの基本を理解しよう)
(第4回:CMakeでビルドタイプとコンパイルオプションを管理しよう!) →
○ CMake講座トップページに戻る

