POCO を使おうとして error while loading shared libraries: libPocoNet.so.60: cannot open shared object file: No such file or directory みたいに「ないよ」って言われる時

posted in: Tips | 0

結論

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

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.