「CMake - 外部コマンド」の版間の差分
編集の要約なし |
|||
36行目: | 36行目: | ||
execute_processコマンド / add_custom_commandコマンドの違いは実行タイミングである。<br> | execute_processコマンド / add_custom_commandコマンドの違いは実行タイミングである。<br> | ||
execute_processコマンドはCMakeの設定時に即座に実行されるのに対して、add_custom_commandコマンドはビルド時に実行される。<br> | execute_processコマンドはCMakeの設定時に即座に実行されるのに対して、add_custom_commandコマンドはビルド時に実行される。<br> | ||
<br> | <br> | ||
パスの扱いでは、<code>WORKING_DIRECTORY</code>オプションを設定することにより、相対パスの問題を回避する必要がある。<br> | パスの扱いでは、<code>WORKING_DIRECTORY</code>オプションを設定することにより、相対パスの問題を回避する必要がある。<br> | ||
138行目: | 127行目: | ||
<br><br> | <br><br> | ||
== add_custom_commandコマンド == | |||
特に、<code>VERBATIM</code>オプションは重要であり、シェルによる引数の解釈の問題を回避することができる。<br> | |||
このオプションは、コマンドライン引数をそのまま使用することを保証する。<br> | |||
<br> | |||
以下の例では、外部のプロトコルバッファコンパイラを使用してソースファイルを生成することが挙げられる。<br> | |||
<br> | |||
<syntaxhighlight lang="cmake"> | |||
add_custom_command( | |||
# 生成される出力ファイルを指定 | |||
# ${CMAKE_CURRENT_BINARY_DIR}はビルドディレクトリを指す | |||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_code.cpp # 生成されるC++ソースファイル | |||
${CMAKE_CURRENT_BINARY_DIR}/generated_code.h # 生成されるヘッダーファイル | |||
# 実行するコマンドとその引数を指定 | |||
COMMAND code_generator # 外部コマンド code_generator | |||
--input ${CMAKE_CURRENT_SOURCE_DIR}/input.def # 入力ファイルのパス | |||
--output ${CMAKE_CURRENT_BINARY_DIR}/generated_code # 出力ファイルのベース名 | |||
# 主要な入力依存ファイルを指定 | |||
# このファイルが変更された場合、コマンドが再実行される | |||
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/input.def | |||
# その他の依存関係を指定 | |||
# この場合、code_generator実行ファイル自体への依存関係を示す | |||
DEPENDS code_generator | |||
# コマンドを実行するディレクトリを指定 | |||
# ${CMAKE_CURRENT_BINARY_DIR}はビルドディレクトリを指す | |||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | |||
# ビルド時に表示されるメッセージを指定 | |||
COMMENT "Generating source code from input.def" | |||
# コマンドライン引数をそのまま使用することを指定 | |||
# シェルによる引数の解釈の問題を回避するために重要なオプション | |||
VERBATIM | |||
) | |||
# 生成されたファイルを使用するターゲットを定義 | |||
add_library(my_library | |||
${CMAKE_CURRENT_BINARY_DIR}/generated_code.cpp | |||
${CMAKE_CURRENT_BINARY_DIR}/generated_code.h | |||
) | |||
# 生成されたファイルへの依存関係を確実にする | |||
add_dependencies(my_library code_generator) | |||
</syntaxhighlight> | |||
<br> | |||
* MAIN_DEPENDENCY | |||
*: 主要な入力ファイルを指定する。 | |||
* DEPENDS | |||
*: その他の依存関係 (他のファイルやターゲット) を指定できる。 | |||
* OUTPUT | |||
*: 指定したファイルは自動的にビルドシステムの依存関係グラフに組み込まれ、必要な場合にのみコマンドが実行される。 | |||
<br> | |||
<u>※注意</u><br> | |||
<u>add_custom_commandコマンドで生成されたファイルを実際にビルドシステムで使用する場合、<code>add_custom_target</code>コマンドや<code>target_sources</code>コマンド等で明示的に組み込む必要がある。</u><br> | |||
<br><br> | |||
{{#seo: | {{#seo: |
2025年1月13日 (月) 04:42時点における最新版
概要
外部コマンドを実行するための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コマンドはビルド時に実行される。
パスの扱いでは、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()
add_custom_commandコマンド
特に、VERBATIM
オプションは重要であり、シェルによる引数の解釈の問題を回避することができる。
このオプションは、コマンドライン引数をそのまま使用することを保証する。
以下の例では、外部のプロトコルバッファコンパイラを使用してソースファイルを生成することが挙げられる。
add_custom_command(
# 生成される出力ファイルを指定
# ${CMAKE_CURRENT_BINARY_DIR}はビルドディレクトリを指す
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_code.cpp # 生成されるC++ソースファイル
${CMAKE_CURRENT_BINARY_DIR}/generated_code.h # 生成されるヘッダーファイル
# 実行するコマンドとその引数を指定
COMMAND code_generator # 外部コマンド code_generator
--input ${CMAKE_CURRENT_SOURCE_DIR}/input.def # 入力ファイルのパス
--output ${CMAKE_CURRENT_BINARY_DIR}/generated_code # 出力ファイルのベース名
# 主要な入力依存ファイルを指定
# このファイルが変更された場合、コマンドが再実行される
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/input.def
# その他の依存関係を指定
# この場合、code_generator実行ファイル自体への依存関係を示す
DEPENDS code_generator
# コマンドを実行するディレクトリを指定
# ${CMAKE_CURRENT_BINARY_DIR}はビルドディレクトリを指す
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
# ビルド時に表示されるメッセージを指定
COMMENT "Generating source code from input.def"
# コマンドライン引数をそのまま使用することを指定
# シェルによる引数の解釈の問題を回避するために重要なオプション
VERBATIM
)
# 生成されたファイルを使用するターゲットを定義
add_library(my_library
${CMAKE_CURRENT_BINARY_DIR}/generated_code.cpp
${CMAKE_CURRENT_BINARY_DIR}/generated_code.h
)
# 生成されたファイルへの依存関係を確実にする
add_dependencies(my_library code_generator)
- MAIN_DEPENDENCY
- 主要な入力ファイルを指定する。
- DEPENDS
- その他の依存関係 (他のファイルやターゲット) を指定できる。
- OUTPUT
- 指定したファイルは自動的にビルドシステムの依存関係グラフに組み込まれ、必要な場合にのみコマンドが実行される。
※注意
add_custom_commandコマンドで生成されたファイルを実際にビルドシステムで使用する場合、add_custom_target
コマンドやtarget_sources
コマンド等で明示的に組み込む必要がある。