Hatena::Groupfreebsd

peanutsjamjamのFreeBSD日記 このページをアンテナに追加 RSSフィード

2009-05-17

devel/libmba Shared object "libmba.so.0.9" not found devel/libmba Shared object "libmba.so.0.9" not found - peanutsjamjamのFreeBSD日記 を含むブックマーク はてなブックマーク - devel/libmba Shared object "libmba.so.0.9" not found - peanutsjamjamのFreeBSD日記 devel/libmba Shared object "libmba.so.0.9" not found - peanutsjamjamのFreeBSD日記 のブックマークコメント

devel/libmba という ports がある。C 言語用のライブラリだ。

libmba - A library of generic C modules
http://www.ioplex.com/~miallen/libmba/

これをインストールして使おうとすると、うまく動かない。

まず、こんなプログラムを書いた:

%cat myhexdump.c
#include <stdio.h>
#include <mba/hexdump.h>

int main(int argc, char **argv) {
        int arr[] = {0xff, 0xaa, 0x30, 0x31};

        hexdump(stdout, arr, sizeof(int)*4, 16);

        return 0;
}

これを、次のようにしてコンパイルした

%cc -pipe -I/usr/local/include -c myhexdump.c
%cc -o myhexdump -L/usr/local/lib -lmba myhexdump.o

動かそうとすると、怒られた

%./myhexdump
/libexec/ld-elf.so.1: Shared object "libmba.so.0.9" not found, required by "myhexdump"

しょうがないので、/usr/local/lib ディレクトリを調べてみた

%cd /usr/local/lib
%ls -l libmba*
-rw-r--r--  1 root  wheel  254720 May 17 17:57 libmba.a
lrwxrwxrwx  1 root  wheel      11 May 17 17:57 libmba.so@ -> libmba.so.0
-rwxr-xr-x  1 root  wheel  208372 May 17 17:57 libmba.so.0*

確かに、"libmba.so.0.9" ってのは無い。"libmba.so.0" だったらあるんだけどね。

なので、無理やり "libmba.so.0.9" を、「あるように」した

%su
Password:
#ln -s libmba.so.0 libmba.so.0.9
#ls -l libmba*
-rw-r--r--  1 root  wheel  254720 May 17 17:57 libmba.a
lrwxrwxrwx  1 root  wheel      11 May 17 17:57 libmba.so@ -> libmba.so.0
-rwxr-xr-x  1 root  wheel  208372 May 17 17:57 libmba.so.0*
lrwxr-xr-x  1 root  wheel      11 May 17 21:42 libmba.so.0.9@ -> libmba.so.0

先ほどのディレクトリに戻って、再度実行

%./myhexdump
00000:  ff 00 00 00 aa 00 00 00 30 00 00 00 31 00 00 00  |........0...1...|

うまく行きました。

もうちょっと、調べてみた

ちなみに、libmba の version とか、私の FreeBSD の version は、こうです

%pwd
/usr/ports/devel/libmba
%head Makefile
# ex:ts=8
# Ports collection makefile for:        libmba
# Date Created:                 Sep 24, 2002
# Whom:                         ijliao
#
# $FreeBSD: ports/devel/libmba/Makefile,v 1.22 2009/03/09 19:29:03 miwi Exp $
#

PORTNAME=       libmba
PORTVERSION=    0.9.1
%uname -prs
FreeBSD 7.2-RELEASE i386

もう一度、make install して、様子を見てやる。そのために、まず make deinstall から

