add_custom_command を使用してビルド中にファイルを生成しようとしています。コマンドが実行されたようには見えなかったので、このテストファイルを作成しました。
cmake_minimum_required( VERSION 2.6 )
add_custom_command(
OUTPUT hello.txt
COMMAND touch hello.txt
DEPENDS hello.txt
)
私は走ってみました:
cmake .
make
そして、hello.txtは生成されませんでした。何が悪いのでしょうか?
以下を追加します。
add_custom_target(run ALL
DEPENDS hello.txt)
Makefileに慣れている場合、これは次のことを意味します。
all: run
run: hello.txt
_add_custom_target(run ALL ...
_ソリューションは、構築しているターゲットが1つしかない単純な場合に機能しますが、トップレベルのターゲットが複数ある場合は機能しません。アプリとテスト。
ユニットテストが外部のものに依存しないように、いくつかのテストデータファイルをオブジェクトファイルにパッケージ化しようとしたときに、この同じ問題に遭遇しました。 _add_custom_command
_と_set_property
_でいくつかの追加の依存関係の魔法を使用して解決しました。
_add_custom_command(
OUTPUT testData.cpp
COMMAND reswrap
ARGS testData.src > testData.cpp
DEPENDS testData.src
)
set_property(SOURCE unit-tests.cpp APPEND PROPERTY OBJECT_DEPENDS testData.cpp)
add_executable(app main.cpp)
add_executable(tests unit-tests.cpp)
_
そのため、unit-tests.cppがコンパイルされる前、およびtestData.srcが変更されるたびにtestData.cppが生成されます。呼び出しているコマンドが本当に遅い場合は、アプリターゲットのみをビルドするときに、そのコマンド(テスト実行可能ファイルのみが必要とする)が終了するのを待つ必要がないという追加のボーナスを得ます。
上には表示されていませんが、${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories()
を注意深く適用すると、ソースツリーで生成されたファイルをきれいに保つことができます。
既存の2つの回答の問題は、依存関係をグローバルにする(add_custom_target(name ALL ...)
)か、特定の単一ファイル(set_property(...)
)に割り当てるかです。依存関係として必要なファイル。代わりに、必要なのは、別のターゲットの依存関係を作成できるターゲットです。
これを行う方法は、_add_custom_command
_を使用してルールを定義し、次に_add_custom_target
_を使用してそのルールに基づいて新しいターゲットを定義することです。次に、そのターゲットを_add_dependencies
_を介して別のターゲットの依存関係として追加できます。
_# this defines the build rule for some_file
add_custom_command(
OUTPUT some_file
COMMAND ...
)
# create a target that includes some_file, this gives us a name that we can use later
add_custom_target(
some_target
DEPENDS some_file
)
# then let's suppose we're creating a library
add_library(some_library some_other_file.c)
# we can add the target as a dependency, and it will affect only this library
add_dependencies(some_library some_target)
_
このアプローチの利点:
some_target
_はALL
の依存関係ではありません。つまり、特定のターゲットで必要な場合にのみビルドします。 (add_custom_target(name ALL ...)
は、すべてのターゲットに対して無条件にビルドします。)some_target
_はライブラリ全体の依存関係であるため、そのライブラリ内のすべてのファイルの前にビルドされます。つまり、ライブラリに多くのファイルがある場合、それらすべてに対して_set_property
_を実行する必要はありません。add_custom_command
_にDEPENDS
を追加すると、入力が変更されたときにのみ再構築されます。 (これをadd_custom_target(name ALL ...)
を使用するアプローチと比較してください。コマンドが必要かどうかに関係なく、すべてのビルドでコマンドが実行されます。)このように機能する理由の詳細については、次のブログ投稿を参照してください。 https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom -コマンド/