はじめに
出尽くしてると思いますが、cmakeを使ってみたので使い方と所感を記載します。
インストール
aptやyumでインストールしてください。
sudo yum install cmake
sudo apt-get install cmake
基本的な使い方
とりあえず使ってみる in-sourceビルド
- 各ディレクトリにCMakeList.txtを置く
- トップで
cmake .
を実行 - make, make install
以上です。簡単ですね!
in-sourceビルドの欠点
2018/08/07 @tenmyo さんコメントを元に追記
上記の使い方、実は不便な点があります。まずはビルド前後のディレクトリ内を見てもらいましょう。
$ ls
CMakeLists.txt conf lib LICENSE README script src uninstall.sh
$ ls
CMakeCache.txt CMakeLists.txt lib README uninstall.sh
CMakeFiles conf LICENSE script
cmake_install.cmake install_manifest.txt Makefile src
な、なんかめっちゃファイルが出来てるんですけど
cmakeを使用してビルドをすると、ビルド時に「成果物 + CMakeCache.txt, CMakeFiles等ビルド用のファイル達」を各ディレクトリ内に作成します。
なので、in-sourceビルド(cmake .
指定)をしてしまうとビルド後ソース内がごちゃごちゃに。
この辺りが最初に戸惑うポイントだと思います。
でも大丈夫!cmakeは簡単にソースと成果物を分離出来るんです
採用するならout-of-source!
cmakeはビルド成果物を格納する場所を変えることが出来ます。例えば先ほどの構成にbuild
という空のディレクトリを用意しておいて、以下手順でビルドします。
- 各ディレクトリにCMakeList.txtを置く
-
buildディレクトリに移動して、
cmake ../
を実行 - make, make install
in-sourceとほとんど変わらず簡単ですね。なのにビルド前も後も綺麗なままです!
$ ls
build CMakeLists.txt conf lib LICENSE README script src uninstall.sh
成果物は全部buildディレクトリ内。cleanもrm -rf build/
でOKです。楽ちん!
[@build]$ ls
CMakeCache.txt cmake_install.cmake lib script
CMakeFiles conf Makefile src
また、buildもmake
ではなくcmake —-build buildディレクトリ
で置き換え可能。
make
以外のコマンドでも同じ手順でコンパイルが可能になっています
その他色々なメリットが以下記事に記載されているので、興味ある方はぜひ参照ください
CMake : out-of-sourceビルドで幸せになる
CMakeList.txtの書き方
使い方の説明は終わり。ここからはCMakeList.txtの書き方です。
紹介するその前に
本記事は最新のcmake事情を追えていないため、現在非推奨なオプションが混在しています。
以下の記事で、その理由も含めた詳しい解説がまとめられていますので、参考にしてください。
CMakeスクリプトを作成する際のガイドライン:https://qiita.com/shohirose/items/5b406f060cd5557814e9
(情報古いけど)こんな方法で実現できるよくらいの感覚で見ていただけると幸いです。
共通
- cmakeの保証最低バージョンを指定する。
cmake_minimum_required(VERSION 2.8)
- コンパイルオプションや独自変数を定義する。
コンパイルオプションはadd_definitions
で、
独自変数はset
で指定します。
#defineの指定
add_definitions("-Wall -g -O2")
#defineの指定
set(DPPATH "/usr/local/lib")
set
で定義した変数は、通常のスクリプトと同様${DPPATH}
で利用できます。
後はディレクトリでやりたいことによって記載が変わります。
変数情報
使いそうな変数情報を記載。他にもめっちゃあるみたいですが、よく使うのはこんなもんかな?
他に使いそうなものがあれば追記します。
変数名 | 意味 |
---|---|
CMAKE_SOURCE_DIR | ソースコードのトップディレクトリ。cmake ../とかで指定された場所。 |
CMAKE_BINARY_DIR | cmakeの成果物が置かれるトップディレクトリ |
PROJECT_SOURCE_DIR | projectオプションで指定されたプロジェクトのトップディレクトリ。 |
CMAKE_INSTALL_PREFIX | インストール先のprefix。デフォルトは/usr/local。cmake -DCMAKE_INSTALL_PREFIX= pwd/../local といったオプション指定で変更可能 |
サブディレクトリ指定
ビルド対象のサブフォルダがある場合は以下のように指定すればOK!
add_subdirectory(src)
srcビルド
バイナリを作成する
基本はadd_executable
でOKです。add_executable(バイナリ名 ソース達)。ここではlan_routerが作成されます。
オプションがある場合はadd_definitions
を使ってください。
add_executable(lan_router DHCPConfigurator.cpp GWConfigurator.cpp LANIPManager.cpp LANManager.cpp main.cpp JsonParser.cpp DHCPConfigurator_dnsmasq.cpp)
set
でソースをまとめておく楽ですかね。複数バイナリも作れます。この場合はlan_router_dhcpd, lan_routerが作成されます。
set(SRCS_BASE DHCPConfigurator.cpp GWConfigurator.cpp LANIPManager.cpp LANManager.cpp main.cpp JsonParser.cpp)
#for dhcpd
set(SRCS_DHCPD ${SRCS_BASE} DHCPConfigurator_dhcpd.cpp)
#for dnsmasq
set(SRCS_DNSMASQ ${SRCS_BASE} DHCPConfigurator_dnsmasq.cpp)
add_executable(lan_router_dhcpd ${SRCS_DHCPD})
add_executable(lan_router ${SRCS_DNSMASQ})
ヘッダーパスを追加するなら以下で出来ます。
INCLUDE_DIRECTORIES("/usr/local/include")
ライブラリをリンクする
ライブラリパスはlink_directories
で指定できます。
link_directories("/usr/local/lib")
ライブラリのリンクはtarget_link_libraries
です。target_link_libraries(バイナリ名 ライブラリ達)
1点注意として、この定義はadd_executable
の後にしないといけないです。
target_link_libraries(lan_router lower_layer_director dputil jansson)
ライブラリビルド
srcビルドとの違いはバイナリの指定方法だけ。add_executable
⇒ADD_LIBRARY
に変わります。
この例ではlibeth_landevice.soが作成されます。
ADD_LIBRARY(eth_landevice SHARED ether_device.c device_json_parser.c)
インストール設定
基本はINSTALL
コマンドを使用。ただし、ライブラリ、バイナリ、それ以外によって少しオプションが変わります。
インストール先は${prefix}/DESTINATION
で指定したフォルダか、もしくはフルパス指定です。
バイナリ: 引数3個目にRUNTIMEを指定する。
INSTALL(TARGETS lan_router RUNTIME DESTINATION bin)
ライブラリ: 引数3個目にLIBRARY を指定する。
INSTALL(TARGETS eth_landevice LIBRARY DESTINATION lib)
それ以外(スクリプトやconfファイル): 引数1個目にFILESを指定する。
INSTALL(FILES lan_interface.conf DESTINATION conf PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
パーミッションの指定も可能です。
#read only
INSTALL(FILES lan_interface.conf DESTINATION conf PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
#read write
INSTALL(FILES setting.json DESTINATION conf PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
パーミッションが同じなら複数指定も可能です。
#read/write/execute
INSTALL(FILES firewall.sh firewall_BLACKLIST.sh countryip.sh DESTINATION /root/script PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE)
おまけ: ちょっと凝った使い方
スクリプト実行
こんな感じにmake実行時にスクリプトを実行することが出来ます。
ここではconfの中身をインストール先のprefixに合わせて置換しています。
add_custom_target(create_setting ALL COMMAND "sed" "-e" "\"s@PREFIX@${CMAKE_INSTALL_PREFIX}@g\"" "setting.json.ini" ">" "setting.json")
最初ソースに対しても同じことをしようかと思いましたが、こちらはadd_definitionsで十分ですね。
add_definitions(-DCONF_PATH="${CMAKE_INSTALL_PREFIX}/conf/")
option追加
configureのenableオプションのように、cmake実行時のオプションで変数定義の切り替えも出来るとのことです。
lighttpdから抜粋
option(WITH_LIBEV "libev support for fdevent handlers [default: off]")
if(WITH_LIBEV)
find_package(LibEV REQUIRED)
set(HAVE_LIBEV 1)
endif()
option設定 ccmake
2018/08/07 追記
option追加出来るけど、configureみたいにhelpで一覧見ること出来ないっぽいな~と心の中で思っていたら、@tenmyo さんよりGUIのcmake-gui
とTUI(text user interface)のccmake
というコマンドを教えていただきました!
早速実践。とりあえずオプションいっぱい持ってそうなlighttpdでのccmake結果。cmakeした後に同じディレクトリでccmake cmakeしたディレクトリ
でこんな感じにconfig設定画面が出てきます。
どんなoptionが使えるか、今の設定がどうなっているのかがすぐにわかります!わかりやすい!
ちなみに、ubuntuではccmakeを使うために以下が必要でした。
sudo apt install cmake-curses-gui
所感
-
make
やconfigure
と比べると導入がとにかく簡単 - 最初は何をやっているか分からなかったが、理解すると覚えることも少ないのでいい。
最初の最初だけとっつきにくいけど、使ってしまえばものすごく楽ちん!って感じでした。
2018/08/07 追記
configure
をまとめた時は導入の説明と利用Tipsで記事を分けましたが、cmake
は大体のことが1つの記事でまとまりましたね
これだけでも導入ハードルの低さがわかります。
最初は別途configure
と比較してcmake
のデメリット(helpがない等)挙げようと思っていたのですが、全部補われていました。もうconfigure
はいらない子なのかな?
でも自分はconfigure
も好きです。--help
でオプションが出てくるのがなんか好きなので。
##参考
基礎: ごく簡単なcmakeの使い方
ライブラリ追加に利用: 初めてのcmake備忘録
自作ライブラリ: CMakeを使って自作ライブラリをビルド&インストールしてみたまとめ
インストール: cmake-commands(7 install
コマンド実行:cmakeでビルド時にシェルスクリプトを実行する
オプション追加:CMakeを使ってみた (4) ビルドオプション
out-of-source:CMake : out-of-sourceビルドで幸せになる
prefix変更:CMakeでprefixを変える
ccmake: ccmakeのすすめ