web-dev-qa-db-ja.com

CMake add_custom_commandが実行されていません

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は生成されませんでした。何が悪いのでしょうか?

52

以下を追加します。

add_custom_target(run ALL
    DEPENDS hello.txt)

Makefileに慣れている場合、これは次のことを意味します。

all: run
run: hello.txt
33
dimba

_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()を注意深く適用すると、ソースツリーで生成されたファイルをきれいに保つことができます。

55
Rian Sanderson

既存の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 -コマンド/

12