macのpkg-config & CMakeでlibraryが見つからずハマった
CMakeでプロジェクトのビルド周りを管理しているのだが、外部のライブラリがCMakeのfind_package()
に対応していない場合は自分でライブラリを直接パスで設定する必要がある。リンクしたいライブラリが多数のライブラリに依存していたらかなり骨の折れる作業となる。しかし、もしpkg-configに対応しているのであれば自分でパスを設定する必要がない。pkg-configはシステムにインストールされているライブラリを検索し、そのライブラリをリンクするために必要なビルド時のオプションを生成してくれるツールだ。例えば以下のような具合に動作する。
pkg-config --libs poppler-glib >>> -L/usr/local/lib -L/usr/local/Cellar/glib/2.62.3/lib -L/usr/local/opt/gettext/lib -L/usr/local/Cellar/cairo/1.16.0_2/lib -lpoppler-glib -lgobject-2.0 -lglib-2.0 -lintl -lcairo
これがCMakeにも対応しているので、CMakeに対応していなくても煩雑な設定を行うことなくライブラリをリンクさせることが出来る。CMakeの中では以下のように書く。
find_package(PkgConfig REQUIRED) pkg_check_modules(LIB_POPPLER REQUIRED poppler-glib) add_executable(sample main.cpp) target_link_libraries(sample ${LIB_POPPLER_LIBRARIES}) target_include_directories(main PRIVATE ${LIB_POPPLER_INCLUDE_DIRS})
使用可能なライブラリはpkg-config --list-all
で確認できる。ここで一つ注意点がある。OSがlinuxであれば上記のもので問題なく動くのだが、macだとうまく動いてくれなかった。エラーでは以下のようにライブラリが見つからないと怒られる。
ld: library not found for -lpoppler-glib
macの場合では-lpoppler-glib
という形でリンクするライブラリの指定を行っても見つけてくれないのが原因だ。cmake
で生成されたMakefileをmake VERBOSE=1
で確認すると、他のライブラリは-lにて.dylibや.a等のファイルのバスが指定されているが、エラーになっているものはそうなっていない。なのでそのようにしたら良い。この作業に相当するオプションはpkg-config自体にはないのだが、CMake上では以下の二行目のように用意されているのでそちらに差し替えたら良い。
<XXX>_LIBRARIES ... only the libraries (without the '-l') <XXX>_LINK_LIBRARIES ... the libraries and their absolute paths
先のサンプルを例にするとこのようになる。
find_package(PkgConfig REQUIRED) pkg_check_modules(LIB_POPPLER REQUIRED poppler-glib) add_executable(sample main.cpp) target_link_libraries(sample ${LIB_POPPLER_LINK_LIBRARIES}) target_include_directories(main PRIVATE ${LIB_POPPLER_INCLUDE_DIRS})
https://cmake.org/cmake/help/v3.12/module/FindPkgConfig.html