LD_LIBRARY_PATH не действует для LibXML.so - PullRequest
0 голосов
/ 08 сентября 2018

XML::LibXML - библиотека Perl. LibXML.so является частью библиотеки. Я пытаюсь XML::LibXML использовать пользовательский libxml2. Но предоставление LD_LIBRARY_PATH не имеет никакого значения:

$ ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
    libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f66af5e9000)

$ LD_LIBRARY_PATH=/home/yuri/_/libxml2/.libs ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
    libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f2d26ae3000)

$ ldd /usr/lib/python3.7/site-packages/libxml2mod.so | grep libxml2
    libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f878cbc8000)

$ LD_LIBRARY_PATH=/home/yuri/_/libxml2/.libs ldd /usr/lib/python3.7/site-packages/libxml2mod.so | grep libxml2
    libxml2.so.2 => /home/yuri/_/libxml2/.libs/libxml2.so.2 (0x00007f6f8f5d8000)

Что я делаю не так? Есть ли способ справиться с этим? Цель состоит в том, чтобы заставить скрипт Perl использовать пользовательскую сборку libxml2 (для исследования какой-либо проблемы).

UPD

$ find /usr/lib -name libxml2.so.2
/usr/lib/libxml2.so.2
/usr/lib/vmware-installer/2.1.0/lib/lib/libxml2.so.2
/usr/lib/vmware-installer/2.1.0/lib/lib/libxml2.so.2/libxml2.so.2
/usr/lib/vmware-vmrc/5.5/lib/libxml2.so.2
/usr/lib/vmware-vmrc/5.5/lib/libxml2.so.2/libxml2.so.2

$ find /usr/local/lib -name libxml2.so.2

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

ТЛ; др

ExtUtils::MakeMaker пути жестких кодов разделяемых библиотек в двоичных файлах с помощью записи RPATH в разделе .dynamic. Но вы можете предварительно загрузить необходимую библиотеку,

$ LD_PRELOAD=path/to/custom/libxml2/.libs/libxml2.so.2 ldd ./blib/arch/auto/XML/LibXML/LibXML.so

или заставить загрузчик игнорировать RPATH запись,

$ LD_LIBRARY_PATH=path/to/custom/libxml2/.libs /usr/lib/ld-linux-x86-64.so.2 --inhibit-rpath /abs/path/to/LibXML.so /abs/path/to/perl ./1.pl

или преобразовать RPATH запись в RUNPATH один,

$ chrpath --convert blib/arch/auto/XML/LibXML/LibXML.so

или удалить RPATH запись,

$ chrpath --delete blib/arch/auto/XML/LibXML/LibXML.so

или укажите XMLPREFIX переменную,

$ perl Makefile.PL XMLPREFIX=path/to/custom/libxml2/build

Под капотом

ExtUtils::Liblist::ext() берет список библиотек, с которыми нужно связать, например, -lxml2 -lz -llzma -licui18n -licuuc -licudata -lm -ldl, и превращает их в четыре или пять переменных , которые пробраться в сгенерированный Makefile. Одним из них является LD_RUN_PATH. Он содержит все пути, где были найдены библиотеки.

$is_dyna - истина, если библиотека динамическая (не оканчивается на .a). $is_perl имеет значение true, если Perl не был встроенным с it , а %ld_run_path_seen не должен дублировать значения в LD_RUN_PATH.

Часть, которая вычисляет LD_RUN_PATH, которая генерирует часть Makefile с переменной и часть, которая передает его компоновщику .

Последствия

LD_RUN_PATH и, в свою очередь, запись RPATH в двоичном файле заставляет загрузчик искать библиотеки (во время выполнения) в каталогах, где они были найдены (во время компиляции).

