steves has asked for the wisdom of the Perl Monks concerning the following question:

I have a problem on Solaris 2.7 that's stumped me. I have rather large Perl installations on 2 Solaris boxes: 1 Solaris 2.7; the other 2.8. Each has over 250 CPAN modules loaded, as well as a number of prerequisite libraries. Both use GNU (gcc) build environments. Both appear to be using the same versions of all software.

Friday, I went to install DBD::mysql. I already had this loaded on the 2.8 box. I built it there against a recent Solaris binary download of mysql. No problems ... all tests pass, etc. On the 2.7 box I'm stuck. Everything builds okay but all the tests yield errors like this:

t/00base............install_driver(mysql) failed: Can't load 'blib/arc +h/auto/DBD /mysql/mysql.so' for module DBD::mysql: ld.so.1: /usr/local/bin/perl: +fatal: rel ocation error: file blib/arch/auto/DBD/mysql/mysql.so: symbol mysql_re +al_escape_ string: referenced symbol not found at /usr/local/lib/perl5/5.6.1/sun4 +-solaris/D ynaLoader.pm line 206. at (eval 1) line 3 Compilation failed in require at (eval 1) line 3. Perhaps a required shared library or dll isn't installed where expecte +d
Basically it looks like at run-time the mysql client library is missing in action. I've been building freeware for some time so I checked all the obvious things: missing shared libraries, unset LD_LIBRARY_PATH, etc. This one is not obvious. Plus all the other modules I've built (including 2 other DBD:: modules) have not hit this problem. My basic conclusion is that the linker is happy it can find everything at build time but the run time linker is not so happy. I added debug to DynaLoader and @dl_library_path is set correctly. Runnning the Solaris ldd command against the created mysql.so shows all the libraries it thinks it wants are there, however the mysql client lib is not in that list on either machine. Instead, the build on both machines (good and bad) shows this sort of set-up to find the mysql client lib:
Running Mkbootstrap for DBD::mysql () chmod 644 mysql.bs rm -f blib/arch/auto/DBD/mysql/mysql.so LD_RUN_PATH="/usr/local/lib/mysql:/usr/lib" /usr/local/bin/perl myld g +cc -G -L/ usr/local/lib dbdimp.o mysql.o -o blib/arch/auto/DBD/mysql/mysql.so + -L/usr/lo cal/lib/mysql -lmysqlclient -lcrypt -lgen -lsocket -lnsl -lm chmod 755 blib/arch/auto/DBD/mysql/mysql.so cp mysql.bs blib/arch/auto/DBD/mysql/mysql.bs chmod 644 blib/arch/auto/DBD/mysql/mysql.bs Manifying blib/man3/DBD::mysql.3 Manifying blib/man3/DBD::mysql::INSTALL.3 Manifying blib/man3/Bundle::DBD::mysql.3 Manifying blib/man3/Mysql.3
I'm not exactly sure what that means ... I assume it's setting things up so DynaLoader finds the libs at run time. The standard mysql downloads only provide a static library so I'm not sure how that works but it does on the 2.8 box -- there are no mysql .so files to be found there and everything is happy.

I've tried using source builds of mysql -- which do have the .so shared libs; tried about a half dozen older versions of DBD::mysql; rebuilt everything including Perl with a new gcc to make sure I matched the other machine, etc. I've found numerous Google references to similar problems which all point to the things I mention here. Anyone have any other ideas (besides a bullet to the head)? Both boxes are running 5.6.1 Perl.

Two things I started looking into that I'm not all that familiar with: gcc has spec files that provide linker defaults; Solaris has a crle command that controls linker options. Interestingly enough, that command is on both the 2.7 and 2.8 box but only the 2.8 box has a man page entry and the directory/file structure that man page describes.

I also posted to the DBI mailing list (no response) and tried to subscribe to a mysql specific list (also no response).

Replies are listed 'Best First'.
Re: DynaLoader DBD::mysql and Solaris 2.7
by steves (Curate) on Feb 03, 2003 at 04:21 UTC

    I fixed this. It seems that the Solaris 2.7 and 2.8 linkers have a subtle difference. I'm using gcc but I'm assuming it uses the native linker somewhere. I used to know this stuff when I coded C, but Perl spoiled me ... At any rate, my linker line looked like this on each system:

    LD_RUN_PATH="/usr/lib:/usr/local/lib" /usr/local/bin/perl myld gcc -G + -L/usr/local/lib dbdimp.o mysql.o -o blib/arch/auto/DBD/mysql/mysql. +so -lmysqlclient -lcrypt -lgen -lsocket -lnsl -lm -lz
    I had to change the Solaris 2.7 line to this:
    LD_RUN_PATH="/usr/lib:/usr/local/lib" /usr/local/bin/perl myld gcc -G + -L/usr/local/lib dbdimp.o mysql.o /usr/local/mysql/lib/libmysqlclien +t.a -o blib/arch/auto/DBD/mysql/mysql.so -lcrypt -lgen -lsocket -lns +l -lm -lz
    In other words, 2.7 wants an explicit *.a listed as part of the objects that make up the mysql.so shared library. 2.8 seems smart enough to know that if there's only a *.a to pull it in regardless of where it is on the linker command line. Note that there is no libmysqlclient.so on either system. I even built one on the 2.7 machine and that also failed.

    For the record, in case some other unfortunate soul loses his weekend like I did over this, I changed one line in the generated Makefile (line 106 of mine):

    OBJECT = $(O_FILES) /usr/local/mysql/lib/libmysqlclient.a
    where it was:
    OBJECT = $(O_FILES)

    I'm not seeing right now how to incorporate this into Makefile.PL or into the mysql_config file that's used. Not sure I care at this point.