Trouble intl-destek ile PHP 5.3.0 yükleme

3 Cevap php

Currently I'm trying to install PHP 5.3.0 on some Linux testing server. As we've urgently waited for ext/intl we want to check out the features it provides. I'm running configure successfully with the following arguments

./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

YBÜ 4.2 /usr/local/icu bulunan ve PHP 5.2.9 (int-ve-icu seçenek olmaksızın) kusursuzca derlendi. Ben PHP 5.3.0 kaynağını complie Ama ben tür hata mesajları bir sürü olsun

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'

Ben paylaşımlı kütüphaneleri bulmak değil bir ilgisi vardır eminim. Ayarı

export LD_LIBRARY_PATH=/usr/local/icu/lib

yardımcı olmuyor.

Herkes bazı çözüm beni işaret edebilir? Ben oldukça clueless değilim - ve ben bu şeyler gerçek uzman değilim ...

EDIT:

Ben sadece rechecked ve çeşitli YBÜ-kütüphaneler ve ilgili yumuşak bağlantılar Tüm bulunan emin yaptı /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 testlerin ton çalışır - başarılı hepsi:

[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'

EDIT: answers to VolkerK's questions

Ben kaynağından YBÜ 4.2 yüklü ve inşa süreci yukarıda yazdığım gibi, birim testleri ve montajı, tüm iyi gitti.

/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

EDIT regarding VolkerK's comment:

Hayır, ilgili derleyici hiçbir anahtar olmuştur - Ben hem doğrudan birbiri ardına süreçleri inşa koştu. objdump /usr/local/icu/lib/libicuuc.so.42.0.1 ya da işe ama çalıştırmak için yönetilen değil

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

Bu bilgi yardımcı olabilir bilmiyorum.

EDIT on VolkerK's edit1 and edit2:

Ben ovmak olduğunu düşünüyorum - Sytem başka icu sürümü gerçekten var; en azından kısmen (örneğin başka bir yoğun bakım-yapılandırma yoktur, yalnızca /usr/local/icu/bin bir).

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

/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 döner ise

libicuuc.so.42

Yani sorun oluşturma sürecine yeni lib-yol almak için, nasıl görünüyor? Bu arada, ben senin cevaplar çok şey öğrendim - Hepinize teşekkür bulunuyor.

Ben de basit bir test programı derlemek için çalıştı - ve aynı zamanda nedeniyle PHP derlemek değil aynı nedenle büyük olasılıkla, aynı undefined reference hata ile başarısız olur.

How can I get rid of the reference to the old icu-library in the lib-path or how do I prioritize the new icu-library-path?

3 Cevap

The problem seems to be that the binary is linked against the wrong (shared) library files.
First a long, boring explaination of what I think the problem is. Keep in mind that I'm not a linux expert. I really want you to understand my train of thoughts so that you can decide if it's feasible and/or where I'm wrong.
The first (crude) solution is easily reversible. Run another ./configure and all changes are history. I think it's pretty save.

Neden ilk etapta 4-2 belirli bağımlılıkları YBÜ var mı? En PHP'nin intl uzantısı (ext / intl / sesletim / grapheme_string.c) bir kaynak dosyaya bir göz atalım

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

Until now there's no version specific code. grapheme_string.c looks the same whether you use icu 3.4 or icu 4.2. Where does the ubrk_close_4_2 come from?
When you run the "./configure ... --with-icu-dir=/usr/local/icu" command the file ext/intl/config.m4 is executed. In this process icu-config is called to get the include path and library files required to build php. You provided a path to your icu installation which boils down to that

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

is executed. You've tried icu-config yourself, so you know what it outputs and therefore what ICU_INCS and ICU_LIBS contain. ICU_INCS and ICU_LIBS are passed to gcc when the files are compiled/linked. gcc (apperently) didn't find unicode/ubrk.h in it's default directory, so it searched for the file in the additional include directories provided by ICU_INCS where it found the icu 4.2 include files. unicode/ubrk.h includes unicode/utypes.h which then includes unicode/urename.h - and again the icu 4.2 header files are included. In this case unicode/urename.h includes #define ubrk_close ubrk_close_4_2.
When the preprocessor is done ubrk_close(bi) has been replaced by ubrk_close_4_2(bi).

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

Now you have a version specific dependency, a reference to ubrk_close_4_2 that some library has to resolve.
So the include part did work. It did indeed find your icu 4.2 version and used its header files. So far so good.
Now for the linker part. In your case ICU_LIBS contains

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

-licuuc tells gcc "find me a library called 'icuuc' and use it". gcc then searches the LIB paths for files with a certain naming scheme that match "icuuc".
In this case libicuuc.so. Note that it doesn't look for a version specific file name, just libicuuc.so. Once it has found such a file it won't look for another one. First gcc searches in its default paths. Then it searches the additional library paths - in the order they are provided to gcc. I.e.

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

will find /usr/lib/libicuuc.so if there is such a file and not /usr/local/lib/libicuuc.so (anymore). Meaning that either the default path or the order of the library path directives may be the cause of your trouble.
When your program is linked against shared objects a "special" loader is added to the code and the name of the shared object is stored in your program (at link time).
Every time your program is executed, first the (runtime) loader searches for the shared object (by its name), loads the code and replaces some stub jump addresses.
The shared object can "tell" the linker (i.e. at link time) the name of the shared object the loader should look for (SONAME property) at runtime. Take a look at the directory listing you provided in your question text

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, that's the file gcc is looking for when -licuuc is provided. The linker follows the symlink and uses libicuuc.so.42.0.1. This file "tells" the linker that the (runtime) loader should look for libicuuc.so.42, see http://userguide.icu-project.org/packaging#TOC-ICU-Versions.
The loader will follow the symlink and load libicuuc.so.42.0.1, or if there is another bugfix libicuuc.so.42.0.2, libicuuc.so.42.0.3, whatever libicuuc.so.42 is pointing to. libicuuc.so.42 will/should always point to an actual shared object that exports the icu 4.2 symbols. The code may have changed/fixed but the exported symbols stay the same. Your problem now is that gcc doesn't find libicuuc.so->libicuuc.so.42.0.1 but (let's say) libicuuc.so->libicuuc.so.34.x.y. This libicuuc.so.34.x.y doesn't export the icu 4.2 symbols, it doesn't provide ubrk_close_4_2 but ubrk_close_3_4. So, no ubrk_close_4_2 -> unresolved reference error.

