Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

Unable to load dynamic library 'XXX.so' - libYYY.so: undefined symbol: ZZZ


configure・make・make installまでは問題なく進んだのに、Apacheを起動しようとすると「Unable to load dynamic library」が発生。よくある話ですね(ホントか?)。
今回はPHP4.4.6+libsablotで発生しました。ズルしてsablotronをrpmからインストールしようとしたのが敗因。
次のような環境で、

configureオプションを

# for PHP4
./configure \
--with-apxs2=/usr/local/apache2/bin/apxs \
--prefix=/usr/local/lib/php4 \
--with-pear=/usr/local/lib/php4/pear \
--with-config-file-path=/usr/local/lib/php4/ini/4.4.6 \
--with-config-file-scan-dir=/usr/local/lib/php4/ini.d \
--enable-zend-multibyte \
--enable-mbstring=shared \
--with-dom \
--with-dom-xslt \
--with-dom-exslt \
--with-gd=shared \
--with-jpeg-dir \
--with-png-dir \
--with-zlib-dir \
--with-ttf \
--with-freetype-dir \
--enable-gd-jis-conv \
--with-pspell=shared \
--enable-debug \
--with-openssl=shared \
--with-mysql=shared \
--with-curl=shared \
--enable-bcmath=shared \
--enable-pcntl=shared \
--enable-sockets=shared \
--with-oci8=shared,/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/ \
--enable-sigchild \
--enable-xslt=shared \
--with-xslt-sablot

のようにしてbuildすると、Apache起動時に

Unable to load dynamic library
  '/usr/local/lib/php4/lib/php/extensions/debug-non-zts-20020429/xslt.so'
  - /usr/lib/libsablot.so.0: undefined symbol: JS_PropertyStub

てな具合でエラーになります(Apacheは起動します)。
今回使ったsablotronのrpmはjsに依存しているため、PHPをbuildする際、libjs.soをリンクしてやる(見えるようにしてやる)必要があります。ここでxslt.soを確認してみると、libjs.soとリンクしてないことが分かります。

$ ldd /usr/local/lib/php4/lib/php/extensions/debug-non-zts-20020429/xslt.so
        libsablot.so.0 => /usr/lib/libsablot.so.0 (0x00111000)
        libexpat.so.0 => /usr/lib/libexpat.so.0 (0x00631000)
        libc.so.6 => /lib/tls/libc.so.6 (0x001e9000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00d00000)
        libm.so.6 => /lib/tls/libm.so.6 (0x006cc000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00387000)
        /lib/ld-linux.so.2 (0x00b64000)
$ 

ということで、configureオプションに

--with-sablot-js

を追加して再buildすると

$ ldd /usr/local/lib/php4/lib/php/extensions/debug-non-zts-20020429/xslt.so
        libsablot.so.0 => /usr/lib/libsablot.so.0 (0x00a31000)
        libjs.so.1 => /usr/lib/libjs.so.1 (0x00111000)
        libexpat.so.0 => /usr/lib/libexpat.so.0 (0x00c37000)
        libc.so.6 => /lib/tls/libc.so.6 (0x0018e000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00843000)
        libm.so.6 => /lib/tls/libm.so.6 (0x00ceb000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0091f000)
        /lib/ld-linux.so.2 (0x00b64000)
$

という具合にlibjs.so(ただしくはlibjs.so.1)とリンクされて、Apacheも問題なく起動してxslt拡張モジュールが使えるようになります。

もう一つの解としては、「(soファイルで必要なライブラリがロードされてないので)そんなシンボル知らんわぃ」ということなので、Apacheを起動する前に必要なライブラリをロードしてやる、というのが考えられます。上記の場合、エラーの原因となっているシンボル「JS_PropertyStub」はlibjs.soの含まれていますので、libjs.soを事前にロードしてやるとヨサゲです。

$ nm /usr/lib/libjs.so | grep JS_PropertyStub
0000fd40 T JS_PropertyStub
$ 

ということで、apachectlと同じディレクトリにenvvarsファイルを作ってやり、そこでロードすることにしました。一番最後の「LD_PRELOAD」がそれです。

$ cat /usr/local/apache2/bin/envvars
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# envvars-std - default environment variables for apachectl
#
# This file is generated from envvars-std.in
#
LD_LIBRARY_PATH="/usr/local/apache2/lib:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
#

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/php5/lib/php/extensions/debug-non-zts-20060613/:/usr/local/lib/php4/lib/php/extensions/debug-non-zts-20020429/
export TZ="Asia/Tokyo"

export LD_PRELOAD=/usr/lib/libjs.so
$

ちなみに、libjs.soはlibjs.so.1へのシンボリックリンクになってます。

$ LANG=C ls -l /usr/lib/libjs*
-rwxr-xr-x  1 root root  695334 Nov 27  2005 /usr/lib/libjs.a
lrwxrwxrwx  1 root root      10 Mar 30 11:55 /usr/lib/libjs.so -> libjs.so.1
-rwxr-xr-x  1 root root 1531088 Nov 27  2005 /usr/lib/libjs.so.1
[shimooka@hrimfaxi php-4.4.6]$

これで起動するとxslt.soもちゃんとロードされました。
まあ、面倒なので、configureオプションを付けてbuildした方が良いでしょうね。