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
ビルドディレクトリのフルパス。