cmakeが好きだが、使い方は忘れることが多い。「あれどうやって書いたっけ?」という情報を中心に覚書として残しておく。
基本形
実行ファイルの作成
main.cppのみ
main.cppから実行ファイルを作成する。CMakeList.txtは、main.cppと同じ場所にひとつだけの構成。
.
├── CMakeLists.txt
└── main.cpp
cmake_minimum_required(VERSION 3.5)
project (Project1)
add_executable(
Target1
main.cpp
)
ソースファイルはsrcとincludeに分ける
CMakeList.txtは、ディレクトリのトップレベル階層にひとつ。ソースファイルは、CMakeList.txtとは別のディレクトリに配置。
.
├── CMakeLists.txt
├── include/
│ └── my_math.h
└── src/
├── main.cpp
└── my_math.cpp
cmake_minimum_required(VERSION 3.5)
project(Project1)
set(SRC_DIR ${PROJECT_SOURCE_DIR}/src)
set(INC_DIR ${PROJECT_SOURCE_DIR}/include)
include_directories(
${INC_DIR}
)
add_executable(
Target1
${SRC_DIR}/main.cpp
${SRC_DIR}/my_math.cpp
)
PROJECT_SOURCE_DIR
は、project()
コマンドでプロジェクト名を定義するとセットされる環境変数で、トップレベル・ディレクトリがセットされる。
ユニットテストの実行
googletestを使う
.
├── CMakeLists.txt
├── src/
│ ├── CMakeLists.txt
│ ├── main.cpp
│ ├── my_math.cpp
│ └── my_math.h
└── test/
├── CMakeLists.txt
└── test.cpp
cmake_minimum_required(VERSION 3.5)
project(Project1)
enable_testing()
add_subdirectory(src)
add_subdirectory(test)
add_test(
NAME MyTests
COMMAND MyTest
)
cmake_minimum_required(VERSION 3.5)
add_library(MyLib1 STATIC my_math.cpp)
add_executable(Target1 main.cpp)
target_link_libraries(Target1 MyLib1)
cmake_minimum_required(VERSION 3.5)
find_package(PkgConfig)
pkg_search_module(GTEST gtest_main REQUIRED)
add_executable(MyTest test.cpp)
target_link_libraries(MyTest MyLib1 ${GTEST_LDFLAGS} gtest_main)
target_compile_options(MyTest PUBLIC ${GTEST_CFLAGS})
REQUIRED
オプションは、エラーがあった時、メッセージを出力して処理を停止させる。
常套句を部品化する
T.B.D. 後日整理したうえで記載する
コマンド
cmake_minimum_required
cmake_minimum_required
は、CMakeLists.txtに記す文法に関するcmakeのバージョン。
cmake_minimum_required(VERSION 3.5)
project
project
は、cmakeプロジェクトの名称。ここ指定した名前は、PROJECT_NAME
にセットされる。同様に、PROJECT_SOURCE_DIR
やPROJECT_BINARY_DIR
がセットされる。
project (Project1)
add_executable
add_executable
は、ビルドターゲットとして実行ファイルを作成する。又、その際に必要なソースファイルを指定する。
add_executable(Target1 main.c)
プロジェクトには、2つ以上のターゲットがあっても良い。
add_executable(Target1 main.c)
add_executable(Target2 main.c)
set_target_properties(Target1 PROPERTIES COMPILE_DEFINITIONS "BUILDTYPE=1")
set_target_properties(Target2 PROPERTIES COMPILE_DEFINITIONS "BUILDTYPE=2")
find_package
find_package
は、外部モジュールの設定をロードする。
find_package(PkgConfig)
例えば、以下のようにX11モジュールをロードすると、X11_LIBRARIES
のような環境変数と値が展開される。
find_package(X11 REQUIRED)
使用できるパッケージは、以下のコマンドで参照できる。
$ cmake --help-module-list | grep -e '^Find'
find_package(PkgConfig)
find_package(PkgConfig)を指定すると、pkg_check_modules
を利用してpkg-configコマンドで参照できる情報をcmakeでも利用できるようになる。
例えば、gtk+-3.0
に関する情報を得るには、以下のように指定する。第一引数は任意の名前。第二引数は、pkg-config --list-all
として表示されるものから選択する。セットされる変数は、マニュアルのFindPkgConfigに説明がある。
pkg_check_modules(GTK3 gtk+-3.0 REQUIRED)
この例では、GTK3_INCLUDE_DIRS
やGTK3_LIBRARIES
という変数に以下の例で示すコマンドの結果が得られる。
$ pkg-config --cflags gtk+-3.0
$ pkg-config --libs gtk+-3.0
pkg_check_modules
で得られる変数は以下の通り。
変数 | 意味 |
---|---|
<XPREFIX>_FOUND | モジュールが見つかると1 |
<XPREFIX>_LIBRARIES | -lで指定するライブラリ |
<XPREFIX>_LIBRARY_DIRS | -Lで指定するライブラリのフルパス |
<XPREFIX>_LDFLAGS | リンカに与えるフラグすべて |
<XPREFIX>_LDFLAGS_OTHER | その他のリンカに与えるフラグ |
<XPREFIX>_INCLUDE_DIRS | -Iで与えるインクルードパス |
<XPREFIX>_CFLAGS | コンパイルフラグすべて |
<XPREFIX>_CFLAGS_OTHER | その他のコンパイルフラグ |
環境変数PKG_CONFIG_PATH
は、cmakeの中でも指定できる。
set(PKG_CONFIG_PATH ${PKG_CONFIG_PATH} /path/to/pkgconfig)
target_include_directories
target_include_directories
は、ターゲットのビルドに必要なヘッダファイルのパスを追加する。
インクルードファイルの指定は、include_directories
もある。target_xxx_yyy は指定した target にのみ影響する。xxx_yyy はその他の処理にも影響を与えるため target_xxx_yyy の使用が推奨されている。つまり、特に全体に共通する設定でない限り、include_directories
でなく、target_include_directories
を使用するのが良い。
target_link_libraries
target_link_libraries
は、ビルドターゲットに必要なライブラリを指定する。
リンクライブラリの指定は、link_libraries
もある。target_xxx_yyy は指定した target にのみ影響する。xxx_yyy はその他の処理にも影響を与えるため target_xxx_yyy の使用が推奨されている。つまり、特に全体に共通する設定でない限り、link_libraries
でなく、target_link_libraries
を使用するのが良い。
target_link_libraries(Target1 ${X11_LIBRARIES})
set_target_properties
set_target_properties
は、ビルドに影響を与えるのプロパティ(以降、ビルドプロパティと呼ぶ)に値をセットする。
set_target_properties(create_window PROPERTIES COMPILE_FLAGS "-O0 -g")
ビルドプロパティは、マニュアルのProperties on Targetsに詳しい説明がある。
ちなみに、例で示したデバッグオプションの指定は、以下のように設定したのと同じ意味になる。
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g")
cmake_print_properties
cmake_print_properties
は、プロパティをデバッグ表示する。
include(CMakePrintHelpers)
cmake_print_properties(TARGETS ModuleB
PROPERTIES
INCLUDE_DIRECTORIES)
CMakePrintHelpersにあるのでモジュールのロード(include(CMakePrintHelpers)
)が必要。
enable_testing
enable_testing
は、指定されているCMakeList.txt以下のユニットテストを有効にする。このコマンドは、トップレベル・ディレクトリのCMakeList.txtに指定する必要がある。
add_test
add_test
は、ctestによるユニットテストを実行する。
add_test(NAME <name> COMMAND <command> [<arg>...]
[CONFIGURATIONS <config>...]
[WORKING_DIRECTORY <dir>])
NAMEで指定された名前のテストを追加する。その際のテスト実行ファイルは、COMMANDで指定する。故に、add_testコマンドでテストを追加する場合、別途、COMMANDで指定した実行ファイルが作られるようにCMakeList.txtに書かれていないといけない。
add_subdirectory
add_subdirectory
は、ビルド対象の下層ディレクトリを追加する。そのディレクトリには、CMakeList.txtを置く必要がある。
set
set
は、カレント変数に値をセットする。unset
コマンドは逆にカレント変数を削除する。
環境変数
PROJECT_NAME
プロジェクト名称。
PROJECT_SOURCE_DIR, <PROJECT-NAME>_SOURCE_DIR
トップレベルのソースパス。
PROJECT_BINARY_DIR, <PROJECT-NAME>_BINARY_DIR
ビルドディレクトリのフルパス。