結論
sudo ldconfig
背景
GET THE POCO C++ LIBRARIES で GNU MAKE のセクションのステップ通りに POCO を install すると(上の方に conan を使う方法もでてますけど、実際、かえってややこしくなるだけなので普通に git clone して make する方がいいです)、出来上がった POCO の .so は
にできるそうです(下の方にそう書いてありますね)/usr/local/lib
インストールがすんだらPOCO を使ってるプロジェクトをなにか適当に試してみます
例えば Maya Posch さんの Cerfletとか
ちなみにたまたまとか適当にとかいうのはブログに物凄くよくあるパターンの嘘で、かくいうわたくしも実は嘘をついておりまして、本当は最初っから Cerflet が使いたくて POCO をインストールしたのでした、嘘ついてごめんなさい
Cerflet を git clone して make するとhellocerflet ができるので実行してみると
pi@raspberrypi:~/Cerflet/sample $ ./hellocerflet
./hellocerflet: error while loading shared libraries: libPocoNet.so.60: cannot open shared object file: No such file or directory
??? あれれ???
調査編
ないと言われる libPocoNet.so.60 を find してみると /usr/local/lib の下にちゃんとあります
pi@raspberrypi:~/Cerflet/sample $ sudo find / -name libPocoNet.so.60
/usr/local/lib/libPocoNet.so.60
/home/pi/poco/lib/Linux/armv7l/libPocoNet.so.60
hellocerflet が使ってる shared object の depency を見てみると
pi@raspberrypi:~/Cerflet/sample $ ldd hellocerflet
linux-vdso.so.1 (0x7ec45000)
/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76ec2000)
libPocoNet.so.60 => not found
libPocoFoundation.so.60 => not found
libPocoUtil.so.60 => not found
libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x76d66000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76ce7000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x76cba000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76b7b000)
/lib/ld-linux-armhf.so.3 (0x76ed8000)
あ、ダイナミックリンカが libPocoNet をみつけられていませんね
解決編
ダイナミックリンカに .so のサーチパスを教えてあげる方法は2つありますので、都合のよい 方法でおしえてあげます
環境変数 LD_LIBRARY_PATH に指定する
POCO の .so のいる /usr/local/lib を LD_LIBRARY_PATH に指定してあげます
こんなかんじ
pi@raspberrypi:~/Cerflet/sample $ ./hellocerflet
./hellocerflet: error while loading shared libraries: libPocoNet.so.60: cannot open shared object file: No such file or directory
pi@raspberrypi:~/Cerflet/sample $ LD_LIBRARY_PATH=/usr/local/lib
pi@raspberrypi:~/Cerflet/sample $ export LD_LIBRARY_PATH
pi@raspberrypi:~/Cerflet/sample $ ./hellocerflet
Request from 192.168.1.6:50985
いぇい!うごいた
5日ほど前に上がってた stadk overflow の質問 も、この方法で自己解決されてますね
ldconfig を実行する
/usr/local/lib に追加された POCO のライブラリは ldconfig コマンドを使う事でもダイナミックリンカに場所を教えてあげることができます
このコマンドは指定されたパス(/etc/ld.so.conf 配下の *.conf ファイルにかいてあるパス。/usr/local/lib は libc.conf に定義されてる)を調べて、ダイナミックリンカが解決してくれるライブラリのためのキャッシュを作ってくれるそうです、親切ですね
パスの指定は /etc/ld.so.conf 配下の *.conf ファイル群で定義します
POCO のライブラリがインストールされている /usr/local/lib は libc.conf で定義されています
それから、現在のキャッシュの状況は ldconfig -p で見ることができて
pi@raspberrypi:~/Cerflet/sample $ ldconfig -p | grep libPocoNet.so.60
と、今はなにもでてきません
なので、ldconfig をしてみると
pi@raspberrypi:~/Cerflet/sample $ sudo ldconfig
pi@raspberrypi:~/Cerflet/sample $ ldconfig -p | grep libPocoNet.so.60
libPocoNet.so.60 (libc6,hard-float) => /usr/local/lib/libPocoNet.so.60
おっ、登録されたみたいですね
動くかな?
pi@raspberrypi:~/Cerflet/sample $ ./hellocerflet
Request from 192.168.1.6:51177
うごいた!いぇい!
考察
Makefile で ldconfig してくれてもいいのにね、POCO さんったらお茶目さん
Leave a Reply