Posted at
CMakeDay 16

CMake: スクリプトモード

More than 3 years have passed since last update.


はじめに

みなさん、こんにちは。今回は CMake に用意されているスクリプトモードなる動作モードについて書いていきます。


スクリプトモードとは何か?

普段使用している CMake ファイルCMakeLists.txtcmake .によって実行し、Makefileなどのビルドシステムを生成するために使用していました。これに対してhoge.cmakeといったスクリプトファイルはcmakeコマンドに-Pオプションを付与してcmake -P hoge.cmakeといった形で利用します。このスクリプトファイルは、ビルドシステムの生成に特化したものではなく、シェルスクリプトのように汎用的に使用することができます。


hoge.cmake

message(1)


$ cmake -P hoge.cmake # 1

また、ファイルの先頭に Shebang を記述し、実行権限を付与することで実行ファイルとして扱うことができます。


hoge.cmake

#!/usr/bin/env cmake -P

message(1)

$ chmod +x hoge.cmake

$ ./hoge.cmake # 1


スクリプトモードと通常の動作モードとの差異

このスクリプトモードですが、通常の動作と比較すると以下の違いがあります。


ビルドシステムを生成するコマンドは使用できない

add_executable()target_link_libraries()といったビルドシステムを生成するコマンドは使用できません。また、ほかのディレクトリのCMakeLists.txtを読み込むadd_subdirectory()も使用できません。


hoge.cmake

add_executable(hoge hoge.cpp)


$ cmake -P hoge.cmake

CMake Error at hoge.cmake:1 (add_executable):
Command add_executable() is not scriptable


キャッシュファイルを生成しない

CMakeCache.txtといったキャッシュファイルを生成しません。しかし、キャッシュ変数は普段と同様に使用できます。したがって、スクリプトモードにおけるキャッシュ変数はグローバル変数のようなものになります。


ディレクトリスコープはひとつだけ

add_subdirectory()が使用できないので、ディレクトリスコープはスクリプト全体でひとつだけとなります。


スクリプトモードの用途

このスクリプトモードの用途は様々ですが、ビルドの補助スクリプトとして利用すると便利です。

例えば、開発中にプロジェクトのビルドとテストを行う場合、ソースツリーがCMakeCache.txtなどで汚染されたくないので、ビルドディレクトリを作って out-of-source ビルドをします。これには以下の手順を踏む必要があります。

$ mkdir build # なければ作る

$ cd build
$ cmake .. # ビルドシステムを生成してないなら実行
$ make all test ARGS='-V'

毎回これを行うのは少々めんどうです。かといって、この一連の作業をシェルスクリプトや Ruby スクリプトなどにすると、依存する環境やツールが増えてしまいます。そこで、以下のような CMake スクリプトを用意し、スクリプトモードで動作させることでこの問題を解決します。


test.cmake

cmake_minimum_required(VERSION 3.0.2)

set(build_dir ${CMAKE_CURRENT_LIST_DIR}/build)

if(NOT EXISTS ${build_dir})
file(MAKE_DIRECTORY ${build_dir})
execute_process(
COMMAND ${CMAKE_COMMAND} ..
WORKING_DIRECTORY ${build_dir}
)
endif()

execute_process(
COMMAND make all test "ARGS='${CMAKE_ARGV3}'"
WORKING_DIRECTORY ${build_dir}
)


$ cmake -P test.cmake -V

Shebang を記述し、実行権限を付与すれば、特定の環境でさらに便利に使用できます。

$ ./test.cmake -V


おわりに

以上、スクリプトモードでした。CMake は意外といろんなことができるので、補助的なスクリプトは CMake スクリプトとして作成することによって、依存するツールを減らせ、ポータビリティにできます。

明日は、mrk_21 さんの『CMake: モジュール』です。