CMake : Custom Target 調べてみた


CMakeをマスターするには、custom_targetをマスターする必要がありそうです。
といわけで、チュートリアル作ってみました。

Step1

カスタムターゲットを追加するには、add_custom_targetコマンドを使います。
一番簡単な例をやってみましょう。下記のようなCMakeListsを用意することで、ターゲットhello_cmakeを追加できます。

CMakeLists.txt
add_custom_target(hello_cmake)

いつもどおり、cmakeを実行します。

mkdir build
cd build
cmake ..

ここで、

make help

と実行してみてください。

$ make help
The following are some of the valid targets for this Makefile:
... all (the default if no target is provided)
... clean
... depend
... rebuild_cache
... edit_cache
... hello_cmake

一番下に、先ほど追加したターゲットhello_cmakeが追加されてますね。このターゲットをビルドしてみましょう。

$ make hello_cmake
Scanning dependencies of target hello_cmake
Built target hello_cmake

hello_cmakeをビルドしたようです。ですが、ビルド時に実行するコマンドを指定してないので実際には何もしてません。

Step2

hello_cmakeビルド時に実行するコマンドを指定しましょう。
ここでは、echo Hello CMakeを実行してみます。
先ほどのCMakeLists.txtを以下のように書き換えてください。

add_custom_target(hello_cmake echo Hello CMake)

もう一度hello_cmakeをビルドしてみましょう。

$ make hello_cmake
Scanning dependencies of target hello_cmake
Hello CMake!!
Built target hello_cmake

echo Hello CMakeが実行されてHello CMakeが標準出力に表示されました。

複数のコマンドを実行したい場合は

add_custom_target(hello_cmake echo first
                  COMMAND echo second
                  COMMAND echo third)

のようにCOMMANDの後にコマンドを書いていきます。

add_custom_target(hello_cmake
                  COMMAND echo first
                  COMMAND echo second
                  COMMAND echo third)

のように最初のコマンドにもCOMMANDをつけても大丈夫です。こっちのほうがわかりやすいかも。

Step3

このターゲットに「依存関係」をつけていきます。
「依存関係」って、make系のコマンドにとってはかなり肝となる概念なんですが、、、ちと説明しずらい。

というわけで、いきなり例題にいきます。
* 3つのTarget "child" "mother" "fater"を作成
* "child"は、"mather"と"father"に依存
という例をやってみます。

まず、依存関係の無いCMakeLists.txtを最初に作りましょう

add_custom_target(child echo I am a child)
add_custom_target(father echo I am a father)
add_custom_target(mather echo I am a mother)

cmake後、make helpして、ターゲットが増えていることを確認してください。

その後、make childmake fathermake motherも実行してみてください。

$ make child
Scanning dependencies of target child
I am a child
Built target child

make childしたら、echo I am a childが実行されてます。

ここで、「childをビルドするときには事前にfatherとmotherもビルドしたい」という要望があるとします。これを解決するのが依存関係です。「childを、fatherとmotherに依存」させれば、childのビルド時には、事前にfatherとmotherがビルドされるようになります。

実際にCMakeLists.txtを改造して「依存関係」をつけてみましょう。下記のようにすることで、childが、fatherとmotherに依存するようになります。

add_custom_target(father echo I am a father)
add_custom_target(mother echo I am a mother)
add_custom_target(child echo I am a child
                  DEPENDS father mother)    # fatherとmotherに依存

make childしてみましょう。どうなるかというと、、

$ make child
I am a father
Built target father
I am a mother
Built target mother
I am a child
Built target child

I am a childの前に、I am a fatherI am a motherが表示されていますね。
ターゲットchildがfatherとmotherに依存するように設定したため、childターゲットのビルドの前に、fatherとmotherのビルドが行われているのです。
なお、make fathermake motherした場合はそれぞれfather、motherだけがビルドされます。father、motherは何にも依存していないからです。