2009-07-03 19 views
5

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 corriendo configure con éxito con los siguientes argumentosProblemas para instalar PHP 5.3.0 con intl-support

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

UCI 4.2 se encuentra en /usr/local/icu y PHP 5.2.9 compila sin problemas (sin las Int- y la UCI-options). Pero cuando complie la fuente PHP 5.3.0 consigo una gran cantidad 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. Configuración

export LD_LIBRARY_PATH=/usr/local/icu/lib 

no ayuda.

¿Alguien me puede indicar alguna solución? Estoy bastante desorientado - y yo soy un experto real en estas cosas ...

EDIT:

acabo vuelto a inspeccionar y se aseguró de que las distintas bibliotecas de la UCI y los respectivos enlaces de software son todos situado 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 carreras toneladas de pruebas - todos ellos 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 la questions

he instalado UCI 4.2 de origen y como he escrito sobre el proceso de construcción, la unidad de pruebas y la instalación fue bien todos VolkerK.

/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 

EDITAR en relación con el comentario de VolkerK:

No, no ha habido ningún interruptor del compilador involucrados - Corrí tanto los procesos de construir directamente una tras otra. objdump /usr/local/icu/lib/libicuuc.so.42.0.1 no funciona bien, pero me las arreglé para 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 edit1 and edit2 de VolkerK:

Creo que ahí está el problema - en efecto, hay otra versión en la UCI en el Inglés; 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 vuelve

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

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

libicuuc.so.42 

Así que el problema parece ser, cómo obtener el nuevo lib-path en el proceso de construcción ?? Por cierto, aprendí mucho de sus respuestas, gracias a todos ustedes.

También intenté compilar su programa de prueba simple - y también falla con el mismo error de referencia indefinido, probablemente debido a la misma razón por la que PHP no compilará.

¿Cómo puedo deshacerme de la referencia a la antigua biblioteca icu en lib-path o cómo priorizo ​​la nueva icu-library-path?

+0

¿Funciona la ejecución de 'ldconfig/usr/local/icu/lib'? –

+0

La salida de icu-config parece ser la correcta. Pity objdump -C no funciona. Afaik libicuuc.so debería exportar ubrk_close ... ¿Tal vez podrías probarlo sin parámetros? Solo "objdump /usr/local/icu/lib/libicuuc.so.42.0.1 ", debería mostrar qué símbolos/funciones han sido exportados por este objeto compartido. Vamos al ejemplo: solo copie y pegue entradas para ubrk_close/ubrk_close_4_2. Por cierto: no ha cambiado los compiladores (o la versión principal de gcc) entre construyendo ICU y PHP? – VolkerK

+0

Editar pregunta después del comentario de Volker K. –

Respuesta

6

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? Vamos a echar un vistazo a un archivo de origen de la extensión de php Intl (ext/intl/grafema/grapheme_string.c)

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

