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).

1 thought on “Perl module library madness!”

  1. If the SFWbdb package was installed, running ‘crle -l /lib -l /usr/lib -l /opt/sfw/lib’ would’ve been easier, no?

Leave a Reply

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