Ste*_*rig 5 php linux installation intl
目前我正在尝试在某些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
Run Code Online (Sandbox Code Playgroud)
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'
Run Code Online (Sandbox Code Playgroud)
我很确定它与找不到共享库有关.设置
export LD_LIBRARY_PATH=/usr/local/icu/lib
Run Code Online (Sandbox Code Playgroud)
没有帮助.
谁能指点我一些解决方案?我很无能 - 我不是这些事情的真正专家......
编辑:
我只是重新检查并确保各种icu-libraries和相应的软链接都位于/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
Run Code Online (Sandbox Code Playgroud)
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'
Run Code Online (Sandbox Code Playgroud)
编辑:回答VolkerK的问题
我从源代码安装了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
Run Code Online (Sandbox Code Playgroud)
关于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
Run Code Online (Sandbox Code Playgroud)
不知道这些信息是否有帮助.
编辑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
Run Code Online (Sandbox Code Playgroud)
而gcc -lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio -print-file-name=libicuuc.so.42
回归
libicuuc.so.42
Run Code Online (Sandbox Code Playgroud)
所以问题似乎是,如何将新的lib-path引入构建过程?顺便说一句,我从你的答案中学到了很多 - 谢谢你们所有人.
我也尝试编译你的简单测试程序 - 它也失败了同样的未定义引用错误,很可能是由于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);
...
Run Code Online (Sandbox Code Playgroud)
到目前为止,还没有特定于版本的代码.无论您使用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`
Run Code Online (Sandbox Code Playgroud)
被执行.您自己尝试过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);
...
Run Code Online (Sandbox Code Playgroud)
现在您有一个特定于版本的依赖项,即对某些库必须解析的ubrk_close_4_2的引用.
所以包含部分确实有效.它确实找到了你的icu 4.2版本并使用了它的头文件.到现在为止还挺好.
现在为链接器部分.在你的情况下ICU_LIBS包含
-lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio
Run Code Online (Sandbox Code Playgroud)
-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
Run Code Online (Sandbox Code Playgroud)
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符号链接(这就是"备份"这个词的含义),只保留libicuXY.so-> libicuXY.so.42.0.1链接.如果没有其他libicuuc.so - >> libicuuc.so.34.xy链接,gcc/linker无法找到它们,也不会链接旧版本.
再次因为SONAME属性已经与旧版本链接的二进制文件仍将起作用,因为"他们的"加载器将搜索(仍然存在的)libicuXY.so.34文件.
这将影响所有后续链接器运行,即如果您构建另一个使用旧包含文件的项目,则会遇到相同的问题.头文件和共享对象(在链接时)必须匹配.
归档时间: |
|
查看次数: |
8737 次 |
最近记录: |