Проблема с установкой PHP 5.3.0 с международной поддержкой

StackOverflow https://stackoverflow.com/questions/1078412

  •  21-08-2019
  •  | 
  •  

Вопрос

В настоящее время я пытаюсь установить PHP 5.3.0 на какой-нибудь тестовый сервер Linux.Поскольку мы срочно ждали выхода 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

ОТДЕЛЕНИЕ интенсивной терапии 4.2 расположено по адресу /usr/local/icu и PHP 5.2.9 скомпилирован безупречно (без опций int- и icu-).Но когда я дополняю исходный код 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'

Редактировать:ответы на вопросы Волкерка вопросы

Я установил 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

ПРАВКА относительно комментария Фолькерка:

Нет, никакого переключения компилятора не было задействовано - я запустил оба процесса сборки напрямую один за другим. 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:

Я думаю, что есть загвоздка - в системе действительно есть другая версия отделения интенсивной терапии;по крайней мере, по частям (например, нет другого 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 не компилируется.

Как я могу избавиться от ссылки на старую icu-библиотеку в lib-path или как мне расставить приоритеты для нового icu-library-path?

Это было полезно?

Решение

Проблема, по-видимому, заключается в том, что двоичный файл связан с неправильными (общими) файлами библиотеки.
Сначала длинное, скучное объяснение того, в чем, по моему мнению, заключается проблема.Имейте в виду, что я не эксперт по Linux.Я действительно хочу, чтобы вы поняли ход моих мыслей, чтобы вы могли решить, осуществимо ли это и / или где я ошибаюсь.
Первое (сырое) решение легко обратимо.Запустите другой ./configure, и все изменения будут сохранены в истории.Я думаю, это довольно экономично.

Почему у вас в первую очередь есть специфические зависимости от отделения интенсивной терапии 4-2?Давайте взглянем на исходный файл php с расширением intl (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 ...--с помощью команды-icu-dir=/usr/local/icu" выполняется файл ext/intl/config.m4.В этом процессе вызывается icu-config, чтобы получить включаемый путь и файлы библиотеки, необходимые для сборки php.Вы указали путь к установке вашего отделения интенсивной терапии, который сводится к следующему

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 (по-видимому) не нашел unicode / ubrk.h в своем каталоге по умолчанию, поэтому он искал файл в дополнительных включенных каталогах, предоставляемых ICU_INCS, где он нашел включаемые файлы icu 4.2.unicode/ubrk.h включает в себя unicode/utypes.h, который затем включает unicode/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".
В данном случае libicuuc.so.Обратите внимание, что он не ищет имя файла, зависящее от версии, просто libicuuc.so.Как только он найдет такой файл, он не будет искать другой.Сначала gcc выполняет поиск по своим путям по умолчанию.Затем он выполняет поиск по дополнительным путям к библиотекам - в том порядке, в каком они предоставлены gcc.То есть.

gcc -L/usr/библиотека -L/usr/локальная/библиотека -licuuc

найдет /usr/lib/libicuuc.итак, если существует такой файл, а не /usr/local/lib/libicuuc.so (больше).Это означает, что причиной вашей проблемы может быть либо путь по умолчанию, либо порядок следования директив пути к библиотеке.
Когда ваша программа связана с общими объектами, в код добавляется "специальный" загрузчик, и имя общего объекта сохраняется в вашей программе (во время соединения).
Каждый раз, когда ваша программа выполняется, сначала загрузчик (во время выполнения) выполняет поиск общего объекта (по его имени), загружает код и заменяет некоторые адреса перехода-заглушки.
Общий объект может "сообщить" компоновщику (т.е.во время соединения) имя общего объекта, который загрузчик должен искать (свойство SONAME) во время выполнения.Взгляните на список каталогов, который вы указали в тексте вашего вопроса

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 , это файл, который ищет gcc, когда предоставляется -licuuc.Компоновщик следует символической ссылке и использует libicuuc.so.42.0.1.Этот файл "сообщает" компоновщику, что загрузчик (во время выполнения) должен искать libicuuc.so.42, см. http://userguide.icu-project.org/packaging#TOC-ICU-Versions.
Загрузчик перейдет по символической ссылке и загрузит libicuuc.so.42.0.1, или, если есть другое исправление libicuuc.so.42.0.2, libicuuc.so.42.0.3, на что указывает libicuuc.so.42.libicuuc.so.42 всегда будет / должен указывать на фактический общий объект, который экспортирует символы icu 4.2.Возможно, код был изменен / исправлен, но экспортированные символы остались прежними.Ваша проблема сейчас в том, что gcc не находит libicuuc.so -> libicuuc.so.42.0.1, но (допустим) libicuuc.so -> libicuuc.so.34.x.y.Этот libicuuc.so.34.x.y не экспортирует символы icu 4.2, он предоставляет не ubrk_close_4_2, а ubrk_close_3_4.Итак, нет ошибки ubrk_close_4_2 -> неразрешенная ссылка.

Первое "решение" (сырое):Позвольте ./configure творить свое волшебство , а затем ...просто отредактируйте Makefile.
Откройте Makefile (в верхнем каталоге исходного кода) в текстовом редакторе, найдите INTL_SHARED_LIBADD= и замените

-licui18n -licuuc -ликудата -ликуйо

в этой строке по

/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 / компоновщику не искать файлы .so, а использовать определенные из них.Результат должен быть таким же, как если бы ваш путь к библиотеке был рабочим (из-за SONAME).
Но каждый раз, когда вы запускаете ./configure, вам приходится снова применять "исправление".

Второе решение:Удалите другие libicuXY.итак, символические ссылки (вот где на ум приходит слово "резервное копирование"), сохраните только ссылки libicuXY.so ->libicuXY.so.42.0.1.Если нет других libicuuc.so ->> ссылки libicuuc.so.34.x.y, gcc / компоновщик не может их найти и не будет ссылаться на старые версии.
Опять же, из-за свойства SONAME двоичные файлы, которые уже были связаны со старой версией, все еще будут функционировать, потому что "их" загрузчик будет искать (все еще существующие) файлы libicuXY.so.34.
Это повлияет на все последующие запуски компоновщика, т.е.если вы создадите другой проект, который использует старые включаемые файлы, вы столкнетесь с той же проблемой наоборот.Файлы заголовков и общие объекты (во время соединения) должны совпадать.

Другие советы

Есть хороший шанс, что ld не знает, где найти эти библиотеки.Вам придется либо обновлять LD_LIBRARY_PATH (каждый раз), либо попросить ldconfig узнать о вашей новой библиотеке.

Вы можете либо:

  • Установите его в /usr/local/lib или /usr/lib
  • Добавьте его местоположение в /etc/ld.so.conf и повторно запустите /sbin/ldconfig

Прямо сейчас, даже если ldconfig был запущен тем, кто установил библиотеку, ldconfig не имел бы представления о ее местоположении, потому что /usr/local /icu /lib не входит в ее область видимости.Если бы библиотека была установлена в /usr/local/lib /icu, ldconfig знал бы, где ее найти, и вам не пришлось бы указывать путь к LD вручную.

Я рекомендую просто переустановить библиотеку в / usr/local /lib и запустить ldconfig перед изменением ld.so.conf, однако изменение этого файла не является большим запретом, если вы просто хотите заставить его работать.

Когда ты позвонишь

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. Эта презентация (PPT) имеет несколько тривиальных примеров.

Редактировать

Я думаю, что я понял это.Похоже, php-intl работает только с libicu 3.6 или 3.8.Я погуглил, что дистрибутив ever Linux поставляется с php-intl, и все они зависят от libicu 3.8, даже если они также поставляют libicu 4.0 или более позднюю версию.В последний список изменений перед тем, как intl стал частью самого php указывает на то же самое.

Я предлагаю установить libicu 3.8 и попробовать еще раз.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top