繁体   English   中英

无法通过intl-support安装PHP 5.3.0

[英]Trouble installing PHP 5.3.0 with intl-support

目前,我正在尝试在某些Linux测试服务器上安装PHP 5.3.0。 由于我们急切地等待ext / intl,我们想检查一下它提供的功能。 我正在使用以下参数成功运行configure

./configure
    --with-apxs2=/usr/local/apache2/bin/apxs
    --prefix=/usr/local/php
    --with-zlib-dir=/usr/local/zlib
    --with-imap=/.../imap-2006k
    --with-imap-ssl
    --with-openssl=shared
    --with-iconv=shared
    --with-zlib=shared
    --with-curl=shared
    --with-curlwrappers
    --enable-exif
    --with-ldap=shared,/usr/local/openldap
    --with-ldap-sasl
    --enable-mbstring=shared
    --with-mcrypt
    --enable-soap=shared
    --enable-sockets
    --enable-zip=shared
    --enable-pdo=shared
    --with-pdo-sqlite=shared
    --with-sqlite=shared
    --with-mysql=shared,/usr/local/mysql
    --with-pdo-mysql=shared,/usr/local/mysql
    --with-mysqli=shared,/usr/local/mysql/bin/mysql_config
    --with-mhash=shared,/usr/local/mhash
    --with-libxml-dir=/usr/local/libxml2
    --with-xsl=shared,/usr/local/libxslt
    --enable-xmlreader=shared
    --enable-xmlwriter=shared
    --with-gmp=shared
    --with-icu-dir=/usr/local/icu
    --enable-intl

ICU 4.2位于/usr/local/icu ,PHP 5.2.9完美编译(没有int-和icu-options)。 但是,当我编译PHP 5.3.0源代码时,会收到很多此类错误消息

