CMakeスクリプトの可読性向上:`CMAKE_CURRENT_LIST_LINE` を活用したログ出力と条件分岐


CMAKE_CURRENT_LIST_LINE は、CMake スクリプト内で現在処理されている行番号を取得するために使用される変数です。これは、CMakeLists.txt ファイルや CMake モジュールファイルなどの CMake 構成ファイルで利用できます。

用途

CMAKE_CURRENT_LIST_LINE は、以下の用途で役立ちます。

  • スクリプトの可読性向上: コメントやドキュメントに現在の行番号を含めることで、スクリプトの理解を促進することができます。
  • 条件付き処理: 現在の行番号に基づいて条件分岐を行うことができます。
  • ログ出力の強化: デバッグ情報や警告メッセージに現在の行番号を含めることで、問題の特定を容易にすることができます。

使用方法

CMAKE_CURRENT_LIST_LINE は、以下の構文で直接使用できます。

message(STATUS "現在の行番号: ${CMAKE_CURRENT_LIST_LINE}")

このコードは、現在の行番号を "STATUS" レベルのメッセージとして出力します。

  • CMAKE_CURRENT_LIST_LINE は、未定義変数警告が有効になっている場合、常に未定義変数として警告されます。ただし、一度でも値を取得した後は、DEFINED(CMAKE_CURRENT_LIST_LINE) を使用して定義されているかどうかを確認できます。
  • CMAKE_CURRENT_LIST_LINE は、cmake_language(DEFER) コマンドによってスケジュールされた遅延呼び出しが現在処理されている場合は、常に "DEFERRED" に評価されます。
  • CMAKE_CURRENT_LIST_LINE は、常に整数値として評価されます。
  • CMAKE_CURRENT_LIST_LINE は、CMake スクリプト内のどこでも使用できます。

以下の例は、CMAKE_CURRENT_LIST_LINE を使用してログ出力と条件付き処理を行う方法を示しています。

# メッセージに現在の行番号を含める
message(STATUS "現在の行番号: ${CMAKE_CURRENT_LIST_LINE}")

# 現在の行番号が 10 より大きい場合は、警告メッセージを出力する
if(CMAKE_CURRENT_LIST_LINE GREATER 10)
  message(WARNING "現在の行番号が 10 を超えました")
endif()

CMAKE_CURRENT_LIST_LINE は、CMake スクリプト内で現在処理されている行番号を取得するための便利な変数です。ログ出力、条件付き処理、スクリプトの可読性向上など、さまざまな用途に役立ちます。

  • CMake のバージョンによっては、CMAKE_CURRENT_LIST_LINE の動作が異なる場合があります。


cmake_minimum_required(VERSION 3.7.2)

project(MyProject)

# メッセージに現在の行番号を含める
message(STATUS "現在の行番号: ${CMAKE_CURRENT_LIST_LINE}")

# ファイルが存在するかどうかを確認する
if(EXISTS ${CMAKE_SOURCE_DIR}/myfile.txt)
  message(STATUS "myfile.txt が存在します")
else()
  message(WARNING "myfile.txt が存在しません")
endif()

# 現在の行番号が 10 より大きい場合は、警告メッセージを出力する
if(CMAKE_CURRENT_LIST_LINE GREATER 10)
  message(WARNING "現在の行番号が 10 を超えました")
endif()

説明

  • CMAKE_CURRENT_LIST_LINE 変数を使用して、現在の行番号が 10 を超えているかどうかを条件分岐します。
  • if() コマンドを使用して、myfile.txt ファイルが存在するかどうかを条件分岐します。
  • message() コマンドを使用して、現在の行番号とファイル myfile.txt の存在状況に関するメッセージを出力します。
  • 最初の行で、CMake バージョン 3.7.2 以降が必要であることを指定します。
  • このコードは、CMake プロジェクト MyProject を作成します。
  • コメントに現在の行番号を含める
