【保存版】CMake: プリコンパイルヘッダーの仕組みと無効化方法を徹底解説! CMAKE_DISABLE_PRECOMPILE_HEADERS 編


CMAKE_DISABLE_PRECOMPILE_HEADERS は、CMake のターゲットにおけるヘッダーファイルのプリコンパイルを制御するための変数です。この変数を設定することで、特定のターゲットまたはプロジェクト全体におけるプリコンパイルのオン/オフを切り替えることができます。

プリコンパイルヘッダーとは

プリコンパイルヘッダーは、コンパイル前に処理されたヘッダーファイルのバイナリ表現です。これにより、コンパイル時間が短縮され、パフォーマンスが向上することがあります。

CMAKE_DISABLE_PRECOMPILE_HEADERS の設定方法

  • ターゲットレベルで設定
set_target_properties(MyTarget PROPERTIES DISABLE_PRECOMPILE_HEADERS ON)

上記の例では、MyTarget というターゲットに対してプリコンパイルを無効化しています。

  • プロジェクトレベルで設定
set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)

上記の例では、プロジェクト全体のすべてのターゲットに対してプリコンパイルを無効化しています。

デフォルト値

CMAKE_DISABLE_PRECOMPILE_HEADERS のデフォルト値は OFF です。つまり、デフォルトではすべてのターゲットでプリコンパイルが有効化されています。

  • プリコンパイルは、すべてのコンパイラでサポートされているわけではありません。
  • プリコンパイルは、ヘッダーファイルが頻繁に変更されない場合にのみ有効です。
  • プリコンパイルを無効化すると、コンパイル時間が長くなる場合があります。
  • プリコンパイルヘッダーは、target_precompile_headers() コマンドを使用して指定できます。
  • CMAKE_DISABLE_PRECOMPILE_HEADERS は CMake 3.16 以降で利用できます。


サンプル 1: ターゲットレベルでの設定

cmake_minimum_required(VERSION 3.16)

project(MyProject)

add_executable(MyTarget MyTarget.cpp)

# ターゲット MyTarget に対してプリコンパイルを無効化
set_target_properties(MyTarget PROPERTIES DISABLE_PRECOMPILE_HEADERS ON)

サンプル 2: プロジェクトレベルでの設定

cmake_minimum_required(VERSION 3.16)

project(MyProject)

# プロジェクト全体のすべてのターゲットに対してプリコンパイルを無効化
set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)

add_executable(MyTarget1 MyTarget1.cpp)
add_executable(MyTarget2 MyTarget2.cpp)
cmake_minimum_required(VERSION 3.16)

project(MyProject)

add_executable(MyTarget MyTarget.cpp)

# 特定のヘッダーファイル MyHeader.h のプリコンパイルを無効化
set_target_properties(MyTarget PROPERTIES DISABLE_PRECOMPILE_HEADERS_FOR MyHeader.h ON)
  • プリコンパイルヘッダーは、target_precompile_headers() コマンドを使用して指定できます。
  • プリコンパイルは、すべてのコンパイラでサポートされているわけではありません。
  • プリコンパイルは、ヘッダーファイルが頻繁に変更されない場合にのみ有効です。
  • プリコンパイルを無効化すると、コンパイル時間が長くなる場合があります。


CMAKE_DISABLE_PRECOMPILE_HEADERS は、特定のターゲットまたはプロジェクト全体におけるヘッダーファイルのプリコンパイルを無効化するための便利な変数ですが、状況によっては代替手段が必要になる場合があります。

代替手段

  1. ヘッダーファイルのインクルード順序を変更する

プリコンパイルヘッダーは、コンパイル時に最初にインクルードされます。そのため、プリコンパイルヘッダーに頻繁に変更されるヘッダーファイルをインクルードすると、プリコンパイルの利点が失われてしまいます。

このような場合は、target_link_libraries() コマンドを使用して、プリコンパイルヘッダーよりも後にインクルードされるヘッダーファイルを指定することができます。

target_link_libraries(MyTarget MyLib)

上記の例では、MyTarget というターゲットに対して、MyLib というライブラリをリンクしています。MyLib のヘッダーファイルは、プリコンパイルヘッダーよりも後にインクルードされます。

  1. NO_COMPILE オプションを使用する

add_executable()add_library() コマンドに NO_COMPILE オプションを指定することで、特定のソースファイルをコンパイルから除外することができます。

add_executable(MyTarget MyTarget.cpp)

# MyHeader.h をコンパイルから除外
set_property(SOURCE MyHeader.h PROPERTY NO_COMPILE TRUE)

上記の例では、MyTarget というターゲットに対して、MyHeader.h というヘッダーファイルをコンパイルから除外しています。

  1. C++17 の PCH 機能を使用する

C++17 では、PCH (Precompiled Header) 機能が導入されました。PCH は、プリコンパイルヘッダーよりも柔軟で効率的なヘッダープリコンパイルメカニズムです。

PCH を使用するには、以下の手順が必要です。

  1. PCH ヘッダーファイルを作成します。
  2. コンパイラオプションで PCH ファイルを指定します。
  3. ソースファイルで PCH ヘッダーファイルをインクルードします。
// PCHヘッダーファイル MyPCH.h
#pragma once

#include <iostream>

// その他のヘッダーファイル
#include <vector>
#include <algorithm>
set_target_properties(MyTarget PROPERTIES COMPILE_FLAGS "-include MyPCH.h")
// ソースファイル MyTarget.cpp
#include "MyPCH.h"

int main() {
  std::vector<int> numbers {1, 2, 3, 4, 5};
  std::sort(numbers.begin(), numbers.end());

  for (int number : numbers) {
    std::cout << number << " ";
  }

  return 0;
}
  1. CMake の target_precompile_headers() コマンドを使用する

target_precompile_headers() コマンドは、特定のターゲットに対してプリコンパイルヘッダーファイルを指定するために使用されます。

target_precompile_headers(MyTarget MyHeader1.h MyHeader2.h)

上記の例では、MyTarget というターゲットに対して、MyHeader1.hMyHeader2.h というヘッダーファイルをプリコンパイルヘッダーファイルとして指定しています。

代替手段メリットデメリット状況
ヘッダーファイルのインクルード順序を変更するプリコンパイルヘッダーよりも後にインクルードされるヘッダーファイルを変更しやすいプリコンパイルヘッダーの利点が失われる可能性があるプリコンパイルヘッダーに頻繁に変更されるヘッダーファイルをインクルードする場合
NO_COMPILE オプションを使用する特定のソースファイルをコンパイルから簡単に除外できるコンパイル対象のソースファイルが減る特定のソースファイルをコンパイルから除外したい場合
C++17 の PCH 機能を使用するプリコンパイルヘッダーよりも柔軟で効率的C++17 以降のコンパイラが必要プリコンパイルヘッダーをより効率的に使用したい場合
CMake の target_precompile_headers() コマンドを使用する特定のターゲットに対してプリコンパイルヘッダーファイルを細かく指定できるCMake のバージョン