【保存版】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 は、特定のターゲットまたはプロジェクト全体におけるヘッダーファイルのプリコンパイルを無効化するための便利な変数ですが、状況によっては代替手段が必要になる場合があります。
代替手段
- ヘッダーファイルのインクルード順序を変更する
プリコンパイルヘッダーは、コンパイル時に最初にインクルードされます。そのため、プリコンパイルヘッダーに頻繁に変更されるヘッダーファイルをインクルードすると、プリコンパイルの利点が失われてしまいます。
このような場合は、target_link_libraries()
コマンドを使用して、プリコンパイルヘッダーよりも後にインクルードされるヘッダーファイルを指定することができます。
target_link_libraries(MyTarget MyLib)
上記の例では、MyTarget
というターゲットに対して、MyLib
というライブラリをリンクしています。MyLib
のヘッダーファイルは、プリコンパイルヘッダーよりも後にインクルードされます。
- 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
というヘッダーファイルをコンパイルから除外しています。
- C++17 の PCH 機能を使用する
C++17 では、PCH (Precompiled Header) 機能が導入されました。PCH は、プリコンパイルヘッダーよりも柔軟で効率的なヘッダープリコンパイルメカニズムです。
PCH を使用するには、以下の手順が必要です。
- PCH ヘッダーファイルを作成します。
- コンパイラオプションで PCH ファイルを指定します。
- ソースファイルで 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;
}
- CMake の
target_precompile_headers()
コマンドを使用する
target_precompile_headers()
コマンドは、特定のターゲットに対してプリコンパイルヘッダーファイルを指定するために使用されます。
target_precompile_headers(MyTarget MyHeader1.h MyHeader2.h)
上記の例では、MyTarget
というターゲットに対して、MyHeader1.h
と MyHeader2.h
というヘッダーファイルをプリコンパイルヘッダーファイルとして指定しています。
代替手段 | メリット | デメリット | 状況 |
---|---|---|---|
ヘッダーファイルのインクルード順序を変更する | プリコンパイルヘッダーよりも後にインクルードされるヘッダーファイルを変更しやすい | プリコンパイルヘッダーの利点が失われる可能性がある | プリコンパイルヘッダーに頻繁に変更されるヘッダーファイルをインクルードする場合 |
NO_COMPILE オプションを使用する | 特定のソースファイルをコンパイルから簡単に除外できる | コンパイル対象のソースファイルが減る | 特定のソースファイルをコンパイルから除外したい場合 |
C++17 の PCH 機能を使用する | プリコンパイルヘッダーよりも柔軟で効率的 | C++17 以降のコンパイラが必要 | プリコンパイルヘッダーをより効率的に使用したい場合 |
CMake の target_precompile_headers() コマンドを使用する | 特定のターゲットに対してプリコンパイルヘッダーファイルを細かく指定できる | CMake のバージョン |