문제

현재 일부 Linux 테스트 서버에 PHP 5.3.0을 설치하려고합니다. Ext/Intl을 긴급히 기다렸으므로 제공하는 기능을 확인하려고합니다. 나는 뛰고있어 configure 다음 주장과 함께 성공적으로

./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가 있습니다 /usr/local/icu 및 PHP 5.2.9는 완벽하게 컴파일되었습니다 (int- 및 ICU-OPTIONS없이). 하지만 PHP 5.3.0 소스에 불만을 제기 할 때 나는 종류의 오류 메시지를 많이 얻습니다.

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'

나는 그것이 공유 라이브러리를 찾지 않는 것과 관련이 있다고 확신합니다. 환경

export LD_LIBRARY_PATH=/usr/local/icu/lib

도움이되지 않습니다.

누구든지 해결책을 가리킬 수 있습니까? 나는 오히려 단서가 없다 - 그리고 나는 이런 것들에 대한 진정한 전문가가 아닙니다 ...

편집하다:

방금 다시 확인하고 다양한 ICU 라이브러리와 각각의 소프트 링크가 모두 /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 수많은 테스트를 실행합니다 - 모두 성공적으로 :

[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'

편집 : Volkerk에 대한 답변 질문

소스에서 ICU 4.2를 설치했으며 빌드 프로세스 위에 글을 썼을 때 단위 테스트 및 설치가 모두 제대로 진행되었습니다.

/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

Volkerk의 의견에 관한 편집 :

아니요, 컴파일러의 스위치가 없었습니다. 저는 두 가지 빌드 프로세스를 직접 운영했습니다. objdump /usr/local/icu/lib/libicuuc.so.42.0.1 작동하지 않지만 실행했습니다

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

이 정보가 도움이 될 수 있는지 모르겠습니다.

Volkerk의 편집 edit1 및 edit2:

문지름이 있다고 생각합니다. 실제로 Sytem에 또 다른 ICU 버전이 있습니다. 적어도 부분적으로 (예를 들어 다른 ICU-Config는 없습니다. /usr/local/icu/bin).

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

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

동안 gcc -lpthread -lm -L/usr/local/icu/lib -licui18n -licuuc -licudata -lpthread -lm -licuio -print-file-name=libicuuc.so.42 보고

libicuuc.so.42

그래서 문제는 새로운 lib-path를 빌드 프로세스에 넣는 방법 인 것 같습니다. 그건 그렇고, 나는 당신의 대답에서 많은 것을 배웠습니다 - 여러분 모두에게 감사합니다.

또한 간단한 테스트 프로그램을 컴파일하려고했는데 동일하게 실패합니다. 정의되지 않은 참조 PHP가 컴파일하지 않는 것과 같은 이유로 인해 오류가 발생합니다.

lib-path의 오래된 ICU-library에 대한 참조를 어떻게 제거 할 수 있습니까?

도움이 되었습니까?

해결책

문제는 바이너리가 잘못된 (공유) 라이브러리 파일과 연결되어있는 것 같습니다.
먼저 문제가 생각하는 것에 대한 길고 지루한 설명. 나는 Linux 전문가가 아니라는 점을 명심하십시오. 나는 당신이 내 생각의 기차를 이해하기를 원합니다.
첫 번째 (원유) 솔루션은 쉽게 가역적입니다. 다른 ./configure를 실행하면 모든 변화는 역사입니다. 나는 그것이 꽤 저장된다고 생각합니다.

처음에 ICU 4-2 특정 종속성이있는 이유는 무엇입니까? PHP의 Intl Extension의 소스 파일 (ext/intl/Grapheme/Grapheme_string.c)을 살펴 보겠습니다.

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

지금까지 버전 특정 코드가 없습니다. Grapheme_string.c는 ICU 3.4 또는 ICU 4.2를 사용하든 동일하게 보입니다. UBRK_CLOSE_4_2는 어디에서 왔습니까?
"./configure ...-with-icu-dir =/usr/local/icu"를 실행하면 파일 ext/intl/config.m4가 실행됩니다. 이 과정에서 ICU-Config는 PHP를 구축하는 데 필요한 포함 경로 및 라이브러리 파일을 얻기 위해 호출됩니다. 당신은 당신의 ICU 설치 경로를 제공하여 그로 인한 것입니다.

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

실행됩니다. ICU-Config를 직접 시도해 보았으므로 출력이 무엇인지, 따라서 ICU_INCS 및 ICU_LIBS에 포함 된 내용을 알고 있습니다. 파일을 컴파일/링크 할 때 ICU_INCS 및 ICU_LIBS가 GCC로 전달됩니다. GCC (Apperely)는 기본 디렉토리에서 유니 코드/ubrk.h를 찾지 못하므로 ICU 4.2에 파일이 포함 된 ICU_INCS에서 제공하는 추가 포함 디렉토리에서 파일을 검색했습니다. 유니 코드/ubrk.h에는 유니 코드/utypes.h가 포함되어 있으며, 여기에는 유니 코드/urename.h를 포함하고 ICU 4.2 헤더 파일이 포함됩니다. 이 경우 Unicode/Urename.h에는 #define ubrk_close ubrk_close_4_2가 포함됩니다.
사전 처리기가 완료되면 ubrk_close (Bi)는 ubrk_close_4_2 (Bi)로 대체되었습니다.

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

이제 일부 라이브러리가 해결 해야하는 UBRK_CLOSE_4_2에 대한 버전 별 종속성이 있습니다.
포함 부분이 작동했습니다. 실제로 ICU 4.2 버전을 찾아 헤더 파일을 사용했습니다. 여태까지는 그런대로 잘됐다.
이제 링커 부분을 위해. 귀하의 경우 ICU_LIBS에는 포함됩니다

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

-licuuc는 GCC에게 " 'icuuc'라는 라이브러리를 찾아서 사용합니다. 그런 다음 GCC는 "ICUUC"와 일치하는 특정 명명 체계가있는 파일의 LIB 경로를 검색합니다.
이 경우 libicuuc.so. 버전 특정 파일 이름을 찾지 않고 libicuuc.so입니다. 그러한 파일을 찾으면 다른 파일을 찾지 못할 것입니다. 첫 번째 GCC는 기본 경로에서 검색합니다. 그런 다음 GCC에 제공되는 순서대로 추가 라이브러리 경로를 검색합니다. 즉

gcc -l/usr/lib -l/usr/local/lib -licuuc

/usr/lib/libicuuc.를 찾을 수 있습니다. 그러한 파일이 있고 /usr/local/lib/libicuuc.so가 아닌 경우 (더 이상). 기본 경로 또는 라이브러리 경로 지시문의 순서가 문제의 원인 일 수 있음을 의미합니다.
프로그램이 공유 객체와 연결되면 "특수"로더가 코드에 추가되고 공유 객체의 이름이 프로그램에 저장됩니다 (링크 시간).
프로그램이 실행될 때마다 먼저 (런타임) 로더가 공유 객체 (이름으로)를 검색하고 코드를로드하고 일부 스텁 점프 주소를 대체합니다.
공유 객체는 로더가 런타임에 찾아야하는 공유 객체의 이름을 링커 (예 : 링크 시간에) 할 수 있습니다. 질문 텍스트에 제공 한 디렉토리 목록을 살펴보십시오.

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, 이것이 -LICUUC가 제공 될 때 GCC를 찾고있는 파일입니다. 링커는 Symlink를 따르고 libicuuc.so.42.0.1을 사용합니다. 이 파일은 링커에 (런타임) 로더가 libicuuc.so.42를 찾아야한다는 것을 링커합니다. http://userguide.icu-project.org/packaging#toc-icu-versions.
로더는 Symlink 및 Load Libicuuc.so.42.0.1을 따라 가거나 Libicuuc.so.42가 지적 하든지 Libicuuc.so.42.0.3, Libicuuc.so.42.0.3이있는 다른 Bugfix libicuuc.so.42.0.3을 따릅니다. libicuuc.so.42는 ICU 4.2 기호를 내보내는 실제 공유 객체를 항상 가리 려야합니다. 코드가 변경/고정되었을 수 있지만 내보낸 기호는 동일하게 유지됩니다. 지금 당신의 문제는 GCC가 libicuuc.so-> libicuuc.so.42.0.1을 찾지 못한다는 것입니다. ICU 4.2 기호를 내보내면 UBRK_CLOSE_4_2를 제공하지 않지만 ubrk_close_3_4를 제공합니다. 따라서 ubrk_close_4_2-> 해결되지 않은 참조 오류가 없습니다.

첫 번째 "솔루션"(원유) : ./configure가 마술을하고 ... Makefile을 편집하자.
텍스트 편집기에서 makefile (소스 상단 디렉토리)을 열고 intl_shared_libadd =를 검색하고 교체하십시오.

-licui18n -licuuc -licudata -licuio

그 선에서

/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

(-LM -PTHREAD ... 그대로 두십시오). 다시 컴파일하십시오.
이것은 "GCC/Linker가 .SO 파일을 검색하지 않고 특정 파일을 사용하도록"알려줍니다 ". 결과는 라이브러리 경로가 작동하는 것과 동일해야합니다 (Soname의 Beacuse).
그러나 당신이 달릴 때마다 ./configure는 "수정"을 다시 적용해야합니다.

두 번째 해결책 : 다른 libicuxy.so symlinks ( "백업"이라는 단어가 떠오르는 곳)를 제거하고 libicuxy.so-> libicuxy.so.42.0.1 링크 만 유지하십시오. 다른 libicuuc.so- >> libicuuc.so.34.xy 링크가없는 경우 GCC/Linker는 찾을 수 없으며 이전 버전과 연결되지 않습니다.
""로더가 (여전히 존재하는) libicuxy.so.34 파일을 검색하기 때문에 이전 버전과 이미 연결된 Soname 속성 바이너리로 인해 여전히 작동합니다.
이렇게하면 모든 후속 링커 실행에 영향을 미칩니다. 즉, 구형 포함 된 파일을 사용하는 다른 프로젝트를 구축하는 경우 다른 방식으로 동일한 문제가 발생합니다. 헤더 파일과 공유 객체 (링크 시간에)가 일치해야합니다.

다른 팁

좋은 기회가 있습니다 ld 해당 라이브러리를 어디에서 찾을 수 있는지 모릅니다. ld_library_path (매번)를 업데이트하거나 LDConfig가 새 라이브러리를 배우게해야합니다.

당신은 둘 중 하나를 할 수 있습니다 :

  • /usr/local/lib 또는/usr/lib에 설치하십시오.
  • /etc/ld.so.conf에 위치를 추가하고 Re-Run /SBIN /LDConfig

LDConfig가 라이브러리를 설치 한 모든 것에 의해 LdConfig가 실행 되더라도 LDConfig는/usr/local/icu/lib가 그 범위에 있지 않기 때문에 그 위치를 알지 못할 것입니다. 라이브러리가/usr/local/lib/icu에 설치된 경우 LDConfig는이를 어디에서 찾을 수 있는지 알게되며 LD 경로를 수동으로 지정할 필요가 없습니다.

Ld.so.conf를 수정하기 전에/usr/local/lib로 라이브러리를 다시 설치하고 ldconfig를 실행하는 것이 좋습니다. 그러나 해당 파일을 수정하는 것은 그냥 작동하기를 원한다면 금기 사항이 아닙니다.

전화 할 때

export LD_LIBRARY_PATH=/usr/local/icu/lib

그런 다음 현재 설정된 경로를 덮어 쓰고 있습니다. 따라서 ICU를 찾을 수는 있지만 필요한 다른 라이브러리는 찾을 수 없습니다. 대신 시도해보십시오.

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

그것이 도움이되지 않으면 시도해 볼 두 가지를 생각할 수 있습니다.

  1. 도서관이 올바른 장소에 있습니까? 아마도 설치가 다른 곳으로 이동했을 것입니다 /usr/local/lib/icu 대신에?
  2. ICU가 작동합니까? ICU의 "확인"대상을 시도하십시오. ICU에 포함 된 테스트 스위트를 컴파일/실행하거나 사소한 ICU 예제를 컴파일하고 실행하십시오. 이 프레젠테이션 (PPT) 몇 가지 사소한 예가 있습니다.

편집하다

나는 그것을 알아 낸 것 같아요. PHP-Intl은 Libicu 3.6 또는 3.8에서만 작동하는 것처럼 보입니다. 나는 Ever Linux 배포 배송 PHP-Intl에 대해 Googled를 보았으며 Libicu 4.0 이상을 배송 할 때에도 Libicu 3.8에 달려 있습니다. 그만큼 INTL이 PHP 자체의 일부가되기 전 마지막 변경 사항 동일합니다.

Libicu 3.8을 설치하고 다시 시도하는 것이 좋습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top