php 链接到系统 libxml 而不是 ./configure --with-libxml-dir 指定的版本

php 链接到系统 libxml 而不是 ./configure --with-libxml-dir 指定的版本

我正在尝试在 Debian 8 系统上从源代码构建 php-5.5.33;configure两者make都运行成功,但是当我运行时make install出现以下错误:

Installing PEAR environment:      /usr/local/lib/php/
/usr/src/www/php/php-5.5.33/sapi/cli/php: symbol lookup error:     /usr/src/www/php/php-5.5.33/sapi/cli/php: undefined symbol: __xmlFree
Makefile:390: recipe for target 'install-pear-installer' failed
make[1]: *** [install-pear-installer] Error 127
Makefile:393: recipe for target 'install-pear' failed
make: *** [install-pear] Error 2

看到这一点后,我运行(从 dir /usr/src/www/php/php-5.5.33ldd sapi/cli/php并看到以下内容(我省略了大部分输出):

libxslt.so.1 => /usr/lib/x86_64-linux-gnu/libxslt.so.1 (0x00007efd9c207000)
libxml2.so.2 => /usr/lib/x86_64-linux-gnu/libxml2.so.2 (0x00007efd9bea0000)

我很惊讶地看到这一点,因为我使用了--with-libxml-dir--with-xsl选项来指定本地安装的位置,从源到 /usr/local,libxml2-2.9.3 和 libxslt-1.1.28 的版本。另外,configure 似乎已经选择了这个版本,因为输出中有很多实例,其中显示:

checking for xml2-config path... /usr/local/bin/xml2-config
checking whether libxml build works... yes

现在,make install我上面列出的错误实际上是有意义的,因为该符号__xmlFree不存在于系统的 中/usr/lib/x86_64-linux-gnu/libxml2.so.2,因为运行readelf -s /usr/lib/x86_64-linux-gnu/libxml2.so | grep -i __xmlfree找不到匹配项。不过我本地安装的版本包含这个符号:

$ readelf -s /usr/local/lib/libxml2.so.2 | grep -i __xmlfree
1409: 00000000000e0b5c    35 FUNC    GLOBAL DEFAULT   12 __xmlFree
5249: 00000000000e0b5c    35 FUNC    GLOBAL DEFAULT   12 __xmlFree

令人困惑的是为什么sapi/cli/php链接的 libxml2 版本与我指定的版本不同configure。注意,我的/etc/ld.so.conf如下:

$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

...并且我已将/etc/ld.so.conf.d目录合并为一个文件,如下所示:

$ cat /etc/ld.so.conf.d/libs.conf
/usr/local/lib
/usr/lib/x86_64-linux-gnu/libfakeroot

...我也在ldconfig安装 libxml2 和 libxslt 之后、构建 php 之前运行过。这是configure我使用的完整内容:

./configure --prefix=/usr/local \
CFLAGS="-O2 -mtune=native -funroll-loops -fPIC" \
--with-libdir=lib \
--with-apxs2=/usr/local/apache2/bin/apxs \
--disable-debug \
--disable-short-tags \
--enable-libgcc \
--enable-shared=yes \
--enable-calendar \
--enable-exif \
--enable-ftp \
--enable-gd-native-ttf \
--enable-mbstring \
--enable-shmop \
--enable-soap \
--enable-sockets \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--with-bz2 \
--with-curl=/usr/local \
--with-freetype-dir \
--with-gd \
--with-gnu-ld \
--with-iconv-dir=/usr/local \
--with-jpeg-dir=/usr/local \
--with-ldap=/usr/local \
--with-libxml-dir=/usr/local \
--with-mcrypt \
--with-mhash \
--with-openssl \
--with-openssl-dir=/usr/local \
--with-pear \
--with-pcre-regex=/usr/local \
--with-pcre-dir=/usr/local \
--with-png-dir=/usr/local \
--with-tidy \
--with-readline \
--with-tsrm-pthreads \
--with-xmlrpc \
--with-xsl=/usr/local \
--with-zlib \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--without-sqlite3 \
--without-pdo-sqlite

(另请注意,在指定为 /usr/local 的所有项目中,如果有可用的系统版本,则 php 实际上也链接到这些项目的系统版本。只有没有系统等效项的项目才实际链接到我指定的版本)。

为什么 php 链接的版本与我所指示的版本不同?看来,如果这没有发生,我可能不会在 期间收到错误make install

答案1

我有一个非常Ubuntu 12 上的 php 5.5 和curl 出现类似问题 - 我需要一个更新的curl,我将其编译并安装到/usr/local/curl-7.49.1.

使用--with-curl=/usr/local/curl-7.49.1未按预期工作 - 生成的二进制文件链接到/usr/lib/x86_64-linux-gnu/libcurl.so.顺便说一句:我的目标是使用 libcurl.a 将curl静态链接到php二进制文件(以避免版本问题),但这不是问题的原因。

此时我开始使用环境变量LDFLAGS设置测试我的构建export LDFLAGS=-L/usr/local/curl-7.49.1/lib。这也不起作用,结果与以前相同。

经过一些研究和测试(我不是 autoconf/Makefile 专家;-),我注意到在构建过程中对 libtool 的调用: libtool -L/usr/lib/x86_64-linux-gnu -L/usr/local/curl-7.49.1/lib [...]

--with-libs配置脚本的参数是放置因此,在变量之前LDFLAGS,libtool 没有获取我的 libcurl 文件,而是获取了基本系统中的文件。

所以我更深入地研究并尝试设置EXTRA_LDFLAGS_PROGRAM而不是LDFLAGS

export EXTRA_LDFLAGS_PROGRAM=-L/usr/local/curl-7.49.1/lib

现在构建成功了。我不知道这是否是解决问题的正确方法,也不知道这是否是错误或配置错误。如果有人能向我澄清这一点,我会非常高兴。

所以 - 您的情况并不完全相同,但在开始配置之前请尝试一下:

export EXTRA_LDFLAGS_PROGRAM=-L/usr/local/lib/

让我知道这是否有帮助。

答案2

如果有人再次查找这个问题,我很确定答案就在 ./configure 命令的 --libdir= 参数中:

  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]

有时你需要 --libdir=/usr/lib/x86_64-linux-gnu 因为 Ubuntu 在 /usr/lib/x86_64-linux-gnu 中保留了许多库,有时你需要 --libdir=/usr/local/lib 例如当您已经从源代码构建了 libxml 并将其放置在 /usr/local 中,在其他情况下,有时最简单的解决方案是将文件从 /usr/local/lib 符号链接到 /usr/lib/x86_64-linux-gnu

相关内容