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