First "solution" (crude): Let ./configure do its magic and then ... just edit the Makefile.
Open the Makefile (in the source top directory) in a text editor, search for INTL_SHARED_LIBADD= and replace

-Licui18n-licuuc-licudata-licuio

bu hat tarafından

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

(leave any -lm -pthread ... as they are). Compile again.
This "tells" the gcc/linker not to search for the .so files but to use the specific ones. The result should be the same as if your library path was working (beacuse of SONAME).
But every time you run ./configure you have to apply the "fix" again.

Second solution: Remove the other libicuXY.so symlinks (that's where the word "backup" comes to mind), only keep the libicuXY.so->libicuXY.so.42.0.1 links. If there are no other libicuuc.so->>libicuuc.so.34.x.y links the gcc/linker can't find them and won't link against the old versions.
Again because of the SONAME property binaries that have already been linked against the old version will still function because "their" loader will search for the (still existing) libicuXY.so.34 files.
This will affect all subsequent linker runs, i.e. if you build another project that uses the older include files you will run into the same problem the other way around. The header files and the shared objects (at link time) must match.

ld bu kitaplıkları bulmak bilmiyor ki iyi bir şans var. Güncelleştirme LD_LIBRARY_PATH (her zaman) ya var, ya da yeni kütüphane öğrenmek Ldconfig olacaktır.

Ya yapabilirsiniz:

  • Bunu / usr / local / lib veya / usr / lib yükleyin
  • Etc / ld.so.conf ve yeniden çalıştırma / sbin / Ldconfig / onun yerini ekle

/ Usr / local / icu / lib kapsamı değil çünkü şu anda, Ldconfig kütüphane yüklü olursa olsun tarafından çalıştırılmış olsa bile, Ldconfig onun yerini hiçbir fikrim olurdu. Kütüphane / usr / local / lib / YBÜ için yüklü ise, Ldconfig nerede bulacağını bilemez ve el LD yolunu belirtmek zorunda değildir.

Ben sadece çalışma almak istiyorsanız sadece hiçbir büyük tabu Ancak bu dosyayı değiştirerek, önce ld.so.conf değiştirerek / usr / local / lib ve çalışan Ldconfig için kütüphane re-takmanızı öneririz.

Aradığınızda

export LD_LIBRARY_PATH=/usr/local/icu/lib

o anda ayarlı yolu üzerine yazıyorsunuz. Bu yüzden ICU'yu bulacaksınız ki olabilir ama bu ihtiyacı diğer kütüphanelerin herhangi bulamazsınız. Bunun yerine bu deneyin:

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

Bu işe yaramazsa ben denemek için iki şey düşünebilirsiniz:

  1. Doğru yerde kütüphane var mı? Belki de montaj yerine /usr/local/lib/icu gibi, başka bir yere taşındı?
  2. YBÜ çalışır? YBÜ için "make check" hedef sahipsiniz. YBÜ ile birlikte test paketi çalışan / derleme deneyin, ya da önemsiz bir YBÜ örneği derlemek ve çalıştırmak için deneyin. This presentation (PPT) bir kaç önemsiz örnekler vardır.

EDIT

Ben bunu çözdüm. Php-intl sadece libicu 3.6 veya 3.8 ile çalışır gibi görünüyor. Ben hiç bir Linux dağıtımı nakliye php-intl için googled var ve hepsi onlar da 4,0 veya daha sonra libicu nakliye bile libicu 3.8 bağlıdır. last changelog before intl became part of php itself ile aynı olduğunu gösterir.

Ben 3.8 libicu yükleme ve tekrar denemenizi öneririz.