CMakeを使ってみた (6) ソース外ビルド

CMakeを使うと、CMakeCache.txtやCMakeFilesなど様々ななファイルやディレクトリが生成される。結果的にプロジェクトのディレクトリが見にくくなりがちだ。そんなときはビルド作業を行うディレクトリを別のディレクトリにするとよい。これをソース外ビルド(out-of-source build)と呼ぶ。例えば、CMakeLists.txtやmain.cppがmyappディレクトリにあるとき、myappにbuildディレクトリを作り、その中でビルドを行うようにしよう。

myapp/
  +- CMakeLists.txt
  +- main.cpp
  +- build/  #この中でビルドする

やり方は特に難しくはない。buildディレクトリを作り、その中でcmakeを呼ぶだけだ。そのときCMakeLists.txtがあるディレクトリを指定すればよい。


こうすると、my-projectディレクトリにはファイル・ディレクトリの追加・変更はされない。要らなくなったらbuildディレクトリを消すだけでよい。

> ls
CMakeLists.txt  main.cpp
> mkdir build                  # buildディレクトリを作る
> cd build/                    # その中でビルド
> cmake .. && make && ./myapp
(snip)
hello

ソース外ビルドの機能を使えば、ビルドディレクトリを複数作ることができる。そうすれば、オプションごとに異なるディレクトリを使えるようになる。例えば、デバッグ版とリリース版をそれぞれDebug、Releaseディレクトリにすると良いだろう。

ソース外ビルドと相対パス

ソース外ビルドを行う場合に注意しなければならないのがパスの設定だ。ビルドが行われる、つまりコンパイラやリンカが実行されるディレクトリが変わるため、CMakeLists.txtがあるディレクトリからの相対パスがあるとビルドできないことがある。

例えば、以下のような構成で、設定ファイルを生成するようにしていたとする。

myapp/
  +- CMakeLists.txt
  +- HogeConfig.h.in # これを基にHogeConfig.hを生成する
  +- Hoge.h          # #include "HogeConfig.h"を含む
  +- Hoge.cpp        #
  +- build/          # ビルドディレクトリ
cmake_minimum_required(VERSION 2.8)
configure_file(
  "HogeConfig.h.in" "HogeConfig.h"
)
add_library(libHoge Hoge.cpp)

これで、buildディレクトリでビルドすると、以下のようになり失敗する。

> cmake ..
(snip)
> ls  # HogeConfig.hがここにできる
CMakeCache.txt  CMakeFiles/  HogeConfig.h  Makefile  cmake_install.cmake
> make VERBOSE=1
(snip)
/usr/bin/c++     -o CMakeFiles/libHoge.dir/Hoge.cpp.o -c /home/ws/wagavulin/06/myapp02/Hoge.cpp
In file included from /home/ws/wagavulin/06/myapp02/Hoge.cpp:1:0:
/home/ws/wagavulin/06/myapp02/Hoge.h:4:24: 致命的エラー: HogeConfig.h: そのよう
なファイルやディレクトリはありません

そのため、ファイルを生成する場合は以下のように書く必要がある。

configure_file(
  "${PROJECT_SOURCE_DIR}/HogeConfig.h.in"
  "${PROJECT_SOURCE_DIR}/HogeConfig.h"
)

ソース外ビルドにしてみたらエラーが出た、という場合は各種パスの設定を見直してみよう。