# コメントに現在の行番号を含める
# --- 行番号: ${CMAKE_CURRENT_LIST_LINE} ---

set(MY_VARIABLE "This is my variable")
  • ループ内の処理ごとにログを出力する
foreach(ITEM IN LISTS ${MY_LIST})
  message(STATUS "処理対象: ${ITEM} (行番号: ${CMAKE_CURRENT_LIST_LINE})")
endforeach()
  • CMake の最新バージョンおよびドキュメントを参照して、最新の機能や使用方法を確認することをお勧めします。
  • 上記の例はあくまでサンプルであり、実際の使用状況に応じて適宜変更する必要があります。


代替方法

  • file(GLOB) コマンドと CMAKE_MATCH_LIST 変数

file(GLOB) コマンドを使用して、現在の行番号を含むファイルパスリストを取得し、CMAKE_MATCH_LIST 変数を使用して行番号を抽出することができます。

file(GLOB CURRENT_FILE_PATHS "*.cmake")
list(GET CURRENT_FILE_PATHS ${CMAKE_MATCH_LIST_INDEX} CURRENT_FILE_PATH)

message(STATUS "現在の行番号: ${CMAKE_CURRENT_LIST_LINE}")

説明

  • list(GET) コマンドは、リストから指定されたインデックスの要素を取得します。
  • CMAKE_MATCH_LIST_INDEX 変数は、file(GLOB) コマンドによって見つかったファイルのインデックスを格納します。
  • file(GLOB) コマンドは、指定されたパターンに一致するファイルをすべて検索します。

利点

  • 複数のファイルにまたがるスクリプトで利用できる。
  • CMAKE_CURRENT_LIST_LINE 変数よりも柔軟性が高い。

欠点

  • file(GLOB) コマンドは、ファイルシステムの読み込みを行うため、CMAKE_CURRENT_LIST_LINE 変数よりも処理速度が遅くなる可能性がある。
  • CMAKE_SCRIPT_RUNNING_DIR 変数とファイルシステムパス

CMAKE_SCRIPT_RUNNING_DIR 変数を使用して、現在のCMake スクリプトのディレクトリパスを取得し、ファイルシステムパスから行番号を抽出することができます。

get_property(CURRENT_FILE_DIR DIRECTORY CMAKE_SCRIPT_RUNNING_DIR)
set(CURRENT_FILE_PATH "${CURRENT_FILE_DIR}/${CMAKE_SCRIPT_NAME}")

# ファイルが存在するかどうかを確認する
if(EXISTS ${CURRENT_FILE_PATH})
  # ファイルの行数を取得する
  file(READ ${CURRENT_FILE_PATH} CURRENT_FILE_CONTENT)
  string(FIND ${CURRENT_FILE_CONTENT} "${CMAKE_SCRIPT_BODY_START}") CURRENT_LINE_NUMBER
  math(EXPR CURRENT_LINE_NUMBER "${CURRENT_LINE_NUMBER} + 1")

  message(STATUS "現在の行番号: ${CURRENT_LINE_NUMBER}")
else()
  message(WARNING "現在のCMake スクリプトファイルが見つかりません")
endif()

説明

  • math(EXPR) コマンドを使用して、行番号を 1 増やします。
  • string(FIND) コマンドを使用して、現在の行番号を含む行の位置を検索します。
  • file(READ) コマンドを使用して、現在のCMake スクリプトの内容を読み取ります。
  • set() コマンドを使用して、現在のCMake スクリプトのファイルパスを作成します。
  • get_property() コマンドを使用して、現在のCMake スクリプトのディレクトリパスを取得します。

利点

  • 複数のファイルにまたがるスクリプトで利用できる。
  • CMAKE_CURRENT_LIST_LINE 変数よりも柔軟性が高い。
  • ファイルシステムの読み込みを行うため、CMAKE_CURRENT_LIST_LINE 変数よりも処理速度が遅くなる可能性がある。