Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Unix-системы Новый топик    Ответить
 (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
Никогда подобным не занимался с таким "размахом", а вот пришлось...
Если не в тот подфорум написал, прошу модератора перенести куда надо.

Имеется сервер под FreeBSD 12.0, где штатно из портов установлен php 7.2.
Потребовалось дополнительно установить пару более ранних версий, начал с php 5.6.
Скомпилировал ее по самой минималке с --prefix=/usr/local/php56c - работает. Добавляю необходимые опции, дошел до -with-openssl и -with-curl и встрял по полной...

Проблема в том, что php 5.6 не компилируется с openssl версии 1.1.1 (различаются структуры), которая поставляется с фряхой "из коробки". Где-то, кажись в багтрекере php, нашел рекомендацию использовать более старую версию openssl.
Ладно, ставлю дополнительно openssl версии 1.0.2 и так же дополнительно curl с тем же --prefix (curl так же использует библиотеку libssl.so)

Для начала проверяю curl - работает, библиотеки грузятся как надо:
$ ldd -v /usr/local/php56c/bin/curl 
/usr/local/php56c/bin/curl:
        libcurl.so.4 => /usr/local/php56c/lib/libcurl.so.4 (0x800271000)
        libidn2.so.0 => /usr/local/lib/libidn2.so.0 (0x8002d7000)
        libssl.so.1.0.0 => /usr/local/php56c/lib/libssl.so.1.0.0 (0x8002f9000)
        libcrypto.so.1.0.0 => /usr/local/php56c/lib/libcrypto.so.1.0.0 (0x80036d000)
        libz.so.6 => /lib/libz.so.6 (0x8005c1000)
        libthr.so.3 => /lib/libthr.so.3 (0x8005db000)
        libc.so.7 => /lib/libc.so.7 (0x800606000)
        libunistring.so.2 => /usr/local/lib/libunistring.so.2 (0x8009f9000)


Ладно, едем дальше, конфигурирую php вот таким образом
LDFLAGS="-Wl,-R/usr/local/php56c/lib -L/usr/local/php56c/lib" ./configure  \
.....
--with-curl=/usr/local/php56c \
--with-openssl=/usr/local/php56c \
--prefix=/usr/local/php56c \
....


Если я правильно понял, тут LDFLAGS должна задать приоритетные пути поиска библиотек.

Компиляция успешно, проходит, но при запуске php валится в кору. Разбор показал такие моменты:
libcurl.so грузится из системной директории, а libssl.so грузится дважды - первый раз из php правильно, а второй раз из неправильной libcurl.so
$ ldd -a /usr/local/php56c/bin/php
/usr/local/php56c/bin/php:
...
        libssl.so.1.0.0 => /usr/local/php56c/lib/libssl.so.1.0.0 (0x800d4d000)
...
        libcurl.so.4 => /usr/local/lib/libcurl.so.4 (0x8016d0000)
...
/usr/local/lib/libcurl.so.4:
...
        libssl.so.111 => /usr/lib/libssl.so.111 (0x801e30000)
...


Посмотрел в truss - там даже нет попытки поискать libcurl.so в /usr/local/php56c/lib, а подгружается она сразу из /usr/local/lib
close(3)                                         = 0 (0x0)
openat(AT_FDCWD,"/usr/local/lib/libcurl.so.4",O_RDONLY|O_CLOEXEC|O_VERIFY,00) = 3 (0x3)
fstat(3,{ mode=-rwxr-xr-x ,inode=883905,size=562960,blksize=32768 }) = 0 (0x0)
mmap(0x0,4096,PROT_READ,MAP_PRIVATE|MAP_PREFAULT_READ,3,0x0) = 34371100672 (0x800ad6000)


Заглянул в Makefile - там в переменных окружения *_LDFLAGS* оба пути упоминаются, притом, первым всегда идет системный /usr/local/lib, а потом уже мой /usr/local/php56c/lib. Пробовал там тупым редактированием поменять пути местами, но результата оно не дало.

Воооот... Теперь я понимаю, что надо как-то более убедительно уговаривать линковщик. но не понимаю, как именно. Советы, в основном, сводятся к LDFLAGS.

Собственно, вопрос. Как уговорить то?

Тем более, что для libssl.so оно сработало, хотя... там же разная версия библиотеки...
29 май 19, 12:15    [21896568]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
fandr
Member

Откуда: ->Msk->SPb->Msk
Сообщений: 740
vkle,

а что в переменной LD_LIBRARY_PATH?
29 май 19, 12:39    [21896608]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
fandr,

Установки каких-то явных значений для LD_LIBRARY_PATH не нашел. Каким образом и где посмотреть ее можно?
29 май 19, 13:39    [21896693]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
fandr
Member

Откуда: ->Msk->SPb->Msk
Сообщений: 740
# echo $LD_LIBRARY_PATH


     The shared	libraries which	are found will be automatically	available for
loading if needed by the program being prepared for execution. This
obviates the need for storing search paths within the executable.

The LD_LIBRARY_PATH environment variable can be used to override the use
of directories (or the order thereof) from the cache or to specify addi-
tional directories where shared libraries might be found.
LD_LIBRARY_PATH is a `:' separated list of directory paths which are
searched by the dynamic linker when it needs to load a shared library.
It can be viewed as the run-time equivalent of the -L switch of ld(1).


PS: с FreeBSD не работаю, если что 8)
29 май 19, 15:25    [21896813]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
Изначально LD_LIBRARY_PATH пустая.
Если перед запуском программы (которая в кору падала) установить свою директорию
$ export LD_LIBRARY_PATH=/usr/local/php56c/lib ; ldd -a /usr/local/php56c/bin/php
, тогда загрузка библиотеки правильно происходит.

Это вариант... с большим натягом на самый крайний случай, когда ну ни под каким соусом не получится нормально скомпилировать php.

Меня же интересует в бОльшей мере способ сказать линковщику, чтобы он правильный путь загрузки библиотеки в бинарнике сделал сразу, при сборке.
29 май 19, 15:41    [21896868]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
fandr
Member

Откуда: ->Msk->SPb->Msk
Сообщений: 740
переменные окружения для того и предназначены, что бы при их помощи все работало без перекомпиляции
как-то странно стремиться к обратному

кстати, правильно делать так:

# export LD_LIBRARY_PATH=/usr/local/php56c/lib:$LD_LIBRARY_PATH
29 май 19, 16:26    [21896991]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
Вы хотите сказать, что компилятору виднее, как собирать программу, а с остальным нехай пользователи трахтибидохаются, устанавливая переменные окружения перед запуском после успешного выпадания в кору? ;-)
Корявенько как-то выходит... Хотя, как вариант, можно и обертку для php сделать, чтобы ручками не ставить LD_LIBRARY_PATH при запуске.

Видимо, действительно, опция конфигурирования
$ ./configure --help | grep curl
  --with-curl=DIR         Include cURL support
вместе с толкованием
https://www.php.net/manual/ru/curl.installation.php
Для использования cURL необходимо собрать PHP с опцией --with-curl[=DIR] , где DIR - имя каталога, содержащего подкаталоги lib и include. Каталог include должен содержать подкаталог curl с файлами easy.h и curl.h. В каталоге lib должен быть файл libcurl.a.
не имеет никакого отношения к путям загрузки курловой библиотеки. По крайней мере, libcurl.so там не требуется.
29 май 19, 16:59    [21897066]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
Залез (немытыми руками, конечно) в Makefile.

Было:

BUILD_CGI = $(LIBTOOL) --mode=link $(CC) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_CGI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_CGI_PATH)

Стало:

BUILD_CGI = $(LIBTOOL) --mode=link $(CC) -export-dynamic $(CFLAGS_CLEAN) -L/usr/local/php56c/lib -R /usr/local/php56c/lib $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_CGI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_CGI_PATH)

Аналогично и для BUILD_CLI и BUILD_FPM поправил.
По крайней мере, так без бубна ldd кажет правильный путь загрузки и php в кору не падает.

Понимаю, что так оно работает...
А если по хорошему делать - то править configure следует или... как это более правильно делается?
Ну, на случай, если в будущем придется с какими-то другими опциями пересобрать.
30 май 19, 02:52    [21897346]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
bga83
Member

Откуда: Город герой Ленинград
Сообщений: 30700
vkle
Имеется сервер под FreeBSD 12.0, где штатно из портов установлен php 7.2.
Потребовалось дополнительно установить пару более ранних версий, начал с php 5.6.
Скомпилировал ее по
а впакетах нужной версии нет, чтобы не мучаться с ручной сборкой?
30 май 19, 09:30    [21897466]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
bga83
а впакетах нужной версии нет, чтобы не мучаться с ручной сборкой?
В пакетах не глядел. Из портов выкинули 5.6 не так давно. И там ещё где-то в шатных мейкфайлах особенность есть, что можно поставить одну из трех доступных версий PHP, а две конфликтуют, так как файлы на одни и те же пути ставятся под одними именами. Пакеты обычно мало чем отличаются, ну, только что минорная версия постарее будет.
30 май 19, 10:40    [21897513]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
bga83
Member

Откуда: Город герой Ленинград
Сообщений: 30700
vkle
bga83
а впакетах нужной версии нет, чтобы не мучаться с ручной сборкой?
В пакетах не глядел. Из портов выкинули 5.6 не так давно. И там ещё где-то в шатных мейкфайлах особенность есть, что можно поставить одну из трех доступных версий PHP, а две конфликтуют, так как файлы на одни и те же пути ставятся под одними именами. Пакеты обычно мало чем отличаются, ну, только что минорная версия постарее будет.

еще есть вариант с модулями наподобие https://lmod.readthedocs.io/en/latest/ но я не уверен наличия подобного решения под FreeBSD, в линуксах точно работает. С фряхой давно уже дела не имел

с lmod или аналогами хоть десяток версий одного и того же софта ставить можно. идея заключается в том что они раскладывают по разным папкам и при необходимости работать с определенной версией софтины автоматом проставляются все переменные окружения
30 май 19, 11:02    [21897530]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
bga83
еще есть вариант с модулями наподобие https://lmod.readthedocs.io/en/latest/ но я не уверен наличия подобного решения под FreeBSD
Занятная штука, но нету. Докер, насколько помню, пока в состоянии экспериментов, да и требования к типу ФС предъявляет.
Потому по совокупности было выбрано решение собрать нужные вручную из исходников. Оно не вполне просто, конечно.
30 май 19, 11:37    [21897564]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
Scott Tiger
Member

Откуда: вмваре
Сообщений: 6797
vkle
Вы хотите сказать, что компилятору виднее, как собирать программу, а с остальным нехай пользователи трахтибидохаются, устанавливая переменные окружения перед запуском после успешного выпадания в кору? ;-)


В целом - да, хотя это не компилятор, а компоновщик (линкер) задействован. Вы же собираете своё похапе и его зависимости с динамической компоновкой и без указания rpath, поэтому при запуске динамический компоновщик подгрузит библиотеку исходя из своих умолчаний, определяемых, в том числе, и переменными окружения.
Вариантов несколько:

1. Оставить как есть будет самый правильный вариант. Пользователь программы обязан знать, какие библиотеки программе нужны, где их можно взять и уметь прочитать man rtld
2. Задать rpath при сборке (опции gcc -Wl,-rpath,../path/to/libs) - потом надо не забыть, где должны быть нужные библиотеки
3. Собрать статически.
30 май 19, 12:29    [21897610]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
vkle
Member

Откуда: Самара
Сообщений: 14701
Scott Tiger
2. Задать rpath при сборке (опции gcc -Wl,-rpath,../path/to/libs) - потом надо не забыть, где должны быть нужные библиотеки
Вот на этом то варианте и вышел затык. Собственно, в стартовом посте о нем и написал.

Scott Tiger
3. Собрать статически.
Это как-то можно задать в опциях/переменных при выполнении ./configure или как?
30 май 19, 13:13    [21897646]     Ответить | Цитировать Сообщить модератору
 Re: (FreeBSD) Как подгружать библиотеку с нужного пути?  [new]
Scott Tiger
Member

Откуда: вмваре
Сообщений: 6797
https://stackoverflow.com/questions/24173906/compile-php-into-static-binary
30 май 19, 16:37    [21897848]     Ответить | Цитировать Сообщить модератору
Все форумы / Unix-системы Ответить