2010年12月6日月曜日

cmakeの使い方

ライブラリの導入時なんかにあちらこちらで見かけるcmake、よく使うけどどのサイトに行っても”「cmake .」とやれ”としか書いていない、それだとたまに困る。

というわけでcmakeメモを過去記事を元に再編集してみた。

ちなみに、cmakeとは
CMakeはソフトウェアのビルドを自動化するためのクロスプラットフォームなシステムである。 UnixにおけるMakeに相当するものであり、ビルドプロセスは設定ファイルCMakeLists.txtによって完全に制御される。 最終的なソフトウェアを直接にはビルドしない点がMakeとは異なっており、 代わりに、よく使われている標準的なビルドファイル(UnixにおけるmakefileやWindows Visual C++におけるプロジェクト/ワークスペースなど)を生成する。 by Wikipedia
みたいなもの 。
ようはダウンドードしたライブラリやアプリケーションのソースコードに「CMakeLists.txt」というファイルがあると、Makefileはもちろん、WindowsやMacの開発環境向けのプロジェクトファイルが生成できるという物。




cmakeコマンド

cmake [オプション] パス
大抵の場合は”CMakeLists.txt”があるディレクトリで「cmake .」すりゃおけ。

”大抵の場合”じゃなかったら、とりあえず利用出来るオプションを調べます。
cmake --help-variable-list
これで利用出来る定数を調べることができます。よくわからない定数があったら「cmake --help-variable 定数名」で利用方法を調べます。

使うときは”-D”をつける、たとえば「CMAKE_<LANG>_FLAGS_RELEASE」ならこんな感じ。
cmake -DCMAKE_CXX_FLAGS_RELEASE='-arch i386' .
この定数はCMakeデフォルトのものと、作者が追加したものがあります。(追加の仕方は後述)

もう一つよく使うのが-Gオプション。プロジェクトファイルの形式を指定するオプションで、利用出来るものは環境によって違うので「cmake --help」などで予め調べましょう。
cmake -G "Unix Makefiles" .


CMakeLists.txtの書き方

CMakeLists.txtはコンパイルの仕方などを定義するファイル。「cmake --help-command-list」で調べることができる”コマンド”を使って定義します。コマンドの意味は「cmake --help-command コマンド名」で調べましょう。

簡単なものなら、たった2行で定義終了です。以下はSHEAED Libararyをつくる例。

まずはソースコードを用意。
//libhello.h
void hello(void);

//libhello.c

#include <stdio.h>

void hello(void) {
printf("Hello, library world.\n");
}

つづいてCMakeLists.txtを作成、今回は単純な共有ライブラリなので以下の三行でおけ
#CMakeLists.txt

#要求するcmakeのバージョン(ここで指定したのより古いバージョンのcmakeではエラー)
cmake_minimum_required(VERSION 2.6)

#プロジェクト名
PROJECT(libHelloWorld)

#ライブラリの生成
ADD_LIBRARY(hello_lib SHARED libhello.c)



あとは「cmake .」すると「CMakeFiles」「CMakeCache.txt」「Makefile」などが生成されます。あとは「make」すれば(Macなら)「libhello_lib.dylib」ができます。
SHAREDの部分を「STATIC」にすると静的ライブラリになったりします。

ちょっとパワーアップ版、上のライブラリを使ったプログラムを作成してみます。
とりあえず、先ほど作成したlibhelloライブラリを使うプログラムを準備します。
#include 
#include "libhello.h"

int main(){
 printf("Hello\n");
 
 //libhelloで定義した関数を使う。
 hello();
 
//-DDEBUGBが指定されていたら実効
#ifdef DEBUG
 printf("Define debugg!!\n");
#endif
 
 return 0;
}

あとはCMakeLists.txtを準備しますが、このとき以下のようにファイルがおかれているとします。
hello.c
lib/libhello_lib.dylib
include/libhello.h

#要求するcmakeのバージョン
cmake_minimum_required(VERSION 2.6)
#プロジェクト名
PROJECT(HelloWorld)
#先にライブラリをコンパイルしとくこと

#ヘッダファイルの場所を指定
include_directories(include)
#ライブラリの場所を指定
link_directories(lib) 

#フラグ設定
##LD_FLAG
set_target_properties(hellodemo LINK_FLAGS -lc)
##コンパイラオプション
set_target_properties(hellodemo COMPILE_FLAGS -Wall)
#-DCMAKE_BUILD_TYPE=Debug した時だけつける
set(CMAKE_C_FLAGS_DEBUG "-g -pg")

#コンパイル時に使うdefinitionの指定
#全体に適用 add_definitions(-DFOO -DBAR ...)
add_definitions(-DDEBUG)

#実行ファイル生成方法
ADD_EXECUTABLE(hellodemo hello.c)

#ライブラリのリンク
target_link_libraries(hellodemo hello_lib) 
%cmake .
%make
%./hellodemo 
Hello
Hello, library world.
Define debugg!!
定数の追加方法

自分で定数を追加し、if文でコンパイル方法を制御することもできます。
以下で、「MESSAGE」はcmake実行時に文字列を出力するコマンド、「SUBDIRS」は"subディレクトリでもcmakeコマンドを実行する"というというコマンドです。(sub/CMakeLists.txtがあればね。)

# ++++
# フラグの例
# ++++

#フラグのサンプル、-Dフラグ名=ONにすると実行できる
#OPTION(フラグ名 "簡単な説明" デフォルト)

OPTION(FLAG_ONE "flag sample one with no value" OFF)
IF(FLAG_ONE)
 MESSAGE("++ Flag_ONE is setting!!")
ENDIF(FLAG_ONE)

OPTION(BUILD_SUB "Set when you want to build the sub" OFF)
IF(BUILD_SUB)
 MESSAGE("++ Build sub source")
 SUBDIRS(sub)
ENDIF(BUILD_SUB)

その他のサンプル
CMakeでFrameworkを作成するサンプル
上記リンク先のファイルをダウンロード、試し方はReadme.txtを参照。
%svn checkout https://my-sample-files.googlecode.com/svn/trunk/Cmake CMake-sample
%cd CMake-sample/make_framework

0 comments:

コメントを投稿