31
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

cmakeの使い方  導入(採用するならout-of-source!)・CMakeList.txtの書き方・自作パッケージのインストール

Last updated at Posted at 2018-08-06

はじめに

出尽くしてると思いますが、cmakeを使ってみたので使い方と所感を記載します。

インストール

aptやyumでインストールしてください。

sudo yum install cmake
sudo apt-get install cmake

基本的な使い方

とりあえず使ってみる in-sourceビルド

  1. 各ディレクトリにCMakeList.txtを置く
  2. トップでcmake .を実行
  3. make, make install

以上です。簡単ですね!

in-sourceビルドの欠点

2018/08/07 @tenmyo さんコメントを元に追記

上記の使い方、実は不便な点があります:cloud:。まずはビルド前後のディレクトリ内を見てもらいましょう。

ビルド前
$ 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

な、なんかめっちゃファイルが出来てるんですけど:weary:

cmakeを使用してビルドをすると、ビルド時に「成果物 + CMakeCache.txt, CMakeFiles等ビルド用のファイル達」を各ディレクトリ内に作成します。

なので、in-sourceビルド(cmake .指定)をしてしまうとビルド後ソース内がごちゃごちゃに。
この辺りが最初に戸惑うポイントだと思います。

でも大丈夫!cmakeは簡単にソースと成果物を分離出来るんです:thumbsup:

採用するならout-of-source!

cmakeはビルド成果物を格納する場所を変えることが出来ます。例えば先ほどの構成にbuildという空のディレクトリを用意しておいて、以下手順でビルドします。

  1. 各ディレクトリにCMakeList.txtを置く
  2. buildディレクトリに移動してcmake ../を実行
  3. make, make install

in-sourceとほとんど変わらず簡単ですね。なのにビルド前も後も綺麗なままです!:laughing:

ビルド後
$ ls
build  CMakeLists.txt  conf  lib  LICENSE  README  script  src  uninstall.sh

成果物は全部buildディレクトリ内。cleanもrm -rf build/でOKです。楽ちん!

buildディレクトリ内
[@build]$ ls
CMakeCache.txt  cmake_install.cmake  lib       script
CMakeFiles      conf                 Makefile  src

また、buildもmakeではなくcmake —-build buildディレクトリで置き換え可能。
make以外のコマンドでも同じ手順でコンパイルが可能になっています:thumbsup:

その他色々なメリットが以下記事に記載されているので、興味ある方はぜひ参照ください:exclamation:
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_executableADD_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が使えるか今の設定がどうなっているのかがすぐにわかります!わかりやすい!:thumbsup:

ccmake.png

ちなみに、ubuntuではccmakeを使うために以下が必要でした。

sudo apt install cmake-curses-gui

所感

  • makeconfigureと比べると導入がとにかく簡単
  • 最初は何をやっているか分からなかったが、理解すると覚えることも少ないのでいい。

最初の最初だけとっつきにくいけど、使ってしまえばものすごく楽ちん!って感じでした。

2018/08/07 追記

configureをまとめた時は導入の説明利用Tipsで記事を分けましたが、cmakeは大体のことが1つの記事でまとまりましたね:grin:
これだけでも導入ハードルの低さがわかります。

最初は別途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のすすめ

31
27
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?