Frage

Zur Zeit versuche ich PHP 5.3.0 auf einigen Linux-Testserver zu installieren. Wie wir dringend für ext / intl gewartet haben wollen wir die Eigenschaften überprüfen, die es bietet. Ich bin mit configure erfolgreich mit den folgenden Argumenten

./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 ist bei /usr/local/icu und in PHP 5.2.9 einwandfrei kompiliert (ohne die int- und ICU-Optionen). Aber wenn ich die PHP 5.3.0 Quelle complie ich eine ganze Menge von Fehlermeldungen der Art

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'

Ich bin mir ziemlich sicher, dass es etwas mit dem zu tun hat, nicht die gemeinsame Bibliotheken zu finden. Einstellen

export LD_LIBRARY_PATH=/usr/local/icu/lib

hilft nicht.

Kann jemand zeigen Sie mir einige Lösung? Ich bin ziemlich ratlos - und ich bin kein echter Experte in diesen Dingen ...

EDIT:

Ich habe gerade nochmals überprüft und sorgte dafür, dass die verschiedenen ICU-Bibliotheken und die entsprechenden Soft-Links all in /usr/local/icu/lib befinden:

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 laufen Tonnen Tests - alle von ihnen erfolgreich:

[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: Antworten auf VolkerK der Fragen

Ich installierte ICU 4.2 von Quelle und als ich über dem Build-Prozess geschrieben, die Einheit-Tests und die Installation aller gingen in Ordnung.

/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 über VolkerK Kommentar:

Nein, hat es beteiligt kein Schalter des Compilers - ich lief beiden Prozesse, die direkt hintereinander bauen. objdump /usr/local/icu/lib/libicuuc.so.42.0.1 funktioniert auch nicht, aber ich schaffte es zu laufen

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

Sie wissen nicht, ob diese Informationen helfen können.

EDIT auf VolkerK edit1 und edit2 :

Ich denke, es ist der Haken - es ist in der Tat eine andere ICU-Version auf dem Sytem; zumindest in den Teilen (es gibt keinen anderen ICU-config zum Beispiel, nur der ein in /usr/local/icu/bin).

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

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

während gcc -lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio -print-file-name=libicuuc.so.42 kehrt

libicuuc.so.42

So das Problem zu sein scheint, wie den neuen lib-Pfad in den Build-Prozess zu bekommen ?? By the way, habe ich viel gelernt aus Ihren Antworten - Danke an euch alle

.

Ich habe auch versucht, Ihr einfaches Testprogramm zu kompilieren - und es scheitert auch mit den gleichen undefined reference Fehlern, wahrscheinlich wegen des gleichen Grunde PHP wird nicht kompiliert.

Wie kann ich den Hinweis auf die alte ICU-Bibliothek in dem lib-Pfad loszuwerden oder wie priorisieren ich den neuen ICU-Bibliothek-Pfad?

War es hilfreich?

Lösung

Das Problem scheint zu sein, dass die binären gegen die falschen (gemeinsam) Bibliotheksdateien verknüpft ist.
Zunächst wird eine lange, langweilige explaination von dem, was ich denke, das Problem ist. Beachten Sie, dass ich kein Linux-Experte bin. Ich möchte Sie wirklich meine Gedankengänge verstehen, damit Sie entscheiden können, ob es machbar und / oder wo ich falsch liege.
Die erste (roh) Lösung ist leicht umkehrbar. Führen Sie eine weitere configure und alle Änderungen sind Geschichte. Ich denke, es ist ziemlich zu speichern.

Warum haben Sie 4-2 spezifische Abhängigkeiten in erster Linie ICU? Lassen Sie uns an einer Quelldatei von PHP intl Erweiterung einen Blick (ext / intl / Graphem / grapheme_string.c)

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

Bis jetzt gibt es keine Version spezifischer Code. grapheme_string.c sieht gleich, ob Sie icu 3.4 oder ICU 4.2 verwenden. Woher kommt der ubrk_close_4_2 kommen?
Wenn Sie das "configure ... --with-ICU-dir = / usr / local / ICU" run-Befehl die Datei ext / intl / config.m4 geführt wird. Bei diesem Verfahren wird ICU-config aufgerufen bauen php erforderlich die Include-Pfad und Bibliotheksdateien zu erhalten. Sie versehen einen Weg zu Ihrer ICU Installation, die auf das läuft darauf hinaus,

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

ausgeführt. Sie haben versucht, ICU-config selbst, so dass Sie wissen, was es gibt und deshalb was ICU_INCS und ICU_LIBS enthalten. ICU_INCS und ICU_LIBS werden weitergegeben gcc, wenn die Dateien / verknüpften zusammengestellt. gcc (apperently) nicht Unicode / ubrk.h finden in ihr Standardverzeichnis ist, so durchsucht er die Datei in der zusätzlichen Einfügeverzeichnisse von ICU_INCS vorgesehen, wo es die ICU 4.2 Include-Dateien gefunden. Unicode / ubrk.h enthält Unicode / utypes.h die dann Unicode / urename.h enthält - und wieder die ICU 4.2 Header-Dateien enthalten sind. In diesem Fall Unicode / urename.h umfasst #define ubrk_close ubrk_close_4_2.
Wenn der Vorprozessor erfolgt ubrk_close (bi) durch ubrk_close_4_2 (bi) ersetzt worden ist.

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

Jetzt haben Sie eine versionsspezifische Abhängigkeit, ein Verweis auf ubrk_close_4_2, dass einige Bibliothek zu lösen hat.
So sind der Teil der Arbeit getan. Es hat in der Tat Ihre ICU 4.2 Version und verwendet seine Header-Dateien. So weit so gut.
Jetzt für den Linker Teil. In Ihrem Fall ICU_LIBS enthält

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

-licuuc sagt gcc „finden Sie mir eine Bibliothek mit dem Namen‚icuuc‘und es verwenden“. gcc sucht dann die LIB-Pfade für Dateien mit einem bestimmten Namensschema, das „icuuc“ entsprechen.
In diesem Fall libicuuc.so. Beachten Sie, dass es nicht für einen versionsspezifische Dateinamen sieht, nur libicuuc.so. Sobald es eine solche Datei gefunden hat, wird es nicht für einen anderen suchen. Erste gcc sucht in seinen Standardpfaden. Dann durchsucht er die zusätzlichen Bibliothekspfade - in der Reihenfolge, wie sie auf gcc vorgesehen sind. D.

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

finden /usr/lib/libicuuc.so wenn es eine solche Datei ist und /usr/local/lib/libicuuc.so nicht (mehr). Was bedeutet, dass entweder der Standardpfad oder die Reihenfolge der Bibliothekspfad-Richtlinien kann die Ursache Ihrer Probleme sein.
Wenn Ihr Programm gegen gemeinsame Objekte verknüpfen ein „besonderen“ Lader zum Code hinzugefügt werden und der Name des gemeinsam genutzten Objekts wird in Ihrem Programm (zur Verknüpfungszeit) gespeichert.
Jedes Mal, wenn Ihr Programm ausgeführt wird, wird zuerst die (Runtime) loader sucht nach dem gemeinsamen Objekt (durch seinen Namen), lädt den Code und ersetzt einige Stummel Sprungadressen.
Das gemeinsame Objekt kann „sagen“, den Linker (das heißt zur Verknüpfungszeit) der Name des gemeinsamen Objekts des Lader für (SONAME Eigenschaft) zur Laufzeit aussehen sollte. Werfen Sie einen Blick auf die Verzeichnisliste Sie in Ihrer Frage Text versehen

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, das ist die Datei gcc sucht, wenn -licuuc vorgesehen ist. Der Linker folgt dem symbolischen Link und verwendet libicuuc.so.42.0.1. Diese Datei "erzählt" die Linker, der die (Runtime) loader für libicuuc.so.42 aussehen sollte, finden Sie unter http://userguide.icu-project.org/packaging#TOC-ICU-Versions .
Der Lader wird folgen dem SYMLlibicuuc.so.42.0.1 Tinte und Last, oder wenn es eine andere Bugfix libicuuc.so.42.0.2 ist, libicuuc.so.42.0.3, was libicuuc.so.42 zeigt auf. libicuuc.so.42 wird / sollte immer nach einem tatsächlichen gemeinsamen Objekt, das den ICU 4.2 Symbole exportiert. Der Code kann geändert / behoben haben, aber die exportierten Symbole bleiben gleich. Ihr Problem ist jetzt, dass gcc nicht findet libicuuc.so-> libicuuc.so.42.0.1 aber (sagen wir mal) libicuuc.so-> libicuuc.so.34.x.y. Diese libicuuc.so.34.x.y nicht exportiert die ICU 4.2 Symbole, es bietet keine ubrk_close_4_2 aber ubrk_close_3_4. Also, keine ubrk_close_4_2 -.> Ungelöste Referenzfehler

Erste „Lösung“ (roh): Lassen Sie configure seine Magie zu tun und dann ... nur das Makefile bearbeiten
. Öffnen Sie die Makefile (im Quell Top-Verzeichnis) in einem Texteditor, suchen Sie nach INTL_SHARED_LIBADD = und ersetzen

-licui18n -licuuc -licudata -licuio

in dieser Zeile von

/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

(lassen Sie jede -Im -pthread ... wie sie sind). Kompilieren Sie erneut.
Diese „erzählt“ die gcc / Linker nicht für die .so-Dateien zu suchen, sondern die spezifisch diejenigen zu verwenden. Das Ergebnis sollte das gleiche sein wie bei dem Bibliothekspfad arbeitet (beacuse SONAME).
Aber jedes Mal, wenn Sie configure müssen Sie gelten die „reparieren“ wieder.

Zweite Lösung: Entfernen Sie die anderen libicuXY.so Symlinks (das ist, wo das Wort „Backup“ in den Sinn kommt), halten nur die libicuXY.so-> libicuXY.so.42.0.1 Links. Wenn es keine andere libicuuc.so sind - >> libicuuc.so.34.x.y verbindet die gcc / Linker sie nicht finden kann und nicht verlinkt gegen die alten Versionen
. Wieder wegen des SONAME Eigenschaft Binärdateien, die bereits gegen die alte Version in Verbindung gebracht worden sind wird noch funktionieren, weil „ihre“ Lader für die (noch vorhandenen) libicuXY.so.34 Dateien suchen.
Dadurch werden alle nachfolgenden Linker läuft, das heißt beeinflussen, wenn Sie ein anderes Projekt erstellen, das die ältere Include-Dateien verwendet, um Ihnen die andere Art und Weise in das gleiche Problem herumlaufen wird. Die Header-Dateien und die gemeinsam genutzten Objekte (zur Verknüpfungszeit) müssen übereinstimmen.

Andere Tipps

Es gibt eine gute Chance, dass ld nicht weiß, wo diese Bibliotheken zu finden. Sie werden zu jedem Update LD_LIBRARY_PATH haben (jedes Mal), oder haben ldconfig Ihre neue Bibliothek lernen.

Sie können entweder:

  • Installieren Sie es in / usr / local / lib oder / usr / lib
  • Fügen Sie seinen Standort /etc/ld.so.conf und re-run / sbin / ldconfig

Gerade jetzt, auch wenn ldconfig von ausgeführt wurde wie auch immer die Bibliothek installiert, ldconfig würde keine Ahnung von seiner Lage, weil / usr / local / icu / lib nicht in ihrem Umfang ist. Wenn die Bibliothek in / usr / local / lib / ICU installiert wurde, ldconfig würde wissen, wo sie zu finden, und Sie müßten nicht manuell den LD-Pfad angeben.

Ich empfehle nur Neuinstallation der Bibliothek in / usr / local / lib und läuft ldconfig vor ld.so.conf jedoch zu ändern, dass die Datei ändern Tabu ist nicht toll, wenn Sie nur wollen es funktioniert.

Wenn Sie anrufen

export LD_LIBRARY_PATH=/usr/local/icu/lib

dann überschreiben Sie die aktuell eingestellte Pfad. So könnte es sein, dass es ICU finden wird, aber es wird keine der anderen Bibliotheken braucht es finden. Versuchen Sie stattdessen:

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

Wenn das nicht hilft ich zwei Dinge denken kann, um zu versuchen:

  1. Ist die Bibliothek an der richtigen Stelle? Vielleicht ist Ihre Installation in woanders bewegt, wie /usr/local/lib/icu statt?
  2. Ist ICU Arbeit? Versuchen Sie, die „make check“ Ziel für die ICU. Versuchen Sie Kompilieren / Laufen der Testsuite mit ICU enthalten, oder versucht, ein triviales ICU Beispiel zu kompilieren und auszuführen. Diese Präsentation (PPT) ein paar triviale Beispiele hat.

Bearbeiten

Ich glaube, ich es herausgefunden. Es sieht aus wie nur php-intl mit libicu 3.6 oder 3.8 funktioniert. Ich habe immer Linux-Distribution Versand php-intl gegoogelt und sie hängt alles von libicu 3.8, selbst wenn sie auch libicu 4.0 oder höher Versand werden. Die letzten Changelog vor intl wurde Teil von PHP selbst zeigt das gleiche.

Ich schlage vor, die Installation von libicu 3.8 und versucht es erneut.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top