ext/intl/grapheme/.libs/grapheme_util.o(.text+0xbab):/.../php-5.3.0/ext/intl/grapheme/grapheme_util.c:208: undefined reference to `ubrk_close_4_2'

我很确定这与找不到共享库有关。 设置

export LD_LIBRARY_PATH=/usr/local/icu/lib

没有帮助。

谁能指出我的解决方案? 我很无能-而且我在这些事情上都不是真正的专家...

编辑:

我只是重新检查并确保各种icu库和相应的软链接都位于/usr/local/icu/lib

lrwxrwxrwx  1 root root       20 Jul  1 09:56 libicudata.so -> libicudata.so.42.0.1
lrwxrwxrwx  1 root root       20 Jul  1 09:56 libicudata.so.42 -> libicudata.so.42.0.1
-rw-r--r--  1 root root 16015140 Jul  1 09:56 libicudata.so.42.0.1
lrwxrwxrwx  1 root root       20 Jul  1 09:56 libicui18n.so -> libicui18n.so.42.0.1
lrwxrwxrwx  1 root root       20 Jul  1 09:56 libicui18n.so.42 -> libicui18n.so.42.0.1
-rwxr-xr-x  1 root root  2454770 Jul  1 09:56 libicui18n.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicuio.so -> libicuio.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicuio.so.42 -> libicuio.so.42.0.1
-rwxr-xr-x  1 root root    65299 Jul  1 09:56 libicuio.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicule.so -> libicule.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicule.so.42 -> libicule.so.42.0.1
-rwxr-xr-x  1 root root   356125 Jul  1 09:56 libicule.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libiculx.so -> libiculx.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libiculx.so.42 -> libiculx.so.42.0.1
-rwxr-xr-x  1 root root    75110 Jul  1 09:56 libiculx.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicutu.so -> libicutu.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicutu.so.42 -> libicutu.so.42.0.1
-rwxr-xr-x  1 root root   159330 Jul  1 09:56 libicutu.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicuuc.so -> libicuuc.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicuuc.so.42 -> libicuuc.so.42.0.1
-rwxr-xr-x  1 root root  1660769 Jul  1 09:56 libicuuc.so.42.0.1

make check运行大量测试-所有测试均成功完成:

[All tests passed successfully...]
Elapsed Time: 00:00:25.000
make[2]: Leaving directory `/.../icu-4.2/source/test/cintltst'
---------------
ALL TESTS SUMMARY:
All tests OK:  testdata intltest iotest cintltst
make[1]: Leaving directory `/.../icu-4.2/source/test'
make[1]: Entering directory `/.../icu-4.2/source'
verifying that icu-config --selfcheck can operate
verifying that make -f Makefile.inc selfcheck can operate
PASS: config selfcheck OK
make[1]: Leaving directory `/.../icu-4.2/source'

编辑:回答沃尔克的问题

我从源代码安装了ICU 4.2,正如我在构建过程上方所写,单元测试和安装都正常。

/usr/local/icu/bin/icu-config --version
4.2.0.1

/usr/local/icu/bin/icu-config --prefix
/usr/local/icu

/usr/local/icu/bin/icu-config --cppflags-searchpath
-I/usr/local/icu/include

/usr/local/icu/bin/icu-config --ldflags --ldflags-icuio
-lpthread -lm   -L/usr/local/icu/lib -licui18n -licuuc -licudata  -lpthread -lm   -licuio

objdump -C /usr/local/icu/lib/libicuuc.so.42.0.1
// doesn't work because of unrecognized argument -C

有关VolkerK评论的编辑:

不,没有涉及编译器的切换-我直接一个接一个地运行了两个构建过程。 objdump /usr/local/icu/lib/libicuuc.so.42.0.1也不起作用,但是我设法运行了

objdump -t /usr/local/icu/lib/libicuuc.so.42.0.1 | grep ubrk_close
00000000000d2484 g     F .text  000000000000002d              ubrk_close_4_2

不知道此信息是否有帮助。

编辑VolkerK的edit1和edit2

我认为这是有问题的-系统上确实存在另一个icu版本; 至少有一部分(例如,没有其他icu-config;只有/usr/local/icu/bin )。

gcc -lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio -print-file-name=libicuuc.so返回

/usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/../../../../lib64/libicuuc.so

gcc -lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio -print-file-name=libicuuc.so.42返回

libicuuc.so.42

所以问题似乎是如何使新的lib路径进入构建过程? 顺便说一句,我从您的回答中学到了很多-谢谢大家。

我还尝试编译您的简单测试程序-并且它也因未定义的引用错误而失败,很可能是由于PHP无法编译的相同原因。

如何摆脱对lib-path中旧的icu-library的引用,或者如何确定新的icu-library-path的优先级?

问题似乎是二进制文件链接到错误的(共享)库文件。
首先,对我认为问题的原因进行冗长而无聊的解释。 请记住,我不是Linux专家。 我真的希望您了解我的思路,以便您可以确定这是否可行和/或我错了。
第一个(原始)解决方案很容易逆转。 运行另一个./configure,所有更改均为历史记录。 我认为这很节省。

为什么首先要具有icu 4-2特定的依赖关系? 让我们看一下php的intl扩展的源文件(ext / intl / grapheme / grapheme_string.c)

#include <unicode/ubrk.h>
...
PHP_FUNCTION(grapheme_substr)
{
   ...
   ubrk_close(bi);
   ...

到目前为止,还没有特定于版本的代码。 无论您使用的是icu 3.4还是icu 4.2,grapheme_string.c看起来都相同。 ubrk_close_4_2来自哪里?
当您运行“ ./configure ... --with-icu-dir = / usr / local / icu”命令时,将执行文件ext / intl / config.m4。 在此过程中,将调用icu-config来获取构建php所需的包含路径和库文件。 您提供了安装到icu的路径,归结为

ICU_CONFIG="$PHP_ICU_DIR/bin/icu-config"
ICU_INCS=`$ICU_CONFIG --cppflags-searchpath`
ICU_LIBS=`$ICU_CONFIG --ldflags --ldflags-icuio`

被执行。 您已经尝试过icu-config,所以您知道它的输出以及ICU_INCS和ICU_LIBS包含的内容。 编译/链接文件时,会将ICU_INCS和ICU_LIBS传递给gcc。 gcc(显然)没有在其默认目录中找到unicode / ubrk.h,因此它在ICU_INCS提供的其他包含目录中搜索了文件,在其中找到了icu 4.2包含文件。 unicode / ubrk.h包含unicode / utypes.h,然后包含unicode / urename.h-并再次包含icu 4.2头文件。 在这种情况下,unicode / urename.h包含#define ubrk_close ubrk_close_4_2。
完成预处理程序后,ubrk_close(bi)已被ubrk_close_4_2(bi)取代。

PHP_FUNCTION(grapheme_substr)
{
   ...
   ubrk_close_4_2(bi);
   ...

现在,您具有特定于版本的依赖性,这是某些库必须解决的对ubrk_close_4_2的引用。
因此,包含部分确实起作用。 它确实找到了您的icu 4.2版本并使用了其头文件。 到目前为止,一切都很好。
现在到链接器部分。 您的情况是ICU_LIBS包含

-lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio

-licuuc告诉gcc“找到一个名为'icuuc'的库并使用它”。 然后,gcc在LIB路径中搜索具有某些匹配“ icuuc”的命名方案的文件。
在这种情况下,libicuuc.so。 请注意,它不会查找版本特定的文件名,而只会查找libicuuc.so。 一旦找到这样的文件,它将不再寻找另一个文件。 第一个gcc搜索其默认路径。 然后,它将搜索其他库路径-按照它们提供给gcc的顺序。

gcc -L / usr / lib -L ​​/ usr / local / lib -licuuc

如果有这样的文件,它将找到/usr/lib/libicuuc.so而不是/usr/local/lib/libicuuc.so(不再)。 这意味着默认路径或库路径指令的顺序可能是造成问题的原因。
当您的程序与共享库链接时,“特殊”加载程序被添加到代码中,并且共享库的名称存储在您的程序中(链接时)。
每次执行程序时,首先(运行时)加载程序(按其名称)搜索共享库,加载代码并替换一些存根跳转地址。
共享库可以“告诉”链接程序(即在链接时),加载程序在运行时应寻找的共享库的名称(SONAME属性)。 查看您在问题文本中提供的目录列表

lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicuuc.so -> libicuuc.so.42.0.1
lrwxrwxrwx  1 root root       18 Jul  1 09:56 libicuuc.so.42 -> libicuuc.so.42.0.1
-rwxr-xr-x  1 root root  1660769 Jul  1 09:56 libicuuc.so.42.0.1

libicuuc.so,这是gcc在提供-licuuc时正在寻找的文件。 链接器遵循符号链接并使用libicuuc.so.42.0.1。 该文件“告诉”(运行时)加载程序应寻找libicuuc.so.42的链接器,请参阅http://userguide.icu-project.org/packaging#TOC-ICU-Versions
加载程序将遵循符号链接并加载libicuuc.so.42.0.1,或者如果存在另一个错误修复程序libicuuc.so.42.0.2,libicuuc.so.42.0.3,无论libicuuc.so.42指向什么。 libicuuc.so.42将/应该始终指向导出icu 4.2符号的实际共享库。 该代码可能已更改/固定,但导出的符号保持不变。 您现在的问题是gcc找不到libicuuc.so-> libicuuc.so.42.0.1,但是(假设)libicuuc.so-> libicuuc.so.34.xy这个libicuuc.so.34.xy找不到导出icu 4.2符号,它不提供ubrk_close_4_2,但提供ubrk_close_3_4。 因此,没有ubrk_close_4_2->无法解决的参考错误。

第一个“解决方案”(粗略):让./configure发挥其魔力,然后...仅编辑Makefile。
在文本编辑器中打开Makefile(在源顶​​级目录中),搜索INTL_SHARED_LIBADD =并替换

-licui18n -licuuc -licudata -licuio

在那一行

/usr/local/icu/lib/libicui18n.so.42 /usr/local/icu/lib/libicuuc.so.42 /usr/local/icu/lib/libicudata.so.42 / usr / local / icu / lib /libicuio.so.42

(保留任何-lm -pthread ...不变)。 重新编译。
这“告诉” gcc /链接器不是搜索.so文件而是使用特定的文件。 结果应与您的库路径正在工作(由于SONAME)相同。
但是,每次运行./configure时,都必须再次应用“修复”。

第二种解决方案:删除其他libicuXY.so符号链接(在这里想到“ backup”一词),仅保留libicuXY.so-> libicuXY.so.42.0.1链接。 如果没有其他libicuuc.so->> libicuuc.so.34.xy链接,则gcc / linker找不到它们,也不会针对旧版本进行链接。
同样,由于已经与旧版本链接的SONAME属性二进制文件仍将起作用,因为“其加载程序”将搜索(仍然存在)libicuXY.so.34文件。
这将影响所有后续的链接器运行,即,如果您构建另一个使用较早的包含文件的项目,则将以另一种方式遇到相同的问题。 头文件和共享库(在链接时)必须匹配。

你打电话的时候

export LD_LIBRARY_PATH=/usr/local/icu/lib

那么您将覆盖当前设置的路径。 因此,可能会找到ICU,但找不到所需的其他任何库。 尝试以下方法:

export LD_LIBRARY_PATH=/usr/local/icu/lib:${LD_LIBRARY_PATH}

如果那没有帮助,我可以考虑尝试以下两种方法:

  1. 图书馆在正确的位置了吗? 也许您的安装移至其他地方,例如/usr/local/lib/icu
  2. ICU可以工作吗? 尝试ICU的“ make check”目标。 尝试编译/运行ICU附带的测试套件,或者尝试编译并运行一个简单的ICU示例。 本演示文稿(PPT)有一些简单的示例。

编辑

我想我知道了。 看来php-intl仅适用于libicu 3.6或3.8。 我曾经在Linux发行版上搜索过php-intl,它们都依赖libicu 3.8,即使它们也发行了libicu 4.0或更高版本也是如此。 intl成为php本身的一部分之前最后一个changelog表示相同。

我建议安装libicu 3.8,然后重试。

ld很可能不知道在哪里可以找到那些库。 您将不得不(每次)更新LD_LIBRARY_PATH或让ldconfig了解您的新库。

您可以:

  • 将其安装在/ usr / local / lib或/ usr / lib中
  • 将其位置添加到/etc/ld.so.conf并重新运行/ sbin / ldconfig

现在,即使ldconfig由安装该库的任何设备运行,由于/ usr / local / icu / lib不在其范围内,ldconfig也不知道其位置。 如果该库已安装到/ usr / local / lib / icu,则ldconfig会知道在哪里可以找到它,而您不必手动指定LD路径。

我建议仅在修改ld.so.conf之前将库重新安装到/ usr / local / lib并运行ldconfig,但是如果只是想使其工作,则修改该文件并不是很大的禁忌。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM