Статически связывать DBD::Pg (против libpq.so), но динамически против Perl?

Я пытаюсь собрать DBD::Pg на Linux-хосте через Makefile.PL; мои требования таковы, что я должен иметь возможность динамически ссылаться на perl, но статически ссылаться на libpq.so (так как он может быть доступен не во всех блоках).

Есть простой способ сделать это? Я попытался изменить параметры ссылки в директиве LIBS файла Makefile.PL, но MakeMaker игнорирует мои параметры.

2 ответа

Решение

ИМО, вы неправильно указали свои требования.

Вам не нужно статически ссылаться на libpq только потому, что он может быть недоступен во всех системах.

То, что вы должны делать вместо этого, это динамически связываться сlibq и либо установить LD_LIBRARY_PATH в сценарии оболочки или использовать rpath связывая так, чтобы libpq может быть найден.

Имейте в виду, что статическое или динамическое связывание, если какой-то другой модуль загружает libpq в тот же Perl вы либо получите два несовместимых libpqs связаны в один и тот же исполняемый файл (boom) или один из модулей, используя libpq кроме того, с которым он был скомпилирован (также бум). Если вы используете ссылки rpath, ld.soОсознание областей действия ссылок может позволить вам сойти с рук, но настройка LD_LIBRARY_PATH почти наверняка вызовет проблемы.

Возможно, вы захотите изучить использование rpath с $ORIGIN,

К сожалению, пытается сделать статическое связывание libpq вряд ли решит вашу проблему в целом.

libpq само по себе может зависеть от libc (glibc). Если вы связываете это статически, но другие модули динамически, это означает, что у вас будет 2 копии libc: один внутри libpqна другой ссылается сам Perl и загружается динамически. Это очень опасная ситуация, особенно если какая-то процедура выделяет память, используя malloc и передает указатель обратно вызывающей стороне. Если у вас есть память, выделенная malloc из одной копии libc, но freeпод влиянием другой копии ваша программа (и Perl) обязательно потерпит крах.

Другими словами, если вы хотите работать статично, вы должны пройти весь путь - все, 100% должны быть скомпилированы статически, поэтому только одна копия libc используется вашим приложением. И наоборот: если вы динамичны, все должно быть динамично, чтобы когда-либо использовать только одну копию libc, Эти правила не применяются, только если ваши библиотеки не используют ничего из libc (даже не sprintf).

Даже если вам удастся в статическом libpq компиляция и она будет работать (не очень вероятно), что если DBI не установлен? Я видел достаточно коробок Linux, где DBI по умолчанию нет. Вы также статически компилируете DBI? Что, если Perl нет (так как вряд ли это на линуксе), или если он очень старый?

Правильное решение - установить его с помощью собственного менеджера пакетов ОС:

sudo apt-get install libdbd-pg-perl   # Ubuntu/Debian
sudo yum install perl-DBD-Pg          # Redhat/Fedora

Если у вас нет root на рассматриваемых хостах, возможно, вам стоит подумать об использовании perlbrew установить свой собственный Perl в домашнем каталоге. Благодаря этому вы сможете собрать свою собственную копию libpq и связать его с Perl, предоставленным perlbrew динамически.

Другие вопросы по тегам