2019-01-30 - 2019-04-29 (update) |
|
|
CMakeの基本的な使い方をメモします.
*CMakeとは
コンパイラの設定を自動化するためのC/C++用の補助ツールです.
例えば,C/C++で記述したプログラムを,何かしらのコンパイラでビルドしたいとします.
それには,「コンパイルしたいファイル(cppやhなど)を追加,参照するライブラリのパスを追加,コンパイラオプションを追加...」等々の設定をする必要があるわけですが,特に複数名で開発を行いたい場合,そういう設定を各自がいちいち行うのは面倒ですしミスが発生する場合もあります.
そこで登場するのがCMakeです.CMakeでは,プログラムに付属してCMake用のファイルを準備さえしておけば,様々なOS・開発環境用に合わせて,ビルドの設定を済ませたプロジェクトファイルを自動で生成することができます.
*CMakeのダウンロード
下記リンクからダウンロードできます.
[link:https://cmake.org/download/]
Binary distributions: と書いてあるリストからOSに合ったファイルをダウンロードしてください.
*CMakeの簡単な例
まず,簡単な例から説明します.下記に示すように,test/src/の下にいくつかC/C++のファイルが置かれていて,それをコンパイルするようなプロジェクトファイルを生成したいとします.
{#
test/
├ build/
├ src/
│ ├ main.cpp
│ ├ util.cpp
│ └ util.h
└ CMakeList.txt
#}
ここで,CMakeList.txt とあるのがコンパイルのルールを記述したCMake用のファイルです.
今回の場合,以下のように記述します.
CMakeList.txt ・・・①
{#
# プロジェクト名を設定
project(test)
# プロジェクトにプログラムのファイルを追加
add_executable(test src/main.cpp src/util.h src/util.cpp)
#}
これで準備が整いました.それではCMakeを起動させてみます.
[img:cn5k]
{{small:図1 Cmakeの画面}}
CMakeを起動すると図1のようなGUIが表示されます.
GUI上でまずは,「Where is the source code:」の部分にCMakeList.txtがあるディレクトリを指定し,「Where to build the binaries:」の部分にプロジェクトファイルを出力するディレクトリを指定します.
続いて,「Configure」→「Generate」の順にボタンを押して,エラーが表示されていなければ指定したディレクトリにプロジェクトファイルが生成されます.
一度目に「Configure」ボタンを押す時は,出力したいプロジェクトファイルの種類が問われるので,所望の項目を選択します.(VisualStudioやXcodeなどの中から選ぶことになります)
*良く利用する記述
上記のCmakeList.txt①では,単に指定したファイルをプロジェクトに追加するだけでしたが,CMakeListには,それ以外にも様々な設定を記述することができます.ここでは,その中で良く利用するものをいくつか紹介します.
**ファイルを追加する
CmakeList.txt①のadd_executableについてですが,以下のような書き方も可能です.
{#
# 方法1 変数「MY_SOURCE」にファイルパスを設定
set(MY_SOURCE src/main.cpp src/util.h src/util.cpp)
add_executable(test ${MY_SOURCE})
#}
以下のように,変数に次々にパスを追加するような書き方もできます.
{#
set(MY_SOURCE src/main.cpp)
set(MY_SOURCE ${MY_SOURCE} src/util.h)
set(MY_SOURCE ${MY_SOURCE} src/util.cpp)
add_executable(test ${MY_SOURCE})
#}
指定したディレクトリ内からファイルを検索して設定したい場合は,下記のようにワイルドカードを利用した記述も可能です.
{#
# 方法2 ファイルを検索し,変数「MY_SOURCE」に設定
file(GLOB MY_SOURCE src/*.h src/*.cpp)
add_executable(test ${MY_SOURCE})
#}
なお,${...}とあるのは,その行より前に定義した変数であることを表しています.
**ライブラリを利用できるようにする
自前のプログラムで何かしらのライブラリを参照している場合,includeディレクトリとライブラリディレクトリの2つを設定しておく必要があります.また,ライブラリディレクトリの中で利用するライブラリの名前も設定する必要があります.
例えば,以下のように記述することになります.
{#
# ディレクトリを設定
set(MY_INCLUDE_DIRS パス1 パス2)
set(MY_LIB_DIRS パス3)
include_directories(${MY_INCLUDE_DIRS})
link_directories(${MY_LIB_DIRS})
# ライブラリを設定
set(MY_LIBS パス4)
target_link_libraries(test ${MY_LIBS})
#}
**ライブラリを利用できるようにする②
有名なライブラリは,簡単に参照できるような機能が用意されています.
例えばOpenCVの場合,以下のように設定すれば自動でOpenCVのディレクトリを見つけて有効化できます.
{#
# OpenCVのincludeディレクトリとライブラリディレクトリを自動で見つける
find_package(OpenCV REQUIRED)
# 見つけたディレクトリのパスを設定する
include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIB_DIRS})
#}
ただ,めぼしい場所にOpenCVが見つからなかった場合,CMakeのGUI上にエラーが出ます.
その場合は,CMakeのGUI上でマニュアルでパスを入力することになります.
**コンパイルオプションを設定する
コンパイルオプションの種類はいろいろありますが,add_compile_optionsを使って設定可能です.また,CMakeの専用変数 CMAKE_CXX_FLAGS(C言語用)やCMAKE_CXX_FLAGS(C++用)に値を設定しても同じです.
{#
# c++11を明示的に有効化する
add_compile_options(-std=c++11)
# マクロを定義する(プログラム内で#define MY_DEFINE と書くのと同じ)
add_compile_options(-D MY_DEFINE)
#}
{#
# c++11を明示的に有効化する
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# マクロを定義する(プログラム内で#define MY_DEFINE と書くのと同じ)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D MY_DEFINE")
#}
**設定を切り替えられるようにする
if分岐や,option関数を利用して設定を切り替えられるようにします.
以下の例では,所定の機能(今回の場合OpenMP)の有効/無効を切り替えられるようになります.すると,CMakeの「Configure」ボタンを押した後に,GUI上にUSE_OPENMPと書かれたチェックボックスが現れるので,そのチェックを切り替えることで設定の変更が可能になります.
{#
option(USE_OPENMP "USE_OPENMP" ON)
if(USE_OPENMP)
find_package(OpenMP)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
#}
*誰かの書いたCMakeList.txtを参考にする
CMakeの使い方を学習したい場合,CMakeのドキュメント{small:[link:https://cmake.org/documentation/]}を参照する以外に,誰かの書いたCMakeList.txtを参考にするという手があります.
例えばGitHubで公開されているC/C++のリポジトリには,CMakeでプロジェクトを生成できるような準備ができているものが多いので,いろいろと参考になりそうです.
{{small:私の公開しているリポジトリでもCMakeを利用しています.興味があれば覗いてみてください.}}
{{small:GitHub:[link:https://github.com/sanko-shoko/simplesp] }}
>> ご意見・ご質問など お気軽にご連絡ください.info