CMakeの最適化オプションを使おう | ビルドタイプとコンパイルオプション

◎ 本記事は「CMake講座」シリーズの第4回です。
前回 -> 【第3回】CMakeで複数ディレクトリ構成を作ろう!〜モジュール分割の基本〜
次回 ->【第5回】CMakeで外部ライブラリを導入しよう!〜find_package / FetchContent / add_subdirectory / ExternalProject_Add〜

○ シリーズ全体の構成はこちら: CMake講座トップページ

【第4回】CMakeでビルドタイプとコンパイルオプションを管理しよう!〜Debug・Release・最適化の基本〜

前回までは、CMakeの構成要素と複数ディレクトリ構成を学び、C++プロジェクトをきれいに分離して管理できるようになりました。
今回のテーマは「ビルドタイプ」と「コンパイルオプション」です。
この2つを理解すれば、開発時とリリース時のコンパイルをより効率的に、意味のあるものにできます。(たぶん。)


1. ビルドタイプ(Build Type)とは?

C++の開発では、目的に応じて「最適化」や「デバッグ情報」の有無を切り替えます。
これを制御するのが CMakeのビルドタイプ です。

ビルドタイプ説明
Debugデバッグ用。最適化を行わず、デバッグ情報を含む (-g)
Release本番用。最適化を有効化 (-O3)、デバッグ情報なし
RelWithDebInfo最適化 + デバッグ情報あり (-O2 -g)
MinSizeRel容量を最小化するためのビルド (-Os)

2. ビルドタイプの指定方法

一時的に指定する方法

cmake -S ./ -B ./build -DCMAKE_BUILD_TYPE=Release
cmake --build ./build

出力確認:

[100%] Built target App

ビルドディレクトリ内の CMakeCache.txt に記録されます。


デフォルトを設定しておく方法

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Debug)
endif()

これで、指定がない場合は自動的に Debug ビルドになります。

さらに、以下のように CAHCHE を指定してあげることで、
前回にReleaseモードでビルドしていた場合も確実にCMakeCache.txtを上書きしてモードが反映されます。

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
endif()

3. 各ビルドタイプのオプションを確認する

CMakeは、ビルドタイプごとにあらかじめ異なるコンパイルオプションを内部で設定しています。
これらの設定値は、コンパイラに渡されるフラグ(-O3-g など)として自動的に反映されます。
そのため、「Debug」「Release」などのビルドタイプを切り替えるだけで、コンパイルの挙動が大きく変化します。

変数名内容(GCC/Clangの場合)目的
CMAKE_CXX_FLAGS_DEBUG-gデバッグ情報を含め、最適化を行わない
CMAKE_CXX_FLAGS_RELEASE-O3 -DNDEBUG最適化を最大化し、デバッグ情報を省く
CMAKE_CXX_FLAGS_RELWITHDEBINFO-O2 -g -DNDEBUGある程度の最適化とデバッグ情報の両立
CMAKE_CXX_FLAGS_MINSIZEREL-Os -DNDEBUG出力バイナリのサイズを最小化

これらの変数は、必要に応じてプロジェクト側で再設定することも可能です。
たとえば、Releaseビルドに警告オプションを追加したい場合は、次のようにします。

set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wall -DNDEBUG")

このように、CMakeはビルドタイプに応じたデフォルトのコンパイル設定を提供しており、
それを理解・調整することで、プロジェクトに最適なビルド環境を構築できます。

4. コンパイルオプションを追加する — target_compile_options

CMakeでは、コンパイル時の警告設定や最適化フラグなどを、ターゲット(=実行ファイルやライブラリ)単位で指定できます。
これにより、プロジェクト全体に影響を与えずに個別の設定が可能になります。

そのために使うのが target_compile_options() です。

add_executable(MyApp main.cpp)
target_compile_options(MyApp PRIVATE -Wall -Wextra -Werror)

この例では、MyApp に対して「すべての警告を有効化し、警告をエラー扱いにする」設定を行っています。
-Wall-Wextra は GCC や Clang で一般的に使われる警告オプションです。

修飾子には次のような意味があります (復習):

修飾子意味適用範囲
PRIVATEこのターゲットだけに適用推奨(他のターゲットへ影響しない)
PUBLICこのターゲット+リンク先に継承ライブラリ側で利用
INTERFACE自分には不要だが、リンク相手だけに伝えるインターフェース専用設定

◎ 初心者のうちは PRIVATE で十分です。
複数のライブラリを組み合わせるようになったときに、PUBLIC/INTERFACEの違いが重要になります。


5. ビルドタイプごとの設定を切り替える