Hasta ahora no hay 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ó una ruta 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` 

se ejecuta. 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 proporcionados por ICU_INCS, donde encontró que el icu 4.2 incluye archivos. unicode/ubrk.h incluye unicode/utypes.h que incluye unicode/urename.h - y nuevamente se incluyen los archivos de encabezado icu 4.2. En este caso, unicode/urename.h incluye #define ubrk_close ubrk_close_4_2.
Cuando finaliza el preprocesador, ubrk_close (bi) ha sido reemplazado por ubrk_close_4_2 (bi).

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

Ahora usted tiene una dependencia específica de la versión, una referencia a ubrk_close_4_2 que alguna biblioteca tiene que resolver.
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 enlazadora. En su caso ICU_LIBS contiene

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

-licuuc dice gcc "Me encontrar una biblioteca llamada 'icuuc' y utilizarlo". 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án /usr/lib/libicuuc.so si hay un archivo de este tipo 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 tiempo 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 "indicar" 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. Tome un vistazo a la lista de directorios que ya ha proporcionado en su texto de la 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 gcc archivo está buscando cuando -licuuc se proporciona. 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.x.y. Este libicuuc.so.34.x.y no exporta los símbolos icu 4.2, no proporciona ubrk_close_4_2, pero ubrk_close_3_4. Por lo tanto, no ubrk_close_4_2 - > error de referencia no resuelto.

Primera "solución" (crudo): Let ./configure hace su magia y luego ... simplemente edite el Makefile.
Abrir el Makefile (en el directorio superior de origen) en un editor de texto, buscar y reemplazar INTL_SHARED_LIBADD =

-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 tiene que 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.x.y el gcc/linker no puede encontrarlos y no enlazará con las versiones anteriores.
Nuevamente debido a la propiedad SONAME, los binarios que ya han sido enlazados con la versión anterior seguirán funcionando porque "su" cargador buscará los archivos (todavía existentes) libicuXY.so.34.
Esto afectará a todas las ejecuciones posteriores del vinculador, es decir, si crea otro proyecto que utiliza 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.

+0

Muy buena explicación y mucho trabajo, aunque puedo probar sus soluciones propuestas hasta el lunes, acepté su respuesta, ya que proporciona una visión muy buena para los tontos (como yo) en este tema (que de alguna manera es críptico para mí). –

+0

Sé lo frustrante que puede ser ;-) Si no funciona, házmelo saber. imho gentoo en una máquina virtual es una buena cosa para jugar con Linux y nuevos paquetes fuente (aunque todavía no hay un ebuild php 5.3) – VolkerK

+0

OK - todo esto compilado ahora después de renombrar todos los enlaces simbólicos de libicuXY.so en libicuXY. so.old en/usr/lib64 para que se hayan utilizado las libs de ICU 4.2. Pero ahora parece haber otro problema: una "prueba de prueba" revela que las pruebas 9999/9999 fallaron o fueron omitidas. Pero eso también ocurre sin que icu se compile en PHP. Siguiente problema para resolver ;-) ¡Gracias de nuevo por sus grandes esfuerzos! –

0

Cuando se llama a

export LD_LIBRARY_PATH=/usr/local/icu/lib 

entonces va a sobrescribir el camino establecido actualmente. Por lo tanto, es posible que encuentre la UCI, pero no encontrará ninguna de las otras bibliotecas que necesita. Prueba este lugar:

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

Si eso no ayuda que puedo pensar en dos cosas a probar:

  1. es la biblioteca en el lugar correcto? ¿Tal vez su instalación se mudó a otra parte, como /usr/local/lib/icu?
  2. ¿Funciona la UCI? 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. This presentation (PPT) tiene algunos ejemplos triviales.

EDITAR

creo que lo he descubierto. 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 last changelog before intl became part of php itself indica lo mismo.

Sugiero instalar libicu 3.8 y volver a intentarlo.

+0

Pensé en eso también, pero: los mensajes de error son los mismos con icu-lib-dir no en LD_LIBRARY_PATH, con icu-lib-dir como el único directorio en LD_LIBRARY_PATH y con icu-lib-dir adjunto a LD_LIBRARY_PATH . La compilación simplemente no parece encontrar las bibliotecas. –

+0

Actualicé mi respuesta. Esto es todo lo que pude encontrar. –

+0

Otra actualización. Creo que necesitas libicu 3.8. –

0

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

Puede:

  • instalarlo en/usr/local/lib o/usr/lib
  • Añadir su ubicación a /etc/ld.so.conf y volver a ejecutar/sbin/ldconfig

en este momento, incluso si ldconfig se llevó a cabo por cualquier instalada la biblioteca, ldconfig no tendría ni idea de su ubicación porque/usr/local/UCI/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 modificarlo no es un gran tabú si solo quieres que funcione.

+0

Lo sentimos, no. Eso no funcionó. Ni la edición de ld.so.conf ni la instalación de icu en la ruta de biblioteca "estándar" arrojaron algunos resultados. ¿Podría haber algún problema relacionado con el entorno de 64 bits en el que se ejecuta el proceso de compilación? –

Cuestiones relacionadas