Pergunta

Atualmente eu estou tentando instalar o PHP 5.3.0 em algum servidor de teste Linux. Como já esperado com urgência para ext / intl queremos verificar as características que ele proporciona. Estou correndo configure com sucesso com os seguintes 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

UTI 4.2 está localizado na /usr/local/icu e PHP 5.2.9 compilado perfeitamente (sem as INT e UTI-opções). Mas quando eu complie a fonte PHP 5.3.0 Eu recebo um monte de mensagens de erro do 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'

Tenho certeza de que tem algo a ver com a não encontrar as bibliotecas compartilhadas. Configuração

export LD_LIBRARY_PATH=/usr/local/icu/lib

não ajuda.

pode apontar-me alguém a alguma solução? Eu sou um pouco à nora - e eu não sou verdadeiro especialista nestas coisas ...

EDIT:

Eu só checado e que garantir que as várias UTI-bibliotecas e os respectivos soft links estão todos localizados na /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 corre toneladas de testes - todos eles com sucesso:

[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: respostas a de VolkerK perguntas

Eu instalei UTI 4.2 a partir da fonte e como eu escrevi acima o processo de construção, a unidade-testes e a instalação todos correu bem.

/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 sobre o comentário de VolkerK:

Não, não houve nenhuma mudança do compilador envolvidos - Corri ambos os processos de construção directamente um após o outro. objdump /usr/local/icu/lib/libicuuc.so.42.0.1 não quer trabalhar, mas eu consegui executar

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

Não sei se esta informação pode ajudar.

EDIT ON da VolkerK edit1 e edit2 :

Eu acho que aí está a dificuldade - há de fato uma outra UTI-versão no sytem; pelo menos em partes (não há nenhum outro icu-config por exemplo, apenas um em /usr/local/icu/bin).

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

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

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

libicuuc.so.42

Assim, o problema parece ser, como obter a nova lib-path para o processo de construção ?? By the way, eu aprendi muito com suas respostas - obrigado de todos vocês

.

Eu também tentei compilar o seu programa de teste simples - e também falha com o mesmo referência indefinida erro, provavelmente devido ao mesmo motivo PHP não irá compilar.

Como posso livrar-se da referência à antiga UTI-biblioteca no lib-path ou como faço para priorizar a nova UTI-library-path?

Foi útil?

Solução

O problema parece ser que o binário é ligado contra o mal (compartilhados) arquivos de biblioteca.
Primeiro, uma longa e chata explicação sobre o que eu acho que é o problema. Tenha em mente que eu não sou um especialista em linux. Eu realmente quero que você entenda a minha linha de pensamentos para que você possa decidir se é viável e / ou onde eu estiver errado.
A primeira solução (em bruto) é facilmente reversível. Executar outro ./configure e todas as alterações são história. Eu acho que é muito salvar.

Por que você tem de UTI 4-2 dependências específicas em primeiro lugar? Vamos dar uma olhada em um arquivo de fonte de extensão intl do PHP (ext / intl / grafema / grapheme_string.c)

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

Até agora não há nenhum código versão específica. grapheme_string.c parece o mesmo se você usa UTI 3.4 ou UTI 4,2. Onde é que os ubrk_close_4_2 vem?
Quando você executa o "./configure ... --with-icu-dir = / usr / local / UTI" comandar o arquivo ext / intl / config.m4 é executado. Neste processo UTI-config é chamado para obter o caminho e arquivos de biblioteca necessários para construir php incluir. Você forneceu um caminho para sua instalação UTI que se resume a esse

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

é executado. Você já tentou UTI-config-se, então você sabe o que ele produz e, portanto, o que ICU_INCS e ICU_LIBS conter. ICU_INCS e ICU_LIBS são passados ??para gcc quando os arquivos são compilados / ligada. gcc (apperently) não encontrou unicode / ubrk.h nele do diretório padrão, por isso procurou o arquivo no adicionais incluem diretórios fornecidos pelo ICU_INCS onde encontraram a UTI 4.2 incluem arquivos. unicode / ubrk.h inclui unicode / utypes.h que então inclui unicode / urename.h - e novamente os arquivos de cabeçalho UTI 4.2 estão incluídos. Neste caso unicode / urename.h inclui #define ubrk_close ubrk_close_4_2.
Quando o pré-processamento é feito ubrk_close (bi) foi substituído por ubrk_close_4_2 (bi).

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

Agora você tem uma dependência versão específica, uma referência ao ubrk_close_4_2 que alguns biblioteca tem de resolver.
Assim, a incluir parte não funcionou. É, de fato, encontrar a sua versão UTI 4.2 e usado seus arquivos de cabeçalho. Até aqui tudo bem.
Agora, a parte vinculador. No seu caso ICU_LIBS contém

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

-licuuc diz gcc "encontrar-me uma biblioteca chamada 'icuuc' e usá-lo". gcc, em seguida, procura os caminhos de LIB para arquivos com um determinado esquema de nomeação que jogo "icuuc".
Neste caso libicuuc.so. Note que ele não olhar para um nome de arquivo versão específica, apenas libicuuc.so. Uma vez que tenha encontrado esse arquivo a ele não vai olhar para o outro. Primeiras pesquisas gcc em seus caminhos padrão. Em seguida, ele procura os caminhos de biblioteca adicionais - na ordem em que são fornecidos para gcc. I.

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

encontrará /usr/lib/libicuuc.so se existe tal arquivo um e não /usr/local/lib/libicuuc.so (mais). O que significa que tanto o caminho padrão ou a ordem das directivas caminho da biblioteca pode ser a causa do seu problema.
Quando o programa está ligado contra objetos compartilhados um carregador de "especial" é adicionado ao código e o nome do objeto compartilhado é armazenado em seu programa (em tempo de link).
Cada vez que seu programa é executado, o primeiro (runtime) pesquisas carregador para o objeto compartilhado (pelo seu nome), carrega o código e substitui alguns endereços esboço de salto.
O objeto compartilhado pode "dizer" o ligador (ou seja, em tempo de ligação) o nome do objeto compartilhado o carregador deve procurar (propriedade SONAME) em tempo de execução. Dê uma olhada no diretório de anúncio que você forneceu em sua texto da pergunta

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, que é o arquivo gcc está procurando quando -licuuc é fornecido. O vinculador segue o link simbólico e usos libicuuc.so.42.0.1. Este arquivo "diz" o vinculador que o (runtime) loader deve procurar libicuuc.so.42, consulte http://userguide.icu-project.org/packaging#TOC-ICU-Versions .
O carregador irá seguir o SYMLtinta e carga libicuuc.so.42.0.1, ou se há outra libicuuc.so.42.0.2 bugfix, libicuuc.so.42.0.3, qualquer que seja libicuuc.so.42 está a apontar para. libicuuc.so.42 vai / deve sempre apontar para um objeto compartilhado real que as exportações da UTI 4,2 símbolos. O código pode ter mudado / fixo, mas os símbolos exportados permanecer o mesmo. Seu problema agora é que gcc não encontrar libicuuc.so-> libicuuc.so.42.0.1 mas (digamos de LET) libicuuc.so-> libicuuc.so.34.x.y. Este libicuuc.so.34.x.y não exporta UTI 4,2 símbolos, ele não fornece ubrk_close_4_2 mas ubrk_close_3_4. Então, não ubrk_close_4_2 -.> Erro de referência não resolvida

Primeiro "solução" (bruto): Vamos ./configure fazer a sua magia e então ... basta editar o Makefile
. Abra o Makefile (no diretório fonte superior) em um editor de texto, procurar INTL_SHARED_LIBADD = e substitua

-licui18n -licuuc -licudata -licuio

nessa linha 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

(deixar qualquer -lm -pthread ... como eles são). Compilar novamente.
Este "diz" o gcc / vinculador não para procurar os arquivos .so mas para usar as específicas. O resultado deve ser o mesmo que se o seu caminho da biblioteca estava trabalhando (beacuse de SONAME).
Mas cada vez que você execute ./configure você tem que aplicar a "correção" novamente.

Segundo solução: Remover os outros links simbólicos libicuXY.so (que é onde a palavra "backup" vem à mente), apenas manter as ligações libicuXY.so-> libicuXY.so.42.0.1. Se não houver nenhum outro libicuuc.so - >> libicuuc.so.34.x.y liga o gcc / vinculador não é possível encontrá-los e não vai ligar contra as versões antigas
. Novamente, devido a binários de propriedade soname que já foram ligados contra a versão antiga ainda irá funcionar porque "seu" loader irá procurar os arquivos libicuXY.so.34 (ainda existentes).
Isso afetará todas as corridas vinculador subsequentes, ou seja, se você construir um outro projeto que usa os mais velhos incluem arquivos que você vai correr para o mesmo problema o contrário. Os arquivos de cabeçalho e os objetos compartilhados (em tempo de link) devem corresponder.

Outras dicas

Há uma boa chance de que ld não sabe onde encontrar essas bibliotecas. Você terá que quer LD_LIBRARY_PATH atualização (cada vez), ou ter ldconfig aprender de sua nova biblioteca.

Você pode:

  • Instale-o em / usr / local / lib ou / usr / lib
  • Adicione sua localização para /etc/ld.so.conf e re-run / sbin / ldconfig

Agora, mesmo que ldconfig foi executado por qualquer instalada a biblioteca, ldconfig não teria nenhuma idéia de sua localização porque / usr / local / UTI / lib não é no seu âmbito. Se a biblioteca foi instalado para / usr / local / lib / UTI, ldconfig saberia onde encontrá-lo, e você não teria que especificar o caminho LD manualmente.

Eu recomendo apenas re-instalar a biblioteca para / usr / / lib local e executando ldconfig antes de modificar ld.so.conf, no entanto modificar esse arquivo não é um grande tabu, se você só quer fazê-lo funcionar.

Quando você chama

export LD_LIBRARY_PATH=/usr/local/icu/lib

então você está substituindo o caminho definido no momento. Então, pode ser que ele vai encontrar UTI, mas não vai encontrar nenhum dos outros bibliotecas que necessita. Tente isto em vez disso:

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

Se isso não ajudar, eu posso pensar em duas coisas para tentar:

  1. É a biblioteca no lugar certo? Talvez sua instalação foi morar em outro lugar, como /usr/local/lib/icu vez?
  2. Does UTI trabalho? Experimente o "make check" alvo para UTI. Tente compilar / executar o conjunto de testes incluídos com UTI, ou tentar compilar e executar um exemplo UTI trivial. Esta apresentação (PPT) tem alguns exemplos triviais.

Editar

Eu acho que eu percebi isso. Parece que php-intl só funciona com libicu 3.6 ou 3.8. Eu pesquisei para sempre distro linux transporte php-Intl e todos eles depende libicu 3.8, mesmo quando eles também estão enviando libicu 4.0 ou posterior. A última changelog antes intl tornou-se parte da própria php indica o mesmo.

Eu sugiro instalar libicu 3.8 e tentar novamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top