CMakeにおける変数スコープとビルド設定の詳細解説

変数のスコープと継承

CMakeにおける変数の扱いでは、スコープ(有効範囲)の理解が不可欠です。特に、サブディレクトリや関数をまたいで値を共有する場合には明示的な指定が必要です。

  • サブディレクトリ間の伝播: add_subdirectory() で呼び出された子CMakeLists.txtから親のスコープへ変数を書き込みたい場合、set() コマンドに PARENT_SCOPE オプションを付加する必要があります。
  • 関数からの返却: function() 内で定義された変数を呼び出し元へ反映させる場合も同様に、PARENT_SCOPE を使用して値を戻します。

主要な定義済み変数

CMakeには、プロジェクトの構造やビルド環境を示す多数の定義済み変数が用意されています。以下に、頻繁に使用される変数とその用途をまとめます。

変数名 説明
CMAKE_SOURCE_DIR プロジェクトの最上位にあるCMakeLists.txtが存在するソースツリーのルートパス
CMAKE_BINARY_DIR ビルド処理を行うルートディレクトリのパス(実行ファイルやライブラリの出力先のベース)
CMAKE_CURRENT_SOURCE_DIR 現在処理中のCMakeLists.txtが配置されているソースディレクトリのパス
CMAKE_CURRENT_BINARY_DIR 現在処理中のCMakeLists.txtに対応するビルドディレクトリのパス
CMAKE_CURRENT_LIST_DIR 現在読み込み中のCMakeLists.txtファイル自体が存在するディレクトリパス
CMAKE_CURRENT_LIST_LINE 現在処理されている行の行番号
CMAKE_MODULE_PATH .cmakeモジュールファイルなどを検索するための追加パスリスト
CMAKE_INCLUDE_CURRENT_DIR ONに設定すると、現在のディレクトリをヘッダーファイルの検索パスに自動追加
CMAKE_LIBRARY_OUTPUT_DIRECTORY ライブラリファイル(.dll, .so等)のデフォルト出力ディレクトリ
CMAKE_RUNTIME_OUTPUT_DIRECTORY 実行可能ファイル(.exe等)のデフォルト出力ディレクトリ
WIN32 Windowsプラットフォームでビルドされている場合に自動的に定義される
UNIX UNIX系プラットフォーム(Linux, macOS等)でビルドされている場合に自動的に定義される

変数の設定とビルド構成

set() コマンドを使用して、ビルドタイプやコンパイラの設定をカスタマイズできます。

ビルドタイプとパスの設定例

# リリースモードをデフォルトに設定し、デバッグ情報も含める
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

# 実行ファイルの探索パス(RPATH)を設定
if(UNIX)
  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
  set(CMAKE_BUILD_RPATH "${CMAKE_SOURCE_DIR}/output/lib")
endif()

コンパイラと標準規格の指定

# C++17を必須とする設定
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 特定のコンパイラパスを強制指定する場合(必要に応じて)
# set(CMAKE_C_COMPILER /usr/bin/clang)
# set(CMAKE_CXX_COMPILER /usr/bin/clang++)

出力ディレクトリのカスタマイズ

ターゲットごとの出力先を細かく制御するには、グローバル変数の設定と set_target_properties() を組み合わせます。

# グローバルな出力フォルダの定義
set(GLOBAL_BIN_DIR "${CMAKE_BINARY_DIR}/binaries")
set(GLOBAL_LIB_DIR "${CMAKE_BINARY_DIR}/libraries")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${GLOBAL_BIN_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${GLOBAL_LIB_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${GLOBAL_LIB_DIR}")

# 特定のターゲットに対して個別にプロパティを上書き
set_target_properties(my_core_lib PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/custom_libs"
    ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/custom_archives"
)

コンパイルオプションとターゲットの作成

オプションの追加方法

  • add_compile_options(): コンパイラフラグ(-Wallなど)を全ターゲットに追加します。
  • add_link_options(): リンカフラグを追加します。
  • add_definitions(): プリプロセッサマクロ(-DDEBUGなど)を定義します。
# 警告オプションの追加
add_compile_options(-Wall -Wextra)

# プリプロセッサ定義の追加
if(ENABLE_FEATURE_X)
    add_definitions(-DFEATURE_X_ENABLED)
endif()

# MSVC用の設定切り替え
if(MSVC)
    add_compile_options(/W4)
else()
    add_compile_options(-Wpedantic)
endif()

ライブラリターゲットの作成

add_library() コマンドを使用して、静的ライブラリ、動的ライブラリ、あるいはオブジェクトライブラリを定義します。

# 静的ライブラリ (Static Library)
add_library(math_utils STATIC
    src/calculations.cpp
    src/geometry.cpp
)

# 動的ライブラリ (Shared Library)
add_library(render_engine SHARED
    src/renderer.cpp
)

# ヘッダーオンリーライブラリ (Interface Library)
add_library(interface_lib INTERFACE)
target_include_directories(interface_lib INTERFACE include/)

タグ: CMake C++ BuildSystem DevOps

8月6日 20:23 投稿