CMakeのビルド構成の設定

Makefileを書くのが面倒になったので、CMakeを使ってみた。
デバッグモードやリリースモードのようなコンパイルのモードを指定できないか調べたところ、CMakeLists.txtに

set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_DEBUG "-g -pg")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -pg -O3")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3")
set(CMAKE_CXX_FLAGS_MINSIZEREL "")

のように設定すると良いみたい。
使うときは

cmake -D CMAKE_BUILD_TYPE=Debug .

みたいにするとモードの指定を記憶してくれる。この場合、フラグはCMAKE_CXX_FLAGSにCMAKE_CXX_FLAGS_DEBUGが連結されたものになる。あと、指定を記憶するので次にcmake .としても無指定にはならずにDebugが使われる。なので、無指定にしたい場合は

cmake -D CMAKE_BUILD_TYPE= .

のようにして記憶をクリアする必要がある。

gccのプリコンパイル済みヘッダ

昨日の続き。

gccのプリコンパイル済みヘッダ(PCH)がかなり速いことに気づいたけど、日本語の資料が少ないので本家のマニュアルを読んだ。結構複雑だったから下にメモしておく。

作り方

foo.hのプリコンパイル済みヘッダを作る場合、普通にコンパイルするように

$ gcc foo.h

とするとfoo.h.gchができる。完成。ヘッダを認識しない場合は-xオプションで指定すると良いみたい。

使い方

PCHを使いたいコードからfoo.hをインクルードするとき、条件が満たされた場合、自動的にPCHが使用される。条件は以下の通り。

foo.h.gchがサーチされること

gccは#include "foo.h"を発見すると、サーチパスのディレクトリごとにfoo.h.gchを探した後でfoo.hを探す。foo.h.gchとfoo.hは同じディレクトリに無くてもかまわない。また、"foo.h.gchディレクトリ"を見つけた場合、その中の全てのファイルの中から使用可能なもの使う。このとき、ディレクトリの中の探す順番は決まっていない。

基本的な制限
  • コンパイル単位に付きPCHは1つまで。
  • PCHのインクルード前にCのトークンが表れてはならない。プリプロセッサは使えるので、インクルードした先でPCHのインクルードをすることも可能。
  • PCHと使用側のプログラムは同じ言語であること。CとC++でもダメ。
  • 同様に、コンパイラは同じバイナリであること。
  • PCHのインクルード前に定義されたマクロは、PCHのコンパイル時にも同じ方法で定義されているか、PCHに何の影響も与えないものであること。-Dオプションと#includeだけでなく、-Oや-Wdeprecatedなどもマクロを定義することに注意。
コンパイラオプションについて

基本的に、PCHと使用側で違うオプションが指定された場合、それらが混ざった動作になる。

  • PCHが-gや類似のデバッグオプション付きでコンパイルされている場合、それら無しで使用側のコードをコンパイルできる。その逆はできない。
  • -mオプションは通常同じでなければならない。
  • その他にいくつか同じでなければならないオプションがあるが、どのオプションを変えても大丈夫かは今のところはっきりしていない。

まとめ

foo.h.gchディレクトリの中にコンパイラオプションだけを変えたPCHを入れておけば、使用側のオプションによって自動的にマッチするものを選んでくれるので便利。ただし、-gや-pgの有無だけが違うものを置いてしまうとどっちが使われるか分からないので、「-g -pgと-DNDEBUG」みたいに片方しかマッチしないように工夫すると良いかも。

ビルド時間の短縮

Boostは便利だけど、ちょっと使っただけでビルド時間が一気に長くなってしまうので、何とかならないか調べてみた。

まず、最近のgccではプリコンパイル済みヘッダ(PCH)が使えるらしい。しかし、ヘッダをプリコンパイルしたときのオプションが本番のコンパイル時と違う場合、プリコンパイル済みヘッダは利用されない可能性が高いとのこと(http://d.hatena.ne.jp/rero/20080609/p1)。リリース時のみ使うか、VCで言うところのstdafx.hのようにプロジェクトごとのプリコンパイル済みヘッダを用意する、ということになりそう。

次に、以前から名前は知っていたccacheを見つけた。(本家windows版
これはヘッダをプリプロセスした結果をキャッシュするツールで、使い方は単に

$ ccache gcc foo.c

とすれば二度目からコンパイルを高速化してくれる。

こっちはBoostを使ったごく短いプログラムでも目に見えて速くなったので、かなり良さそう。

追記:
ccache-win32gccに-cオプションが付くとなぜかうまく動かない。makeとかから機械的に呼ぶツールだから、これは困った。