Статически связывать 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 вы либо получите два несовместимых libpq
s связаны в один и тот же исполняемый файл (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
динамически.