「CMake - 外部コマンド」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
56行目: 56行目:
== execute_processコマンド ==
== execute_processコマンド ==
外部コマンドを実行して戻り値を取得することができる。<br>
外部コマンドを実行して戻り値を取得することができる。<br>
<br>
戻り値が0以外の場合は、エラーが発生したことを示す。<br>
戻り値が0以外の場合は、エラーが発生したことを示す。<br>
<br>
<br>
65行目: 64行目:
例えば、lsコマンドでは、戻り値が0ではない場合はエラーメッセージが出力される。<br>
例えば、lsコマンドでは、戻り値が0ではない場合はエラーメッセージが出力される。<br>
以下の例では、変数名LS_RESULTには、lsコマンドの戻り値が格納される。<br>
以下の例では、変数名LS_RESULTには、lsコマンドの戻り値が格納される。<br>
<br>
  <syntaxhighlight lang="cmake">
  <syntaxhighlight lang="cmake">
  # lsコマンドを実行して戻り値を取得する場合
  # lsコマンドを実行して戻り値を取得する場合
71行目: 71行目:
  if(LS_RESULT)
  if(LS_RESULT)
     message("ls command failed with error code ${LS_RESULT}")
     message("ls command failed with error code ${LS_RESULT}")
endif()
</syntaxhighlight>
<br>
以下の例では、Gitのバージョン管理システムからタグ情報を取得している。<br>
ビルドバージョンの自動生成やバージョン情報の埋め込み等を行うことができる。<br>
<syntaxhighlight lang="cmake">
execute_process(
    # Gitのタグ情報を取得するコマンドを実行
    COMMAND git describe --tags
    # コマンドを実行するディレクトリをプロジェクトのルートディレクトリに設定
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    # コマンドの終了コードを GIT_RESULT 変数に格納
    RESULT_VARIABLE GIT_RESULT
    # コマンドの標準出力を GIT_VERSION 変数に格納
    OUTPUT_VARIABLE GIT_VERSION
    # エラーが発生した場合の出力を GIT_ERROR 変数に格納
    ERROR_VARIABLE GIT_ERROR
    # 出力から末尾の空白文字や改行を削除
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
# コマンドが失敗した場合 (終了コードが0以外) の処理
if(NOT GIT_RESULT EQUAL 0)
    # 警告メッセージを表示
    message(WARNING "Git command failed : ${GIT_ERROR}")
endif()
</syntaxhighlight>
<br>
以下の例では、ls -lコマンドでディレクトリ内のファイル一覧を詳細形式で取得して、その出力をgrep ".txt"コマンドにパイプで渡して、テキストファイルのみを抽出している。<br>
また、その結果を変数TEXT_FILESに格納している。<br>
<syntaxhighlight lang="cmake">
execute_process(
    # ls -lコマンドでファイル一覧を取得
    COMMAND ls -l
    # ファイル一覧からテキストファイル (.txt拡張子) を含む行を抽出
    COMMAND grep ".txt"
    # コマンドを実行するディレクトリを設定
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    # コマンドの実行結果 (終了コード) を格納
    # 0 : コマンドが正常に終了
    # 非0 : コマンドが何らかのエラーで終了
    RESULT_VARIABLE SEARCH_RESULT
    # 結果を TEXT_FILES 変数に格納
    OUTPUT_VARIABLE TEXT_FILES
    # コマンドの標準エラー出力 (stderr) の内容を格納
    # コマンド実行中にエラーが発生した場合、そのエラーメッセージがこの変数に格納される
    ERROR_VARIABLE SEARCH_ERROR
)
if(SEARCH_RESULT EQUAL 0)
    message(STATUS "Command executed successfully")
else()
    message(WARNING "File search failed : ${SEARCH_ERROR}")
  endif()
  endif()
  </syntaxhighlight>
  </syntaxhighlight>

2025年1月13日 (月) 04:30時点における版

概要

外部コマンドを実行するためのCMakeコマンドにおいて、execute_processコマンドおよびadd_custom_commandコマンドがある。
これらは、異なる用途と実行タイミングを持つ。

execute_processコマンドでは、CMakeの設定時 (configureスクリプト時) に即座に実行される。
外部ツールを使用してビルドに必要な情報を取得する場合に使用されることが多い。

 execute_process(
    COMMAND <cmd1> [args1...]        # 実行する最初のコマンドと引数
    [COMMAND <cmd2> [args2...]]      # パイプで接続される後続のコマンド
    [WORKING_DIRECTORY <directory>]  # コマンド実行時の作業ディレクトリ
    [RESULT_VARIABLE <variable>]     # 実行結果のステータスコードを格納する変数
    [OUTPUT_VARIABLE <variable>]     # 標準出力の内容を格納する変数
    [ERROR_VARIABLE <variable>]      # 標準エラー出力の内容を格納する変数
    [INPUT_FILE <file>]              # 標準入力としてリダイレクトするファイル
    [OUTPUT_FILE <file>]             # 標準出力をリダイレクトするファイル
    [ERROR_FILE <file>]              # 標準エラー出力をリダイレクトするファイル
 )


add_custom_commandコマンドは、ビルド時に実行されるコマンドを定義する。
これは、ビルドプロセスの一部として特定のファイルの生成、あるいは、特定のアクションを実行する場合に使用される。

 add_custom_command(
    OUTPUT output1 [output2 ...]          # 生成される出力ファイル
    COMMAND command1 [ARGS] [args1...]    # 実行するコマンドと引数
    [COMMAND command2 [ARGS] [args2...]]  # 追加のコマンド
    [MAIN_DEPENDENCY depend]              # 主要な入力依存ファイル
    [DEPENDS [depends...]]                # その他の依存ファイルやターゲット
    [WORKING_DIRECTORY dir]               # コマンド実行時の作業ディレクトリ
    [COMMENT comment]                     # ビルド時に表示されるメッセージ
    [VERBATIM]                            # コマンドラインの引数をそのまま使用
 )


execute_processコマンド / add_custom_commandコマンドの違いは実行タイミングである。
execute_processコマンドはCMakeの設定時に即座に実行されるのに対して、add_custom_commandコマンドはビルド時に実行される。

例えば、外部のプロトコルバッファコンパイラを使用してソースファイルを生成することが挙げられる。

 add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.pb.cc
    COMMAND protoc --cpp_out=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/message.proto
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/message.proto
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMENT "Generating protocol buffer code"
 )


