Perl module library madness!


While reading up on website performance monitoring applications last week, I came across the cricket HTTP-performance module. HTTP-performance allows you to graph the time it takes to connect to a website and to render a page. This sounded interesting, so I decided to download and install cricket. After reading through the beginners guide, I installed all of the required Perl modules, and proceeded to run the cricket compile script:

$ ./compile

Can't load '/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so' for module DB_File: ld.so.1: /usr/perl5/5.8.4/bin/perl: fatal: libdb-4.2.so: open failed: No such file or
directory at /usr/perl5/5.8.4/lib/i86pc-solaris-64int/XSLoader.pm line 68.
at /usr/perl5/5.8.4/lib/i86pc-solaris-64int/DB_File.pm line 251
Compilation failed in require at /home/rmatteso/cricket-1.0.5/lib/ConfigTree/Node.pm line 25.
BEGIN failed--compilation aborted at /home/rmatteso/cricket-1.0.5/lib/ConfigTree/Node.pm line 25.
Compilation failed in require at ./compile line 39.
BEGIN failed--compilation aborted at ./compile line 39.I

Ack!!!! – it looks like DB_File.so can’t find the BerkelyDB shared library:

$ ldd

/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so**

libdb-4.2.so => (file not found)
libc.so.1 => /lib/libc.so.1
libm.so.2 => /lib/libm.so.2

Since I hate using LD_LIBRARY_PATH, I decided to adjust the link line to include a hard coded runtime path. To determine which variable to edit, I searched the Makefile until I came to the following line:

$ less Makefile

$ (LD) (LDDLFLAGS) (LDFROM) (OTHERLDFLAGS) -o @ (MYEXTLIB)
$ (PERL_ARCHIVE) \ (LDLOADLIBS) (PERL_ARCHIVE_AFTER)
$ (EXPORT_LIST) (INST_DYNAMIC_FIX)

After locating this line, I added “-R/usr/sfw/lib:/usr/local/BerkeleyDB/lib” to the LDDLFLAGS variable and rebuilt the Perl module:

$ make

cc -c -I/usr/local/BerkeleyDB/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_TS_ERR
NO -DVERSION="1.814" -DXS_VERSION="1.814" "-I/usr/perl5/5.8.4/lib/i86pc-solaris-64
int/CORE" -D_NOT_CORE -DmDB_Prefix_t=size_t -DmDB_Hash_t=u_int32_t version.c
cc -c -I/usr/local/BerkeleyDB/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_TS_ERR
NO -DVERSION="1.814" -DXS_VERSION="1.814" "-I/usr/perl5/5.8.4/lib/i86pc-solaris-64
int/CORE" -D_NOT_CORE -DmDB_Prefix_t=size_t -DmDB_Hash_t=u_int32_t DB_File.c
Running Mkbootstrap for DB_File ()
chmod 644 DB_File.bs
rm -f blib/arch/auto/DB_File/DB_File.so
LD_RUN_PATH="/usr/local/BerkeleyDB/lib"
cc -G -R/usr/sfw/lib:/usr/local/BerkeleyDB/lib version.o DB_File.o -o blib/arch/auto/DB_File/DB_File.so -L/usr/local/BerkeleyDB/lib -ldb
chmod 755 blib/arch/auto/DB_File/DB_File.so
cp DB_File.bs blib/arch/auto/DB_File/DB_File.bs
chmod 644 blib/arch/auto/DB_File/DB_File.bs
Manifying blib/man3/DB_File.3

$ make install

Installing /usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
Installing /usr/perl5/5.8.4/man/man3/DB_File.3
Writing /usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/.packlist
Appending installation info to /usr/perl5/5.8.4/lib/i86pc-solaris-64int/perllocal.pod

Everything seemed to work, but did the runpath get set correctly? A quick check revealed that it did:

$ dump -Lv

/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so

/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so:

DYNAMIC SECTION INFORMATION 
.dynamic:
[INDEX] Tag Value
[1] NEEDED libdb-4.2.so
[2] NEEDED libc.so.1
[3] INIT 0xe030
[4] FINI 0xe050
[5] RUNPATH /usr/sfw/lib:/usr/local/BerkeleyDB/lib
[6] RPATH /usr/sfw/lib:/usr/local/BerkeleyDB/lib

This was a fun experience, since it finally forced me to sit down and read through the ELF standard (great read if you are into that kind of stuff).

This article was posted by Matty on 2006-02-25 11:10:00 -0400 -0400