C
C++
CMake

ごく簡単なcmakeの使い方

More than 3 years have passed since last update.

なんかcmakeの使い方わからんかった、という記事を最近見たのでごく簡単な部分をまとめる。


単一のソースファイルの場合

${PROJECT_HOME}/

main.cpp

の時は以下の2行を書くだけでOK:

cmake_minimum_required(VERSION 2.8)

add_executable(Main main.cpp)

これをCMakeLists.txtとしてmain.cppと同じディレクトリに置く:

(CMakeList*s*.txt な事に注意)

${PROJECT_HOME}/

main.cpp
CMakeLists.txt

同じディレクトリで

cmake . # .を忘れずに

make

を実行すれば実行ファイルMainが作成される。

コンパイルフラグが必要な場合は2通り方法がある:


add_definitions

環境に依らず必要な場合はadd_definitionsを使う

cmake_minimum_required(VERSION 2.8)

add_definitions("-Wall -std=c++11") # <= new
add_executable(Main main.cpp)


ccmake (cmake-cli), cmake-gui

コンパイル毎に変えたい場合はccmakeコマンドあるいはcmake-guiコマンドを使う

ccmake .

cmake-gui .

cmake本体とは別パッケージになっている事が多いのでapt,yum,pacman等で検索する。

ccmakeを実行すると

CMAKE_BUILD_TYPE

CMAKE_INSTALL_PREFIX

の2つだけ表示される。変更したいのは

CMAKE_CXX_FLAGSであって、これはtを入力すると出現する。

ここで必要なフラグを調整する。


少数のソースとヘッダの場合

${PROJECT_HOME}/

main.cpp
mod.hpp
mod_func1.cpp
mod_func2.cpp

この場合も同じディレクトリに以下のCMakeLists.txtを追加する。

cmake_minimum_required(VERSION 2.8)

add_executable(Main
main.cpp
mod_func1.cpp
mod_func2.cpp
)

add_executableに引数を追加した。

ヘッダの依存関係はcmakeが勝手に解決してくれる


ディレクトリが分かれている場合

${PROJECT_HOME}/

main.cpp
mod1.hpp
mod1/
func1.cpp
func2.cpp
mod2.hpp
mod2/
func1.cpp
func2.cpp

このくらいになってくるとcmakeによる管理の効果がでてくる。

この場合、


  • 単一のCMakeLists.txtを使う方法

  • 各ディレクトリにCMakeLists.txtを作る方法

がある。個人的には後者がおすすめである。


単一のCMakeLists.txtを用いる

${PROJECT_HOME}/

CMakeLists.txt <- new
main.cpp
mod1.hpp
mod1/
func1.cpp
func2.cpp
mod2.hpp
mod2/
func1.cpp
func2.cpp

上述のケースと同様にプロジェクトのトップにCMakeLists.txtを作り、

cmake_minimum_required(VERSION 2.8)

add_executable(Main
main.cpp
mod1/func1.cpp
mod1/func2.cpp
mod2/func1.cpp
mod2/func2.cpp
)

のようにする。上述のケースと本質的に同じである。


各ディレクトリにCMakeLists.txtを作る

${PROJECT_HOME}/

CMakeLists.txt <- new
main.cpp
mod1.hpp
mod1/
CMakeLists.txt <- new
func1.cpp
func2.cpp
mod2.hpp
mod2/
CMakeLists.txt <- new
func1.cpp
func2.cpp


CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

add_subdirectory(mod1) # <- new
add_subdirectory(mod2) # <- new
add_executable(Main main.cpp)
target_link_libraries(Main Mod1 Mod2) # <- new


mod1/CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

add_library(Mod1 STATIC
func1.cpp
func2.cpp
)


mod2/CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

add_library(Mod2 STATIC
func1.cpp
func2.cpp
)

のようにする。少し手間かもしれないが、この方がモジュール化が分りやすいし増えてくると管理が楽。

cmakeでは静的ライブラリが簡単に作れ、さらにリンクも簡単。


add_library

STATICを付けると静的ライブラリを作る。

上の例だとUnix上ではmod1/libMod1.a,mod2/libMod2.aを作る。


target_link_libraries

ライブラリを実行ファイルにリンクする。

具体的にはフラグに-lMod1 -lMod2が追加される形。

名前の解決はcmakeが行い、cmakeは自分で作ったライブラリの名前は

(ディレクトリ関係なく)グローバルに保持するので、

ここでmod1/Mod1のようにする必要はない。


add_subdirectory

ディレクトリをcmakeの管理に追加する。

そのディレクトリにCMakeLists.txtが存在しないとエラーになる。

add_definitionssetによる変数の定義は子ディレクトリには伝わりますが、

親ディレクトリには伝わらない。

cmakeにおける変数の扱い


Further Reading

以上、cmakeのごく簡単な使い方を説明しました。

自分が使うだけの簡単なツールをbuildするのには十分な情報だったと思います。

cmakeにはctestと呼ばれるテスト実行支援ツールもあります。

cmakeは比較的普及しているツールですが、日本語の情報が非常に乏しいです。

最近cmake3.0がリリースされ、それに伴いドキュメントが整備されました

cmakeはmakeの出力をかっこよく隠すので、表示したい時はCMakeLists.txtの先頭に

set(CMAKE_VERBOSE_MAKEFILE 1)

とするとmakeの完全な実行コマンドが見えます。デバッグのお供に。