CMake - 外部コマンド
概要
外部コマンドを実行するための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()