-rpath = каталог Добавить каталог в путь поиска библиотеки времени выполнения. Используется при связывании исполняемого файла ELF с общими объектами. Все аргументы -rpath объединяются и передаются компоновщику среды выполнения, который использует их для поиска общих объектов во время выполнения. Опция -rpath также используется при поиске общих объектов, которые необходимы для общих объектов, явно включенных в ссылку; см. описание опции -rpath-link. Если -rpath не используется при связывании исполняемого файла ELF, будет использоваться содержимое переменной среды "LD_RUN_PATH", если оно определено.

https://jlk.fjfi.cvut.cz/arch/manpages/man/core/binutils/ld.1.en

Если зависимость общего объекта не содержит косую черту, то она ищется в следующем порядке:

o Использование каталогов, указанных в атрибуте динамического раздела DT_RPATH двоичного файла, если он присутствует, а атрибут DT_RUNPATH не существует. Использование DT_RPATH устарело.

o Использование переменной окружения LD_LIBRARY_PATH , если только исполняемый файл не запущен в режиме безопасного выполнения (см. Ниже), в этом случае эта переменная игнорируется.

https://jlk.fjfi.cvut.cz/arch/manpages/man/core/man-pages/ld.so.8.en

$ perl Makefile.PL
$ make

Результат,

$ readelf --dynamic ./blib/arch/auto/XML/LibXML/LibXML.so | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [/usr/lib]

$ objdump -x ./blib/arch/auto/XML/LibXML/LibXML.so | egrep RPATH
  RPATH                /usr/lib

$ LD_LIBRARY_PATH=path/to/custom/libxml2/.libs ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
    libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f6cfabb2000)

--dynamic - отображать содержимое раздела .dynamic, -x - отображать все заголовки.

Решение

Один из способов исправить это - предварительно загрузить необходимый экземпляр libxml2,

$ LD_PRELOAD=path/to/custom/libxml2/.libs/libxml2.so.2 ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
    path/to/custom/libxml2/build/lib/libxml2.so.2 (0x00007fe183aeb000)

Другой способ - Makefile.PL искать libxml2 в нужном месте (во время компиляции).

$ perl Makefile.PL XMLPREFIX=path/to/custom/libxml2/build
$ make

Результат,

$ readelf --dynamic ./blib/arch/auto/XML/LibXML/LibXML.so | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [path/to/custom/libxml2/build/lib:/usr/lib]

$ objdump -x ./blib/arch/auto/XML/LibXML/LibXML.so | egrep RPATH
  RPATH                path/to/custom/libxml2/build/lib:/usr/lib

$ ldd ./blib/arch/auto/XML/LibXML/LibXML.so | grep libxml2
    libxml2.so.2 => path/to/custom/libxml2/build/lib/libxml2.so.2 (0x00007fe183aeb000)

На заметке

Если вы хотите отладить XML::LibXML, вы можете запустить make с переменной OPTIMIZE (добавьте -B, чтобы make перестраивал все, если библиотека уже была собрана),

$ make OPTIMIZE='-g3 -O0'

Есть также -O2, и нет -g в LDDLFLAGS, но не уверен, что это имеет большое значение.

В качестве альтернативы, WriteMakeFile принимает параметр OPTIMIZE, поэтому вы можете добавить строку здесь ,

'OPTIMIZE' => '-g3 -O0'

Или вы можете добавить переменную здесь и передать ее Makefile.PL,

$ perl Makefile.PL OPTIMIZE='-g3 -O0'
0 голосов
/ 08 сентября 2018

Если вы устанавливаете свою собственную версию libxml в /usr/local/lib, я думаю, что модуль XML :: LibXML должен загружать пользовательскую версию, а не ту, что в /usr/lib (при условии, что у вас есть права доступа sudoers или root для ее установки) .

Я не уверен, почему Python использует путь поиска для библиотек, отличный от Perl. Может быть, полный путь к библиотеке libxml жестко запрограммирован в XML :: LibXML libXML.so? Если бы модуль XML :: LibXML был связан с -l / usr / lib / libxml2.so вместо -lxml2, это было бы проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...