草庐IT

php - 无法通过intl-support安装PHP 5.3.0

coder 2023-06-20 原文

目前,我正在尝试在某些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库和相应的软链接(soft link)都位于/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'

编辑:VolkerK的questions 的答案

我从源代码安装了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 and 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路径进入构建过程?顺便说一句,我从您的答案中学到了很多东西-谢谢大家。

我还尝试编译您的简单测试程序-并且它也因 undefined reference 错误而失败,很可能是由于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时正在寻找的文件。链接器遵循符号链接(symbolic link)并使用libicuuc.so.42.0.1。该文件“告诉”(运行时)加载程序应寻找libicuuc.so.42的链接程序,请参阅http://userguide.icu-project.org/packaging#TOC-ICU-Versions
加载程序将遵循符号链接(symbolic link)并加载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.x.y。这个libicuuc.so.34.x.y不会导出icu 4.2符号,它不会提供ubrk_close_4_2,但会提供ubrk_close_3_4。因此,没有ubrk_close_4_2-> Unresolved reference 错误。

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

关于php - 无法通过intl-support安装PHP 5.3.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1078412/

有关php - 无法通过intl-support安装PHP 5.3.0的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  5. ruby - 完全离线安装RVM - 2

    我打算为ruby​​脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn

  6. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  7. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  8. ruby - 如何为 emacs 安装 ruby​​-mode - 2

    我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby​​提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs

  9. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  10. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

随机推荐