開発中は「デバッグ情報を含む」ビルド、リリース時は「最適化を有効にする」ビルド、と使い分けたい場合があります。
CMakeではこのような条件ごとの切り替えを簡潔に記述できます。

target_compile_options(MyApp PRIVATE
  CONFIG:Debug>:-O0 -g>
  CONFIG:Release>:-O3>) 
 

ここでは、「Debugビルドなら-O0 -g(最適化なし+デバッグ情報あり)」、「Releaseなら-O3(最適化重視)」を設定しています。
このように、ビルドタイプに応じて自動的にオプションを切り替える仕組みを ジェネレーター式 と呼びます。
このジェネレーター式については長くなってしまうのでまた別の機会に説明します。
今回はこのような書き方が存在するということを理解しておけばOKです。


6. プラットフォームごとの設定を分ける

開発環境がLinux・Windows・macOSなど複数ある場合、コンパイラオプションを切り替える必要があります。
CMakeは内部変数 CMAKE_SYSTEM_NAME に現在のOS名を自動で設定しており、これを使って条件分岐が可能です。

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  target_compile_options(MyApp PRIVATE -Wall -Wextra)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
  target_compile_options(MyApp PRIVATE /W4)
endif()

上記の例では、Linuxでは-Wall -Wextraを、WindowsではMSVC用の/W4を適用しています。
このように条件分岐を使うことで、同じCMakeLists.txtを異なる環境でも共通利用できます。


7. 実践例:Releaseビルドの設定をまとめる

これまでの内容を組み合わせると、ビルドタイプや環境に応じた柔軟な設定が行えます。
次は、実際のCMakeLists.txt全体例を見てみましょう。

cmake_minimum_required(VERSION 3.10)
project(OptimizedApp LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(App main.cpp)

# 共通の警告設定
target_compile_options(App PRIVATE -Wall -Wextra -Wpedantic)

# ビルドタイプ別設定
target_compile_options(App PRIVATE
  CONFIG:Debug>:-O0 -g>
  CONFIG:Release>:-O3 -DNDEBUG>) 


ポイント

  • Debug時 → -O0 -g:デバッグ情報付き、最適化なし
  • Release時 → -O3 -DNDEBUG:最適化有効、アサート無効化

DNDEBUGassert() 関数を無効にするC++標準のマクロで、リリースビルドでよく使われます。


8. ビルドタイプを確認する方法

現在の設定が正しく反映されているかを確認するには、CMakeのキャッシュを参照してみましょう。

grep CMAKE_BUILD_TYPE build/CMakeCache.txt

出力例:

CMAKE_BUILD_TYPE:STRING=Release

◎ CMakeは設定情報を build/CMakeCache.txt に保存します。
ここを確認すると、CMakeLists.txtの内容が正しく反映されているかが分かります。


9. プリセットを使った構成(CMake 3.19以降)

CMake 3.19以降では、JSON形式の CMakePresets.json ファイルを使って、
構成設定を保存・共有できるようになりました。チーム開発や自動ビルドに便利です。

{
  "version": 3,
  "configurePresets": [
    {
      "name": "release",
      "generator": "Ninja",
      "binaryDir": "build/release",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release"
      }
    }
  ]
}

設定後、以下のように実行できます:

cmake --preset release

◎ プリセットを使うと、複数環境でも同じビルド設定を再現できます。


10. キャッシュをリセットして再構成する

設定を変更しても反映されない場合は、古いキャッシュが残っている可能性があります。
その場合は、build ディレクトリを削除して再構成しましょう。

rm -rf build/
cmake -S ./ -B ./build

◎ CMakeは一度生成したキャッシュ(CMakeCache.txt)を優先して読み込むため、
設定を大きく変えたときはクリーンビルドが安全です。


11. まとめ

目的コマンド / 変数ポイント
ビルドタイプ切替-DCMAKE_BUILD_TYPE=ReleaseDebug/Releaseの選択
警告設定target_compile_options()ターゲットごとの安全設定
条件分岐if(CMAKE_SYSTEM_NAME ...)環境ごとの切替
マクロ定義DNDEBUGassertを無効化(リリース向け)
キャッシュ確認CMakeCache.txt現在の設定を確認可能

◎ CMakeのコンパイル設定を理解しておくと、開発効率が上がるだけでなく、
複数環境で安定したビルドを行えるようになります。


◇CMake基礎講座

(第3回:CMakeで複数ディレクトリ構成を作ろう)
(第5回:CMakeで外部ライブラリを導入しよう!)

CMake講座トップページに戻る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です