used - php_extension intl
Problemas para instalar PHP 5.3.0 con intl-support (3)
Existe una buena posibilidad de que ld
no sepa dónde encontrar esas bibliotecas. Tendrá que actualizar LD_LIBRARY_PATH (cada vez) o hacer que ldconfig conozca su nueva biblioteca.
Tu también puedes:
- Instálelo en / usr / local / lib o / usr / lib
- Agregue su ubicación a /etc/ld.so.conf y vuelva a ejecutar / sbin / ldconfig
En este momento, incluso si ldconfig fuera ejecutado por cualquier instalación de la biblioteca, ldconfig no tendría idea de su ubicación porque / usr / local / icu / lib no está en su alcance. Si la biblioteca se instaló en / usr / local / lib / icu, ldconfig sabría dónde encontrarla, y no tendría que especificar la ruta LD manualmente.
Recomiendo simplemente volver a instalar la biblioteca en / usr / local / lib y ejecutar ldconfig antes de modificar ld.so.conf, sin embargo, modificar ese archivo no es un gran tabú si solo quieres que funcione.
Actualmente estoy tratando de instalar PHP 5.3.0 en algún servidor de prueba de Linux. Como hemos esperado urgentemente para ext / intl, queremos verificar las funciones que proporciona. Estoy ejecutando configure
correctamente con los siguientes argumentos
./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 se encuentra en /usr/local/icu
y PHP 5.2.9 compilado sin problemas (sin las opciones int e icu). Pero cuando cumplo con la fuente PHP 5.3.0 recibo un montón de mensajes de error del tipo
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''
Estoy bastante seguro de que tiene algo que ver con no encontrar las bibliotecas compartidas. Ajuste
export LD_LIBRARY_PATH=/usr/local/icu/lib
no ayuda.
¿Alguien puede indicarme alguna solución? No tengo ni idea, y no soy un verdadero experto en estas cosas ...
EDITAR:
Acabo de volver a verificar y me aseguré de que las diversas icu-libraries y los respectivos soft links se encuentren en /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
ejecuta toneladas de pruebas, todas con éxito:
[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: respuestas a las preguntas de VolkerK
Instalé ICU 4.2 desde la fuente y como escribí anteriormente, el proceso de compilación, las pruebas unitarias y la instalación funcionaron bien.
/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
EDITA con respecto al comentario de VolkerK:
No, no ha habido ningún cambio en el compilador involucrado. Ejecuté ambos procesos de compilación directamente uno después del otro. objdump /usr/local/icu/lib/libicuuc.so.42.0.1
tampoco funciona pero logré ejecutar
objdump -t /usr/local/icu/lib/libicuuc.so.42.0.1 | grep ubrk_close
00000000000d2484 g F .text 000000000000002d ubrk_close_4_2
No sé si esta información puede ayudar.
EDIT en VolkerK''s edit1 y edit2 :
Creo que existe el problema: de hecho, hay otra icu-versión en el sistema; al menos en partes (no hay otra icu-config, por ejemplo, solo la de /usr/local/icu/bin
).
gcc -lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio -print-file-name=libicuuc.so
regresa
/usr/lib64/gcc-lib/x86_64-suse-linux/3.3.5/../../../../lib64/libicuuc.so
mientras que gcc -lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio -print-file-name=libicuuc.so.42
regresa
libicuuc.so.42
Entonces, ¿el problema parece ser cómo colocar el nuevo camino de lib en el proceso de compilación? Por cierto, aprendí mucho de sus respuestas, gracias a todos ustedes.
También traté de compilar tu programa de prueba simple, y también falla con el mismo error de referencia no definido , muy probablemente debido a la misma razón por la que PHP no compilará.
¿Cómo puedo deshacerme de la referencia a la antigua icu-library en lib-path o cómo priorizo la nueva icu-library-path?
Cuando usted llama
export LD_LIBRARY_PATH=/usr/local/icu/lib
entonces está sobrescribiendo la ruta establecida actualmente. Por lo tanto, es posible que encuentre la UCI, pero no encontrará ninguna de las otras bibliotecas que necesita. Pruebe esto en su lugar:
export LD_LIBRARY_PATH=/usr/local/icu/lib:${LD_LIBRARY_PATH}
Si eso no ayuda, puedo pensar en dos cosas para probar:
- ¿Está la biblioteca en el lugar correcto? Tal vez su instalación se trasladó a otro lugar, como
/usr/local/lib/icu
lugar? - ¿La UCI funciona? Pruebe el objetivo "make check" para ICU. Intente compilar / ejecutar el conjunto de pruebas incluido con ICU o intente compilar y ejecutar un ejemplo trivial de ICU. Esta presentación (PPT) tiene algunos ejemplos triviales.
EDITAR
Creo que lo descubrí. Parece que php-intl solo funciona con libicu 3.6 o 3.8. He buscado en Google para siempre distribución de Linux envío php-intl y todos ellos dependen de libicu 3.8 incluso cuando también están enviando libicu 4.0 o posterior. El último registro de cambios antes de intl se convirtió en parte de php en sí mismo indica lo mismo.
Sugiero instalar libicu 3.8 y volver a intentarlo.
El problema parece ser que el binario está vinculado con los archivos de biblioteca incorrectos (compartidos).
Primero una explicación larga y aburrida de lo que creo que es el problema. Tenga en cuenta que no soy un experto en Linux. Realmente quiero que entiendas mi tren de ideas para que puedas decidir si es factible y / o dónde estoy equivocado.
La primera solución (cruda) es fácilmente reversible. Ejecute otra ./configure y todos los cambios sean históricos. Creo que es bonito guardar.
¿Por qué tiene icu 4-2 dependencias específicas en primer lugar? Echemos un vistazo a un archivo fuente de la extensión intl de php (ext / intl / grapheme / grapheme_string.c)
#include <unicode/ubrk.h>
...
PHP_FUNCTION(grapheme_substr)
{
...
ubrk_close(bi);
...
Hasta ahora no hay un código específico de versión. grapheme_string.c tiene el mismo aspecto ya sea que uses icu 3.4 o icu 4.2. ¿De dónde viene el ubrk_close_4_2?
Cuando ejecuta el comando "./configure ... --with-icu-dir = / usr / local / icu" se ejecuta el archivo ext / intl / config.m4. En este proceso, se llama a icu-config para obtener la ruta de inclusión y los archivos de biblioteca necesarios para compilar php. Proporcionó un camino a su instalación icu que se reduce a eso
ICU_CONFIG="$PHP_ICU_DIR/bin/icu-config"
ICU_INCS=`$ICU_CONFIG --cppflags-searchpath`
ICU_LIBS=`$ICU_CONFIG --ldflags --ldflags-icuio`
es ejecutado. Has probado icu-config, para que sepas qué produce y, por lo tanto, qué ICU_INCS y ICU_LIBS contienen. ICU_INCS y ICU_LIBS se pasan a gcc cuando los archivos se compilan / vinculan. gcc (aparentemente) no encontró unicode / ubrk.h en su directorio predeterminado, por lo que buscó el archivo en los directorios de inclusión adicionales provistos por ICU_INCS donde encontró que el icu 4.2 incluye archivos. unicode / ubrk.h incluye unicode / utypes.h que luego incluye unicode / urename.h - y nuevamente se incluyen los archivos de cabecera icu 4.2. En este caso, unicode / urename.h incluye #define ubrk_close ubrk_close_4_2.
Cuando el preprocesador finaliza, ubrk_close (bi) ha sido reemplazado por ubrk_close_4_2 (bi).
PHP_FUNCTION(grapheme_substr)
{
...
ubrk_close_4_2(bi);
...
Ahora tiene una dependencia específica de la versión, una referencia a ubrk_close_4_2 que debe resolver alguna biblioteca.
Entonces, la parte de inclusión funcionó. De hecho, encontró su versión icu 4.2 y utilizó sus archivos de encabezado. Hasta aquí todo bien.
Ahora para la parte del enlazador. En tu caso, ICU_LIBS contiene
-lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio
-licuuc le dice a gcc "búscame una biblioteca llamada ''icuuc'' y úsala". gcc luego busca en las rutas LIB los archivos con un cierto esquema de nomenclatura que coincida con "icuuc".
En este caso libicuuc.so. Tenga en cuenta que no busca un nombre de archivo específico de la versión, solo libicuuc.so. Una vez que ha encontrado dicho archivo, no buscará otro. Primeras búsquedas de gcc en sus rutas predeterminadas. Luego busca las rutas adicionales de la biblioteca, en el orden en que se proporcionan a gcc. Es decir
gcc -L / usr / lib -L / usr / local / lib -licuuc
encontrará /usr/lib/libicuuc.so si existe dicho archivo y no /usr/local/lib/libicuuc.so (más). Lo que significa que la causa de la falla es la ruta predeterminada o el orden de las directivas de la ruta de la biblioteca.
Cuando su programa está vinculado a objetos compartidos, se agrega un cargador "especial" al código y el nombre del objeto compartido se almacena en su programa (en el momento del enlace).
Cada vez que se ejecuta su programa, primero el cargador (en tiempo de ejecución) busca el objeto compartido (por su nombre), carga el código y reemplaza algunas direcciones de salto de código auxiliar.
El objeto compartido puede "decirle" al vinculador (es decir, en tiempo de enlace) el nombre del objeto compartido que el cargador debe buscar (propiedad SONAME) en el tiempo de ejecución. Eche un vistazo a la lista de directorios que proporcionó en su texto de pregunta
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, ese es el archivo que gcc está buscando cuando se proporciona -licuuc. El enlazador sigue el enlace simbólico y usa libicuuc.so.42.0.1. Este archivo "le dice" al vinculador que el cargador (en tiempo de ejecución) debe buscar libicuuc.so.42, consulte http://userguide.icu-project.org/packaging#TOC-ICU-Versions .
El cargador seguirá el enlace simbólico y cargará libicuuc.so.42.0.1, o si hay otra corrección de error libicuuc.so.42.0.2, libicuuc.so.42.0.3, a lo que apunta libicuuc.so.42. libicuuc.so.42 siempre / deberá apuntar a un objeto compartido real que exporte los símbolos icu 4.2. Es posible que el código haya cambiado o se haya corregido, pero los símbolos exportados siguen siendo los mismos. Su problema ahora es que gcc no encuentra libicuuc.so-> libicuuc.so.42.0.1 pero (digamos) libicuuc.so-> libicuuc.so.34.xy Este libicuuc.so.34.xy no exportar los símbolos icu 4.2, no proporciona ubrk_close_4_2 pero ubrk_close_3_4. Entonces, no ubrk_close_4_2 -> error de referencia no resuelto.
Primera "solución" (crudo): Let ./configure hace su magia y luego ... solo edita el Makefile.
Abra el archivo Makefile (en el directorio superior de origen) en un editor de texto, busque INTL_SHARED_LIBADD = y reemplace
-licui18n -licuuc -licudata -licuio
en esa línea por
/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
(deja cualquier -lm -pthread ... como están). Compilar de nuevo
Esto "le dice" al gcc / linker que no busque los archivos .so sino que use los específicos. El resultado debería ser el mismo que si tu ruta de acceso a la biblioteca funcionara (debido a SONAME).
Pero cada vez que ejecuta ./configure, debe volver a aplicar el "arreglo".
Segunda solución: elimine los otros enlaces simbólicos libicuXY.so (de ahí viene la palabra "copia de seguridad"), solo mantenga los enlaces libicuXY.so-> libicuXY.so.42.0.1. Si no hay otros enlaces libicuuc.so - >> libicuuc.so.34.xy el gcc / linker no puede encontrarlos y no enlazará con las versiones anteriores.
De nuevo, debido a los binarios de propiedades de SONAME que ya han sido vinculados con la versión anterior seguirán funcionando porque "su" cargador buscará los archivos libicuXY.so.34 (aún existentes).
Esto afectará todas las ejecuciones posteriores del enlazador, es decir, si construye otro proyecto que use los archivos de inclusión anteriores, se encontrará con el mismo problema al revés. Los archivos de encabezado y los objetos compartidos (en tiempo de enlace) deben coincidir.