Domanda

Al momento sto cercando di installare PHP 5.3.0 su alcuni server di prova Linux. Come abbiamo urgentemente aspettato per ext / Intl vogliamo verificare le caratteristiche che offre. Io corro configure con successo con i seguenti argomenti

./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 si trova a /usr/local/icu e PHP 5.2.9 compilato senza problemi (senza le INT e ICU-opzioni). Ma quando ho complie la sorgente PHP 5.3.0 ho un sacco di messaggi di errore 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'

Sono abbastanza sicuro che abbia qualcosa a che fare con non trovare le librerie condivise. Impostazione

export LD_LIBRARY_PATH=/usr/local/icu/lib

non aiuta.

Qualcuno mi può puntare a qualche soluzione? Sono piuttosto all'oscuro - e io non sono un vero esperto in queste cose ...

Modifica

Ho appena ricontrollato e fatto in modo che i vari ICU-biblioteche e le rispettive soft link sono tutti situati in /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 tonnellate di test - tutti loro successo:

[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: risposte a di VolkerK domande

ho installato ICU 4.2 dai sorgenti e come ho scritto sopra il processo di compilazione, le unità di test e l'installazione tutto è andato bene.

/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

Modifica per quanto riguarda il commento di VolkerK:

No, non c'è stato alcun interruttore del compilatore coinvolti - ho corso sia costruire processi direttamente uno dopo l'altro. objdump /usr/local/icu/lib/libicuuc.so.42.0.1 non funziona neanche, ma sono riuscito a correre

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

Non so se questa informazione può aiutare.

EDIT di VolkerK Edit1 e EDIT2 :

Credo che qui sta il problema - v'è infatti un'altra ICU-versione sul sytem; almeno in parte (non c'è altra ICU-config per esempio, solo quello in /usr/local/icu/bin).

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

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

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

libicuuc.so.42

Così il problema sembra essere, come ottenere il nuovo lib-path nel processo di generazione ?? A proposito, ho imparato molto dalle sue risposte - grazie di tutti voi

.

Inoltre ho provato a compilare il programma di test semplice - e viene a mancare anche con la stessa di riferimento non definito errore, molto probabilmente a causa lo stesso motivo PHP non verrà compilato.

Come posso eliminare il riferimento al vecchio ICU-biblioteca nel lib-path o come faccio a dare priorità alla nuova ICU-library-path?

È stato utile?

Soluzione

Il problema sembra essere che il binario è legato contro i (condivisi) file di libreria sbagliate.
In primo luogo una lunga, noiosa spiegazione di quello che penso sia il problema. Tenete a mente che io non sono un esperto di Linux. Voglio davvero a capire il mio treno di pensieri in modo da poter decidere se è fattibile e / o dove ho sbagliato.
La prima soluzione (grezzo) è facilmente reversibile. Eseguire un altro ./configure e tutte le modifiche sono storia. Penso che sia abbastanza salvare.

Perché avete ICU 4-2 dipendenze specifiche, in primo luogo? Diamo uno sguardo a un file sorgente di estensione Intl di PHP (ext / intl / grafema / grapheme_string.c)

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

Fino ad ora non c'è alcun codice specifico di versione. grapheme_string.c sembra lo stesso se si utilizza icu icu 3.4 o 4.2. Da dove viene il ubrk_close_4_2 viene?
Quando si esegue il "./configure ... --with-ICU-dir = / usr / local / ICU" comandare il file ext / intl / config.m4 viene eseguito. In questo processo ICU-config è chiamata per ottenere il file di percorso e di libreria necessari per costruire php include. È fornito un percorso per l'installazione di terapia intensiva, che si riduce a che

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

viene eseguito. Hai provato ICU-config te stesso, in modo da sapere che cosa uscite e quindi ciò ICU_INCS e ICU_LIBS contengono. ICU_INCS e ICU_LIBS sono passati a GCC quando i file vengono compilati / collegate. gcc (apperently) non ha trovato unicode / ubrk.h nella sua directory di default, quindi cercato il file nella directory aggiuntive includono forniti da ICU_INCS dove ha trovato la terapia intensiva 4.2 includono file. unicode / ubrk.h comprende unicode / utypes.h che poi comprende unicode / urename.h - e di nuovo i file header ICU 4.2 sono inclusi. In questo caso unicode / urename.h include #define ubrk_close ubrk_close_4_2.
Quando il preprocessore è fatto ubrk_close (BI) è stato sostituito da ubrk_close_4_2 (BI).

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

Ora avete una dipendenza specifica versione, un riferimento a ubrk_close_4_2 che qualche libreria deve risolvere.
Così l'inclusione parte ha funzionato. Esso ha effettivamente trovato la versione 4.2 ICU e utilizzato i suoi file di intestazione. Fin qui tutto bene.
Ora per la parte linker. Nel tuo caso ICU_LIBS contiene

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

-licuuc dice gcc "me trovare una libreria chiamata 'icuuc' e utilizzarlo". gcc poi cerca i percorsi LIB per i file con un determinato schema di denominazione che corrispondono "icuuc".
In questo caso libicuuc.so. Si noti che non cerca un nome di file specifico di versione, appena libicuuc.so. Una volta che ha trovato un file, non cercherà un altro uno. Le prime ricerche gcc nei suoi percorsi predefiniti. Poi cerca i percorsi di libreria aggiuntiva - nell'ordine in cui sono forniti per gcc. Cioè.

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

troveranno /usr/lib/libicuuc.so se esiste un tale file e non /usr/local/lib/libicuuc.so (più). Il che significa che sia il percorso predefinito o l'ordine delle direttive percorso della libreria possono essere la causa della vostra difficoltà.
Quando il programma è collegato agli oggetti condivisi di un caricatore "speciale" viene aggiunto al codice e il nome dell'oggetto condiviso è memorizzato nel programma (in fase di collegamento).
Ogni volta che si esegue il programma, in primo luogo i (runtime) ricerche caricatore per l'oggetto condiviso (con il suo nome), carica il codice e sostituisce alcuni indirizzi stub di salto.
L'oggetto condiviso può "raccontare" il linker (cioè in fase di link) il nome dell'oggetto condiviso il caricatore dovrebbe cercare (proprietà Soname) in fase di esecuzione. Date un'occhiata alla directory annuncio ha fornito nel testo domanda

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, questo è il file gcc è alla ricerca di quando -licuuc è fornito. Il linker segue il link simbolico e usa libicuuc.so.42.0.1. Questo file "racconta" il linker che il (runtime) loader deve cercare libicuuc.so.42, vedi http://userguide.icu-project.org/packaging#TOC-ICU-Versions .
Il caricatore seguirà il link simbolico e carico libicuuc.so.42.0.1, o se v'è un altro libicuuc.so bugfix.42.0.2, libicuuc.so.42.0.3, qualunque sia libicuuc.so.42 sta puntando. libicuuc.so.42 sarà / deve sempre puntare a un oggetto condiviso effettivo che esporta ICU 4.2 simboli. Il codice può essere cambiato / fisso, ma i simboli esportati rimanere lo stesso. Il tuo problema ora è che gcc non trova libicuuc.so-> libicuuc.so.42.0.1 ma (diciamo) libicuuc.so-> libicuuc.so.34.x.y. Questo libicuuc.so.34.x.y non esporta l'ICU 4.2 simboli, non fornisce ubrk_close_4_2 ma ubrk_close_3_4. Quindi, non ubrk_close_4_2 -.> Errore di riferimento non risolto

Per prima "soluzione" (grezzo): Facciamo ./configure fare la sua magia e poi ... basta modificare il Makefile
. Aprire il Makefile (in alto fonte directory) in un editor di testo, cercare INTL_SHARED_LIBADD = e sostituire

-licui18n -licuuc -licudata -licuio

in quella linea da

/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

(lasciare alcun -lm -pthread ... come sono). Compilare nuovamente.
Questa "racconta" il gcc / linker non per cercare i file .so ma di utilizzare quelli specifici. Il risultato dovrebbe essere lo stesso come se il vostro percorso di libreria funzionava (Allucinante Soname).
Ma ogni volta che si esegue ./configure si deve applicare il "fix" di nuovo.

Seconda soluzione: Rimuovere gli altri link simbolici libicuXY.so (che è dove la parola "backup" viene in mente), mantenere solo le libicuXY.so-> libicuXY.so.42.0.1 link. Se non ci sono altre libicuuc.so - >> libicuuc.so.34.x.y collega il gcc / linker non riesce a trovare loro e non collegherà contro le vecchie versioni
. Sempre a causa dei binari di proprietà Soname che sono già stati collegati contro la vecchia versione continuerà a funzionare, perché "loro" loader cercherà i file libicuXY.so.34 (tuttora esistenti).
Questo influenzerà tutte le successive esecuzioni del linker, vale a dire se si crea un altro progetto che utilizza il vecchio file include verrà eseguito nello stesso problema il contrario. I file header e gli oggetti condivisi (in fase di collegamento) devono corrispondere.

Altri suggerimenti

C'è una buona probabilità che ld non sa dove trovare queste librerie. Si dovrà o aggiornamento LD_LIBRARY_PATH (ogni volta), o hanno ldconfig apprendere la nuova libreria.

È possibile:

  • Installa in / usr / local / lib o / usr / lib
  • Aggiungi la sua posizione a /etc/ld.so.conf e ri-run / sbin / ldconfig

In questo momento, anche se ldconfig è stato eseguito con qualsiasi installato la libreria, ldconfig avrebbe alcuna idea della sua posizione perché / usr / local / ICU / lib non è nel suo campo di applicazione. Se la libreria è stato installato in / usr / local / lib / ICU, ldconfig saprebbe dove trovarlo, e non avrebbe dovuto specificare il percorso LD manualmente.

Mi raccomando solo a reinstallare la libreria in / usr / ldconfig local / lib e funzionante prima di modificare ld.so.conf, tuttavia modificando il file non è grande tabù se si desidera solo per farlo funzionare.

Quando si chiama

export LD_LIBRARY_PATH=/usr/local/icu/lib

allora si sovrascrive il percorso attualmente impostato. Quindi potrebbe essere che troverà in terapia intensiva, ma non troverà una qualsiasi delle altre librerie di cui ha bisogno. Prova a modificare:

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

Se questo non risolve il problema posso pensare a due cose da provare:

  1. è la Biblioteca nel posto giusto? Forse l'installazione spostato da qualche altra parte, come /usr/local/lib/icu invece?
  2. Fa il lavoro di terapia intensiva? Provate il bersaglio "make check" per terapia intensiva. Provare a compilare / corsa la suite di test incluso in terapia intensiva, o cercare di compilare ed eseguire un esempio di ICU banale. Questa presentazione (PPT) ha alcuni esempi banali.

Modifica

Credo di aver capito. Sembra che php-Intl funziona solo con libicu 3.6 o 3.8. Googled per sempre il trasporto distro Linux php-Intl e che tutto dipende da libicu 3.8, anche quando sono anche la spedizione libicu 4.0 o versione successiva. Il ultimo changelog prima Intl a far parte di php per sé indica lo stesso.

Suggerisco l'installazione libicu 3,8 e riprovare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top