FindGtk+.cmake 書いてみた

インストールされている GTK のライブラリとかヘッダとか探す CMake のモジュールが大昔の Gtk 用のしかないみたいなので、ちょっと書いてみた。
ああ、そうそう、CMake は make の新しいやつとかじゃなくて、autotools の代替版だよ。
ライブラリをリンクするには、ヘッダファイルへのパスとライブラリファイルへのパスの 2 つが必要だ。
*.pc からコンバートできればいいんだけど…。

1 find_path でヘッダファイルのあるパスを探す

>


まずは、ヘッダーファイルを調べるディレクティブの find_path からいってみよう。

find_path はこんな風に使うよ:


find_path(GTK_glib_INCLUDE_PATH NAMES glib.h
  PATH_SUFFIXES glib-2.0 glib-1.2 glib-1.0 glib
  PATHS
    /lib/include
    /lib/local/include)

find_path は第一引数の GTK_glib_INCLUDE_PATH に glib.h が存在する場所を代入するディレクティブで、 NAMES、PATH_SUFFIXES、PATHS は引数名シンボルと覚えておけばあんまり間違ってないと思う。
えーっと、上に書いてあるのは /lib/include か /lib/local/include の中にある、glib-2.0 か glib-1.0 か glib というディレクトリで、 glib.h が入っているパスを GTK_glib_INCLUDE_PATH に代入せよという意味だ。

このシンボル NAMES, PATH_SUFFIXES, PATHS や、後に出てくる NOT や message ディレクティブに使う STATUS は大文字でなければいけない。
そうしないと、またほら、わけのわからないエラーが出てきてプチプチを数平方メートル潰さないといけないノルマを食らった人みたいになってしまうだろう。
とにかく、ディレクティブの名前は小文字でも大文字でもいいんだけど、ある特定のシンボルは大文字でなければダメなのだ。

これらの名前付き引数の一部、または全部を省略して:

find_path(GTK_glib_INCLUDE_PATH NAMES glib.h
  PATHS
    /lib/include
    /lib/local/include)

こんな風に書いても CMake は許してくれるが、その代わり GTK_glib_INCLUDE_PATH は空っぽになる。
この場合はね。
ディレクトリなんて無くて、/lib/include や /lib/local/include に直に置いてあるなら、PATH_SUFFIXES 部分は要らないだろう。

2 find_library でライブラリファイルを探す

お次は ライブラリを探すとしよう。
glib のライブラリを探す find_library はこんな風になる:

find_library(GTK_glib_LIBRARY
  NAMES glib-2.0 glib-1.2 glib
  PATHS
    /usr/lib
    /usr/local/lib)

意味的には find_path と同じだが、この find_library はライブラリファイルを探すディレクティブだという事に注意して欲しい。
パッケージの中には複数のライブラリファイルが含まれていることがあるが、それらを全て探さなければならない。
Gtk の様な依存パッケージが多いパッケージの依存するライブラリ全てを探すのはとても骨が折れる仕事だ。マジで。

3 見つけたかどうかのフラグを立てる

全てのライブラリやヘッダファイルパスを探し終わったら、それらをきちんとまとめる必要がある。
その前に、見つかったかどうかのフラグを立てよう:

set(GTK_FOUND "YES")

CMake オリジナルの GTK_FOUND がこうなっていた。
そして、GTK_INCLUDE_DIR にこれまでみつけたヘッダファイルパスを全部ぶち込む。
こんな風に:

set(GTK_INCLUDE_DIR
  ${GTK_glibconfig_INCLUDE_PATH}
  ${GTK_glib_INCLUDE_PATH}
  ${GTK_gmodule_INCLUDE_PATH}
  ${GTK_gio_INCLUDE_PATH}
  ${GTK_gthread_INCLUDE_PATH}
  ${GTK_gobject_INCLUDE_PATH}
  ${GTK_gail_INCLUDE_PATH}
  ${GTK_gdk_INCLUDE_PATH}
  ${GTK_gtk_INCLUDE_PATH})

GTK_LIBRARIES も同じようにぶち込む。

set(GTK_LIBRARIES
  ${GTK_glib_LIBRARY}
  ${GTK_gtk_LIBRARY}
  ${GTK_gdk_LIBRARY})

あとは mark_as_advanced なんだけど、なにやってるのか全くわからない。
まあ、詳しくはここ参照。