【ビルド高速化】CMakeで「target_compile_features」と「add_compile_options」を使いこなす


CMAKE_LANG_FLAGS_RELEASE_INIT は CMake における変数の一つで、ビルド構成が "Release" の場合に、特定のプログラミング言語用のコンパイラフラグを初期化する役割を果たします。この変数は、toolchain file と呼ばれる設定ファイル内で設定されます。

変数の構成

CMAKE_LANG_FLAGS_RELEASE_INIT は以下の形式で構成されます。

string(APPEND CMAKE_<LANG>_FLAGS_RELEASE "${FLAGS}")
  • FLAGS: 設定するコンパイラフラグ (スペース区切りで複数指定可能)
  • <LANG>: 対象となるプログラミング言語 (例: C, CXX, Fortran, RC, ASM)

動作の詳細

  • すでに CMAKE_<LANG>_FLAGS_RELEASE キャッシュエントリに値が設定されている場合は、CMAKE_LANG_FLAGS_RELEASE_INIT で設定されたフラグは 追加 されます。
  • その後、CMake は環境やターゲットプラットフォームに基づいて、CMAKE_<LANG>_FLAGS_RELEASE の値にフラグを追加したり、先頭に挿入したりする場合があります。
  • 初めてビルドツリーを構成する場合、CMAKE_LANG_FLAGS_RELEASE_INIT で設定されたフラグが CMAKE_<LANG>_FLAGS_RELEASE キャッシュエントリに初期値として格納されます。

toolchain file との連携

以下の例は、toolchain fileC 言語用のコンパイラフラグを設定する例です。

# toolchain file の例

set(CMAKE_TOOLCHAIN_FILE "toolchain.cmake")

# C 言語用のコンパイラフラグを設定
string(APPEND CMAKE_C_FLAGS_RELEASE "-O3 -Wall")

この設定により、toolchain file を使用するすべてのCMake プロジェクトで、C 言語のコンパイル時に -O3-Wall フラグが自動的に適用されます。

  • 詳細については、CMake 公式ドキュメントの "Variables" セクションを参照してください。
  • 他のビルド構成用の変数として、CMAKE_LANG_FLAGS_DEBUG_INITCMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT などがあります。
  • CMAKE_LANG_FLAGS_RELEASE_INIT は CMake 3.7 以降で導入された変数です。


# toolchain.cmake の例

# C 言語用のコンパイラフラグを設定
string(APPEND CMAKE_C_FLAGS_RELEASE "-O3 -Wall")

# C++ 言語用のコンパイラフラグを設定
string(APPEND CMAKE_CXX_FLAGS_RELEASE "-std=c++11 -O2")

# Fortran 言語用のコンパイラフラグを設定
string(APPEND CMAKE_FORTRAN_FLAGS_RELEASE "-O2 -fPIC")

説明

この例では、toolchain.cmake ファイル内に CMAKE_LANG_FLAGS_RELEASE_INIT 変数を使用して、C、C++、Fortran 言語用のコンパイラフラグを設定しています。

  • -fPIC: 位置独立コード (PIC) を生成
  • -std=c++11: C++11 標準規格を適用
  • -Wall: すべての警告を有効にする
  • -O3: 最適化レベル 3 を設定 (高速化)

例2: 特定のプラットフォーム向けにフラグを設定

# toolchain.cmake の例

# Linux 向けの C 言語用コンパイラフラグを設定
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
  string(APPEND CMAKE_C_FLAGS_RELEASE "-m64")
endif()

# Windows 向けの C++ 言語用コンパイラフラグを設定
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
  string(APPEND CMAKE_CXX_FLAGS_RELEASE "/MT")
endif()

説明

この例では、CMAKE_SYSTEM_NAME 変数を使用して、オペレーティングシステムを判別し、それに応じてコンパイラフラグを設定しています。

  • /MT: マルチスレッド (MT) モードでコンパイル
  • -m64: 64 ビットモードでコンパイル

例3: 外部変数を参照する

# toolchain.cmake の例

# 外部変数から C 言語用コンパイラフラグを取得
set(MY_C_FLAGS "-Werror -Wextra")

# CMAKE_LANG_FLAGS_RELEASE_INIT に MY_C_FLAGS を追加
string(APPEND CMAKE_C_FLAGS_RELEASE "${MY_C_FLAGS}")

説明

この例では、MY_C_FLAGS という外部変数に定義されたコンパイラフラグを、CMAKE_LANG_FLAGS_RELEASE_INIT に追加しています。

  • CMake の詳細については、公式ドキュメントを参照してください。
  • 上記の例はあくまで一例であり、実際のプロジェクトでは必要に応じて設定を調整する必要があります。


代替方法

  1. target_compile_features プロパティを使う

    target_compile_features プロパティは、ターゲットに特定のコンパイラ機能を有効にするための CMake 命令です。このプロパティは、CMAKE_LANG_FLAGS_RELEASE_INIT 変数よりも詳細な制御を提供し、特定のコンパイラおよびプラットフォームに依存しない設定を可能にします。

    例:

    target_compile_features(mytarget PUBLIC CXX_STANDARD_11)
    

    この例では、mytarget ターゲットに対して C++11 標準規格を有効にします。

  2. add_compile_options コマンドを使う

    add_compile_options コマンドは、特定のターゲットに対してコンパイラフラグを直接追加するための CMake 命令です。このコマンドは、CMAKE_LANG_FLAGS_RELEASE_INIT 変数よりも柔軟性が高く、個々のコンパイルコマンドにフラグを追加することができます。

    add_compile_options(mytarget "-O3 -Wall")
    

    この例では、mytarget ターゲットに対して -O3-Wall フラグを追加します。

  3. CMake のキャッシュ変数を使う

    CMake のキャッシュ変数は、プロジェクト全体で設定を共有するために使用することができます。CMAKE_LANG_FLAGS_RELEASE_INIT 変数よりも柔軟性が高く、特定の条件に基づいてフラグを設定することができます。

    set(CMAKE_C_FLAGS_RELEASE "-O3 -Wall")
    
    if(CMAKE_SYSTEM_NAME MATCHES "Windows")
      set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
    endif()
    

    この例では、CMAKE_C_FLAGS_RELEASE キャッシュ変数に -O3-Wall フラグを設定します。さらに、CMAKE_SYSTEM_NAME 変数を使用してオペレーティングシステムを判別し、Windows の場合は /MT フラグを追加します。

各方法の利点と欠点

方法利点欠点
target_compile_features詳細な制御、プラットフォーム非依存機能ごとに個別の設定が必要
add_compile_options柔軟性、個々のコンパイルコマンドへのフラグ追加詳細な設定が難しい
CMake キャッシュ変数設定の共有、条件に基づいた設定キャッシュ変数の管理が必要

最適な方法の選択

最適な方法は、プロジェクトの要件と複雑さに依存します。以下の点を考慮して選択してください。

  • プラットフォーム: プラットフォーム非依存の設定が必要な場合は target_compile_features を使用します。
  • プロジェクトの複雑性: シンプルなプロジェクトの場合は add_compile_options、複雑なプロジェクトの場合は target_compile_features または CMake キャッシュ変数を使用します。
  • 必要な制御レベル: 詳細な制御が必要な場合は target_compile_features、柔軟性が必要な場合は add_compile_options、設定の共有が必要な場合は CMake キャッシュ変数を使用します。
  • CMake の詳細については、公式ドキュメントを参照してください。
  • 上記の代替方法は、互いに排他的ではありません。状況に応じて複数の方法を組み合わせることもできます。