#make deinstall
===>  Deinstalling for devel/libmba
===>   Deinstalling libmba-0.9.1
#make install
===>  Installing for libmba-0.9.1
===>   libmba-0.9.1 depends on shared library: expat.6 - found
===>   Generating temporary packing list
===>  Checking if devel/libmba already installed
./mktool -i libmba.a /usr/local/lib
./mktool -i -libname mba -libvers 0.9.1 /usr/local/lib
./mktool -i src/mba/dbug.h src/mba/msgno.h src/mba/stack.h src/mba/linkedlist.h src/mba/hashmap.h src/mba/hexdump.h src/mba/cfg.h src/mba/pool.h src/mba/varray.h src/mba/shellout.h src/mba/csv.h src/mba/iterator.h src/mba/text.h src/mba/path.h src/mba/eval.h src/mba/svsem.h src/mba/allocator.h src/mba/suba.h src/mba/time.h src/mba/bitset.h src/mba/svcond.h src/mba/daemon.h src/mba/diff.h src/mba/misc.h /usr/local/include/mba
./mktool -i docs/man/*.3m.gz /usr/local/man/man3
make -f Makefile.bsd platform_specific_install
make: cannot open Makefile.bsd.

installation successful
===>   Running ldconfig
/sbin/ldconfig -m /usr/local/lib
===>   Registering installation for libmba-0.9.1

なんだ、"make: cannot open Makefile.bsd." って怒られてるじゃん。コケてるのに、"installation successful" って言うなよなぁ。

この、"Makefile.bsd" ってのがぜんぜん見当たらないんだけど、どうしたらいいんだろ。

追記

いろいろ調べて原因がわかりました。

libmba を make してる時の様子をじーっとみていると、当然 so ファイルを作る所も見れるのだけど、そのときのコマンドはこうなってる。(改行を勝手に追加)

gcc -shared -Wl,-soname,libmba.so.0.9 -lutil
 src/dbug.pic.o src/stack.pic.o src/linkedlist.pic.o src/hashmap.pic.o src/hexdump.pic.o
 src/msgno.pic.o src/cfg.pic.o src/pool.pic.o src/varray.pic.o src/shellout.pic.o
 src/csv.pic.o src/path.pic.o src/misc.pic.o src/text.pic.o src/eval.pic.o
 src/svsem.pic.o src/allocator.pic.o src/suba.pic.o src/time.pic.o src/bitset.pic.o
 src/svcond.pic.o src/daemon.pic.o src/diff.pic.o
 -o libmba.so.0

このオプション指定の中の -Wl,-soname,libmba.so.0.9 という部分は、リンカにそのまま渡される部分なのだけど、リンカに対して「 sonamelibmba.so.0.9 だよ」と言っている。なのに、実際に作ってるファイルは、最後のオプション指定にあるように libmba.so.0 となっている。くいちがってる。

リンカ ld のマニュアルを見てみると、-soname オプションの説明はこうなってる

 -soname=name
        ELF の共有オブジェクトを生成する際に、内部の DT_SONAME フィールドに
        、指定した name を設定します。実行形式が DT_SONAME フィールドを持つ
        共有オブジェクトとリンクされると、実行形式が実行される時に、動的リ
        ンカはリンカに与えられたファイル名を使う代わりに DT_SONAME フィール
        ドで指定された共有オブジェクトをロードしようとします。

なるほどね。実行形式の中に「おいらを動かすときは "libmba.so.0.9" とリンクしてね」って焼き込まれちゃうんだな。共有オブジェクトの中の DT_SONAME フィールドの値が、実行形式の中に書き込まれちゃう。

なので、make が終わってから、make install する前に work/libmba-0.9.1 に降りていって、先ほどのコマンドを、-soname オプションのところだけ変えて実行してやるという方法でもうまく行きます。

gcc -shared -Wl,-soname,libmba.so.0 -lutil src/dbug.pic.o ...(略)... src/diff.pic.o -o libmba.so.0

これをやってあげることによって、libmba.so.0 の中の DT_SONAME フィールドが "libmba.so.0.9" ではなく "libmba.so.0" になるので、実行形式の中に焼きこまれる値と、実際に存在するファイル名が食い違うってことがなくなる。

以下の記事も大変参考になりました。

共有ライブラリ - name-3333’s memo
http://d.hatena.ne.jp/name-3333/20080516/1210918147

npzlbrcspnpzlbrcsp2012/12/08 18:08iVxRXv <a href="http://wozkcpuyxviz.com/">wozkcpuyxviz</a>

sohwpexisohwpexi2012/12/09 23:274WcS6u , [url=http://frlhjxbyyyqn.com/]frlhjxbyyyqn[/url], [link=http://hxrmegbgzsmo.com/]hxrmegbgzsmo[/link], http://kowdizadwceq.com/

hcuxuzeadkhcuxuzeadk2012/12/11 14:40p74ooF <a href="http://brosjztwfxxc.com/">brosjztwfxxc</a>

gcywoqqqfvkgcywoqqqfvk2012/12/13 01:16Ijmyh6 , [url=http://favhofulurds.com/]favhofulurds[/url], [link=http://dkdqpbvumdzp.com/]dkdqpbvumdzp[/link], http://thjdjefosfpx.com/

トラックバック - http://freebsd.g.hatena.ne.jp/peanutsjamjam/20090517