Protocol Bufferesのチュートリアル準備(pkg-configメモ)

前回でProtocol Bufferesのコンパイルとインストールができた(http://d.hatena.ne.jp/torazuka/20111201/protobuf)ので、チュートリアルをやってみようということで、その準備です。

examplesディレクトリ以下に、C++JavaPythonで書かれた(おそらくは)同内容のチュートリアル用コードがあります。それぞれmakeしてから使います。

make allすると、C++版、Java版、Python版すべての実行ファイルが生成されます。make cpp、make java、make pythonなどとすることで、各言語版を個別にコンパイルすることもできます。

しかし、試しにmake allしてみると、Javaでprotobufライブラリがないというエラーが出てしまいました。今回はC++版を使う予定なので、この解決は保留にして、C++版だけコンパイルすることにします(手抜きです)

次のようにmake cppを実行します。

$ env PKG_CONFIG_PATH=/usr/lib/pkgconfig:$PKG_CONFIG_PATH make cpp
pkg-config --cflags protobuf  # fails if protobuf is not installed
-pthread  
c++ add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf`
pkg-config --cflags protobuf  # fails if protobuf is not installed
-pthread  
c++ list_people.cc addressbook.pb.cc -o list_people_cpp `pkg-config --cflags --libs protobuf`

成功すると、これらのファイルが作成されました。

  • 実行ファイル
    • add_person_cpp
    • list_people_cpp
  • その他
    • addressbook_pb2.py
    • addressbook.pb.cc
    • addressbook.pb.h
    • com/example/tutorial/AddressBookProtos.java
    • protoc_middleman

補足: pkg-config

examplesディレクトリのMakefileは、pkg-configというツールを呼び出します。

pkg-configとは、パッケージ情報を管理するツールです。.pcファイルというライブラリのメタデータを読み込んで使います。.pcファイルは、ライブラリディレクトリ以下のpkgconfigディレクトリに入っています。

make cppを単に実行すると、次のエラーが出ました。

$ make cpp
protoc --cpp_out=. --java_out=. --python_out=. addressbook.proto
pkg-config --cflags protobuf  # fails if protobuf is not installed
Package protobuf was not found in the pkg-config search path.
Perhaps you should add the directory containing `protobuf.pc'
to the PKG_CONFIG_PATH environment variable
No package 'protobuf' found
make: *** [add_person_cpp] Error 1

このエラーは、pkg-configの検索パスが、protobufライブラリのメタデータがあるディレクトリを見ていないことが原因です。

確認と対処

protobufの.pcファイルが存在するディレクトリのパスと、それをpkg-configが見ていないことを確認します。

pkg-configの管理下に、protobufのライブラリがないことを再度確認します。

$ pkg-config --libs protobuf
Package protobuf was not found in the pkg-config search path.
Perhaps you should add the directory containing `protobuf.pc'
to the PKG_CONFIG_PATH environment variable
No package 'protobuf' found

続いて、pkg-configが現在管理しているすべてのパッケージを確認します(出力は例です)。

$pkg-config --all-list
systemd                  systemd - systemd System and Service Manager
gnome-icon-theme         gnome-icon-theme - A collection of icons used as the basis for GNOME themes
usbutils                 usbutils - USB device database
fontutil                 FontUtil - Font utilities dirs
gnome-keybindings        gnome-keybindings - Keybindings configuration for GNOME applications
gnome-python-desktop-2.0 GNOME-python - Python bindings for GNOME libraries
gnome-video-effects      gnome-video-effects - A collection of GStreamer effects to be used in different GNOME Modules
udev                     udev - udev
notify-python            notify-python - Python bindings for libnotify
shared-mime-info         shared-mime-info - Freedesktop common MIME database

たしかにprotobufはありません。

なお、手元のシステムに作成されているpkgconfigディレクトリは、次の3つです。

$ sudo find / -name 'pkgconfig' -print 
/usr/lib/pkgconfig
/usr/lib64/pkgconfig
/usr/share/pkgconfig

そして、それぞれのディレクトリの中身は、こんな感じ。

$ ls /usr/lib/pkgconfig/
protobuf-lite.pc  protobuf.pc
$ ls /usr/lib64/pkgconfig/
fontutil.pc  gnome-python-desktop-2.0.pc  notify-python.pc
$ ls /usr/share/pkgconfig/
gnome-icon-theme.pc   gnome-video-effects.pc  systemd.pc  usbutils.pc
gnome-keybindings.pc  shared-mime-info.pc     udev.pc

これらの結果から、次のことが確認できました。

  • pkg-configの検索対象
    • /usr/lib64/pkgconfig/
    • /usr/share/pkgconfig/
  • 検索対象外
    • /usr/lib/pkgconfig/

そして、examplesのコンパイルに必要なファイル(protobuf.pc)は、/usr/lib/pkgconfig/にあります。

というわけで、エラーメッセージの指示どおり、PKG_CONFIG_PATHに抜けているディレクトリを追加します。それが、envコマンドでパスを設定した、先ほどのmake cppコマンドです。

というわけで、補足おしまい。