CMake 簡易まとめ


autotools に比べてとても使いやすい。

CMakeLists.txt

ビルド対象のディレクトリーに CMakeLists.txt を配置することで cmake コマンドが対象だと認識してくれるようになる。

最低限必要な設定は次になる。

  1. cmake_minimum_required
    • CMakeLists.txt に記載されている内容を実行するにあたって必要な CMake のバージョンを明示する
  2. add_executable
    • 実行ファイル名と、そのビルドに必要な c / cpp ファイルの指定
    • ヘッダーファイルはここに指定しなくても、更新すると勝手に認識してリビルド対象にしてくれる
  3. target_link_libraries
    • リンクするライブラリーの指定
    • gcc に -lfoo と指定していた場合、 foo とだけ書く

ビルド対象の分割

複数のビルド対象がある場合、ひとつの CMakeLists.txt でアレコレやろうとするとこんがらがるので、ディレクトリーを切ってわける。
たとえばこんな感じ。

  • /path/to/your/project/
    • CMakeLists.txt
    • commandA/
      • CMakeLists.txt
      • src/
    • commandB/
      • CMakeLists.txt
      • src/

で、トップの CMakeLists.txt で add_subdirectory を使って下のディレクトリーをビルド対象に加えてやる。

# add_subdirectory でビルド対象追加
cmake_minimum_required(VERSION 2.8)

add_subdirectory(commandA)
add_subdirectory(commandB)

こうすると cmake をトップに対して指定するだけで配下のディレクトリーもビルド対象になる。

ビルド

その他のファイルと混じらないよう、ビルド用のディレクトリーを作成してその中で走らせるのが定石 ?
/path/to/your/sources/ に CMakeLists.txt が存在すると仮定する。

# ビルド時コマンド
cd /path/to/your/sources
mkdir build
cd build
cmake ..

これで Makefile が出力されるので make する。
実行ファイルは同一ディレクトリーにできるけど、 add_subdirectory したものは同名のディレクトリーが作成されて、その下にできる。
上記の例でいうとこんな感じ。

  • /path/to/your/project/
    • build/
      • commandA/
        • commandA 実行ファイル
      • commandB/
        • commandB 実行ファイル
    • CMakeLists.txt
    • commandA/
      • CMakeLists.txt
      • src/
    • commandB/
      • CMakeLists.txt
      • src/

コンパイルオプション

コンパイラーに渡したいオプションを指定する場合は変数 CMAKE_C_FLAGS / CMAKE_CXX_FLAGS を使う。
CMAKE_C_FLAGS が C 用、 CMAKE_CXX_FLAGS が C++ 用。

# gcc -Wall オプションを指定する
set(CMAKE_CXX_FLAGS "-Wall")

モード指定

Debug や Release などモードを切り替えたい場合、 cmake コマンド実行時に -D オプションで CMAKE_BUILD_TYPE シンボルを書き換えることで実現できる。

# Release モードでビルドする
cmake -DCMAKE_BUILD_TYPE=Release ..

選択可能なモードの一覧は次。

  • 指定なし
    • 初期状態で CMAKE_BUILD_TYPE シンボルを書き換えないとこの状態
    • 一度でも他の値で書き換えるとずっと記憶するので、あらためて指定なしにしたい場合は -DCMAKE_BUILD_TYPE= とする
  • Debug
    • CMAKE_C_FLAGS / CMAKE_CXX_FLAGS に加えて変数 CMAKE_C_FLAGS_DEBUG / CMAKE_CXX_FLAGS_DEBUG の値も使われる
  • Release
    • CMAKE_C_FLAGS / CMAKE_CXX_FLAGS に加えて変数 CMAKE_C_FLAGS_RELEASE / CMAKE_CXX_FLAGS_RELEASE の値も使われる
  • RelWithDebInfo
    • 最適化しつつデバッグ用情報も付加するためのモード
    • CMAKE_C_FLAGS / CMAKE_CXX_FLAGS に加えて変数 CMAKE_C_FLAGS_RELWITHDEBINFO / CMAKE_CXX_FLAGS_RELWITHDEBINFO の値も使われる
  • MinSizeRel
    • 実行ファイルのサイズを一番小さくするためのモード
    • CMAKE_C_FLAGS / CMAKE_CXX_FLAGS に加えて変数 CMAKE_C_FLAGS_MINSIZEREL / CMAKE_CXX_FLAGS_MINSIZEREL の値も使われる

というわけで CMAKE_C_FLAGS / CMAKE_CXX_FLAGS に共通するオプションを、その他に目的別のオプションを指定すると幸せになれる。

プロジェクト名

project() でプロジェクト名と使用言語を指定できる。

プロジェクト名を指定することで別プロジェクトから読み込んだりできる。

使用言語はデフォルトだと C と CXX になるらしい。
ここを明示しないと C++ しか使わないのに C 言語用のコマンドを探索したりと若干無駄が多くなる。

サンプル

ここまでを踏まえた gcc C++11 向けのサンプル。
次の定義のみ変えればすぐに使えるはず。

  • project
  • add_executable
  • target_link_libraries

CMAKE_CXX_FLAGS に指定してるオプションについては次を参照。

CMakeLists.txt
cmake_minimum_required(VERSION 2.8)

project(MyProject CXX)

set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic -Wcast-align -Wcast-qual -Wconversion -Wdisabled-optimization -Wendif-labels -Wfloat-equal -Winit-self -Winline -Wlogical-op -Wmissing-include-dirs -Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual -Wpacked -Wpointer-arith -Wredundant-decls -Wshadow -Wsign-promo -Wswitch-default -Wswitch-enum -Wunsafe-loop-optimizations -Wvariadic-macros -Wwrite-strings ")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0 -pg")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG -march=native")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g3 -Og -pg")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -s -DNDEBUG -march=native")

add_executable(my-command
    main.cpp
    my-class.cpp)

target_link_libraries(my-command
    my-lib)