mysql-4.1.11 / php-5.0.4: shared library / linker puzzles [Long]

Joseph E. Sacco, Ph.D. joseph_sacco at comcast.net
Fri Apr 8 16:08:19 MDT 2005


I have managed to get php-5.0.4 to load without our favorite PPC error
rearing up its ugly head:

        PHP Warning:  PHP Startup: Unable to load dynamic library
        '/usr/lib/php/modules/mysqli.so' -
        /usr/lib/php/modules/mysqli.so: R_PPC_REL24 relocation at
        0x0cbae510 for symbol `__stpcpy' out of range in Unknown on line
        0

The workaround to eliminate this error is puzzling [at least to me].
Maybe someone on the list can provide an insight into what's going on.

Discussion
----------
The SRPM for mysql-4.1.11

	http://dev.mysql.com/downloads/mysql/4.1.html

builds a number of RPMS:
        MySQL-bench-4.1.11-0.glibc23.ppc.rpm
        MySQL-client-4.1.11-0.glibc23.ppc.rpm
        MySQL-debuginfo-4.1.11-0.glibc23.ppc.rpm
        MySQL-devel-4.1.11-0.glibc23.ppc.rpm
        MySQL-embedded-4.1.11-0.glibc23.ppc.rpm
        MySQL-Max-4.1.11-0.glibc23.ppc.rpm
        MySQL-ndb-extra-4.1.11-0.glibc23.ppc.rpm
        MySQL-ndb-management-4.1.11-0.glibc23.ppc.rpm
        MySQL-ndb-storage-4.1.11-0.glibc23.ppc.rpm
        MySQL-ndb-tools-4.1.11-0.glibc23.ppc.rpm
        MySQL-server-4.1.11-0.glibc23.ppc.rpm
        MySQL-shared-4.1.11-0.glibc23.ppc.rpm

"MySQL-shared" contains the shared client libraries, which are installed
under /usr/lib:

        /usr/lib/libmysqlclient.so
        /usr/lib/libmysqlclient.so.14
        /usr/lib/libmysqlclient.so.14.0.0
        /usr/lib/libmysqlclient_r.so
        /usr/lib/libmysqlclient_r.so.14
        /usr/lib/libmysqlclient_r.so.14.0.0

"MySQL-devel" contains:
* include files installed under /usr/include/mysql

* static libraries installed under /usr/lib/mysql
        /usr/lib/mysql/libdbug.a
        /usr/lib/mysql/libheap.a
        /usr/lib/mysql/libmerge.a
        /usr/lib/mysql/libmygcc.a
        /usr/lib/mysql/libmyisam.a
        /usr/lib/mysql/libmyisammrg.a
        /usr/lib/mysql/libmysqlclient.a
        /usr/lib/mysql/libmysqlclient.la
        /usr/lib/mysql/libmysqlclient_r.a
        /usr/lib/mysql/libmysqlclient_r.la
        /usr/lib/mysql/libmystrings.a
        /usr/lib/mysql/libmysys.a
        /usr/lib/mysql/libnisam.a
        /usr/lib/mysql/libvio.a

First puzzle:

	"Why are the mysql libraries in two places?" 

One explanation is "users" don't need the files in MySQL-devel, so why
force a user to install things that are not needed. Developers, on the
other hand, are smart folks who will know how to handle the shared
client libraries being in one place and the static libraries in another
place. Right??? [Place your hand on your wallet. You are being hustled
:-)].

A number applications look for mysql libraries in /usr/lib/mysql, which
can lead to problems since the shared client libraries are elsewhere. A
simple workaround is create links in /usr/lib/mysql that point to the
shared libraries in /usr/lib. `ld' will search a directory for a library
with an extension of `.so' before searching for one with an extension of
`.a'. So creating the links should work, right??? [Keep your hand on
your wallet...]. So what's the problem???

Consider a fragment of the Makefile that builds the PHP modules mysql.so
and mysqli.so:

 [backslashes were added for readability because of line wrap]

        shared_objects_mysql = ext/mysql/php_mysql.lo
        MYSQL_SHARED_LIBADD = -lmysqlclient
        MYSQL_MODULE_TYPE = external
        MYSQL_LIBS = -L/usr/lib -lmysqlclient
        MYSQL_INCLUDE = -I/usr/include/mysql
        
        shared_objects_mysqli = ext/mysqli/mysqli.lo          \
        ext/mysqli/mysqli_api.lo ext/mysqli/mysqli_prop.lo    \
        ext/mysqli/mysqli_nonapi.lo ext/mysqli/mysqli_fe.lo   \
        ext/mysqli/mysqli_report.lo ext/mysqli/mysqli_repl.lo
        
        MYSQLI_SHARED_LIBADD = -Wl,-rpath,/usr/lib/mysql      \
        -L/usr/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm

Notice that mysql.so uses the client library found under /usr/lib,
whereas mysqli.so uses the client library found under /usr/lib/mysql,
which is puzzling. 

Should not be a problem, right??? We know `ld' will search a directory
for a library with an extension of `.so' before searching for one with
an extension of `.a'. Right??? [Keep your hand on your wallet ...]

Experiment #1
-------------
* Modify MYSQLI_SHARED_LIBADD to use libraries under /usr/lib
* rebuild and install mysqli.so
* fire up httpd

	==> works OK.

Experiment #2
-------------
* move all of the static libraries out of /usr/lib/mysql
leaving only links to the shared mysql client libraries under /usr/lib
* rebuild and install mysqli.so
* fire up httpd

	==> works OK.

Observations
-------------
* Looks like 'ld' ignored the shared mysql client library and used the
statically linked library instead, mixing PIC and non-PIC code, which is
known to be a bad thing on PPC's. 


Second puzzle:

	Why is that???




-Joseph


-- 
joseph_sacco[at]comcast[dot]net



More information about the yellowdog-general mailing list