Help us understand the problem. What is going on with this article?

CMakeの使い方〜覚書〜

More than 1 year has passed since last update.

cmakeが好きだが、使い方は忘れることが多い。「あれどうやって書いたっけ?」という情報を中心に覚書として残しておく。

基本形

実行ファイルの作成

main.cppのみ

main.cppから実行ファイルを作成する。CMakeList.txtは、main.cppと同じ場所にひとつだけの構成。

main.cppのみ
.
├── CMakeLists.txt
└── main.cpp
CMakeList.txt
cmake_minimum_required(VERSION 3.5)
project (Project1)
add_executable(
        Target1
        main.cpp
)

ソースファイルはsrcとincludeに分ける

CMakeList.txtは、ディレクトリのトップレベル階層にひとつ。ソースファイルは、CMakeList.txtとは別のディレクトリに配置。

ソースファイルはsrcとincludeに分ける
.
├── CMakeLists.txt
├── include/
│   └── my_math.h
└── src/
    ├── main.cpp
    └── my_math.cpp
CMakeList.txt
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を使う

./CMakeList.txt
.
├── CMakeLists.txt
├── src/
│   ├── CMakeLists.txt
│   ├── main.cpp
│   ├── my_math.cpp
│   └── my_math.h
└── test/
    ├── CMakeLists.txt
    └── test.cpp
./CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(Project1)
enable_testing()
add_subdirectory(src)
add_subdirectory(test)
add_test(
        NAME MyTests
        COMMAND MyTest
)
./src/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
add_library(MyLib1 STATIC my_math.cpp)
add_executable(Target1 main.cpp)
target_link_libraries(Target1 MyLib1)
./test/CMakeLists.txt
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_DIRPROJECT_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_DIRSGTK3_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に詳しい説明がある。

ちなみに、例で示したデバッグオプションの指定は、以下のように設定したのと同じ意味になる。

方法A
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

ビルドディレクトリのフルパス。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away