パスの扱いでは、WORKING_DIRECTORYオプションを設定することにより、相対パスの問題を回避する必要がある。
また、エラーハンドリングにおいて、execute_processコマンドでは、戻り値を格納する変数を使用して実行結果を確認することにより、必要に応じてエラー処理を行うべきである。

依存関係の管理では、add_custom_commandコマンドを使用する場合は、DEPENDSオプションを設定することにより、必要な依存関係を正しく指定することが重要である。


execute_processコマンド

外部コマンドを実行して戻り値を取得することができる。
戻り値が0以外の場合は、エラーが発生したことを示す。

 execute_process(COMMAND <コマンド名 または コマンドのパス> RESULT_VARIABLE <戻り値を格納する変数>)


例えば、lsコマンドでは、戻り値が0ではない場合はエラーメッセージが出力される。
以下の例では、変数名LS_RESULTには、lsコマンドの戻り値が格納される。

 # lsコマンドを実行して戻り値を取得する場合
 
 execute_process(COMMAND ls RESULT_VARIABLE LS_RESULT)
 if(LS_RESULT)
    message("ls command failed with error code ${LS_RESULT}")
 endif()


以下の例では、Gitのバージョン管理システムからタグ情報を取得している。
ビルドバージョンの自動生成やバージョン情報の埋め込み等を行うことができる。

 execute_process(
    # Gitのタグ情報を取得するコマンドを実行
    COMMAND git describe --tags
 
    # コマンドを実行するディレクトリをプロジェクトのルートディレクトリに設定
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 
    # コマンドの終了コードを GIT_RESULT 変数に格納
    RESULT_VARIABLE GIT_RESULT
 
    # コマンドの標準出力を GIT_VERSION 変数に格納
    OUTPUT_VARIABLE GIT_VERSION
 
    # エラーが発生した場合の出力を GIT_ERROR 変数に格納
    ERROR_VARIABLE GIT_ERROR
 
    # 出力から末尾の空白文字や改行を削除
    OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 
 # コマンドが失敗した場合 (終了コードが0以外) の処理
 if(NOT GIT_RESULT EQUAL 0)
    # 警告メッセージを表示
    message(WARNING "Git command failed : ${GIT_ERROR}")
 endif()


以下の例では、ls -lコマンドでディレクトリ内のファイル一覧を詳細形式で取得して、その出力をgrep ".txt"コマンドにパイプで渡して、テキストファイルのみを抽出している。
また、その結果を変数TEXT_FILESに格納している。

 execute_process(
    # ls -lコマンドでファイル一覧を取得
    COMMAND ls -l
 
    # ファイル一覧からテキストファイル (.txt拡張子) を含む行を抽出
    COMMAND grep ".txt"
 
    # コマンドを実行するディレクトリを設定
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 
    # コマンドの実行結果 (終了コード) を格納
    # 0 : コマンドが正常に終了
    # 非0 : コマンドが何らかのエラーで終了
    RESULT_VARIABLE SEARCH_RESULT
 
    # 結果を TEXT_FILES 変数に格納
    OUTPUT_VARIABLE TEXT_FILES
 
    # コマンドの標準エラー出力 (stderr) の内容を格納
    # コマンド実行中にエラーが発生した場合、そのエラーメッセージがこの変数に格納される
    ERROR_VARIABLE SEARCH_ERROR
 )
 
 if(SEARCH_RESULT EQUAL 0)
    message(STATUS "Command executed successfully")
 else()
    message(WARNING "File search failed : ${SEARCH_ERROR}")
 endif()