67

ビルド中に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は生成されませんでした。私は何を間違えましたか?

4

3 に答える 3

70

この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()と、ソースツリーから生成されたファイルをクリーンに保つことができます。

于 2011-07-22T04:07:40.260 に答える
42

以下を追加します。

add_custom_target(run ALL
    DEPENDS hello.txt)

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

all: run
run: hello.txt
于 2010-05-30T20:21:39.027 に答える
34

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、それらのすべてに対して行う必要はありません。
  • に追加DEPENDSするとadd_custom_command、入力が変更されたときにのみ再構築されます。add_custom_target(name ALL ...)(これを、必要かどうかに関係なく、すべてのビルドでコマンドが実行される場所を使用するアプローチと比較してください。)

物事がこのように機能する理由の詳細については、次のブログ投稿を参照してください:https ://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/

于 2018-08-16T16:01:58.640 に答える