静态链接DBD::Pg(针对libpq.so),但动态链接Perl



我正试图通过Makefile.PL在linux主机上构建DBD::Pg;我的要求是,我必须能够动态地链接perl,但静态地链接libpq.so(因为它可能不适用于所有的盒子(。

有简单的方法吗?我尝试更改Makefile.PL的LIBS指令中的链接选项,但MakeMaker忽略了我的选项。

IMO您错误地指定了您的要求。

您不需要静态链接到libpq,因为它可能在所有系统上都不可用。

您通常应该做的是动态链接到libq,并在包装脚本中设置LD_LIBRARY_PATH或使用rpath链接,以便可以找到libpq

请注意,无论是静态链接还是动态链接,如果其他模块将libpq加载到同一Perl中,您要么会将两个不兼容的libpq链接到同一可执行文件中(boom(,要么会将其中一个模块使用与其编译对象不同的libpq(也是boom(。如果您使用rpath链接,ld.so对链接作用域的感知可能会让您逃脱惩罚,但设置LD_LIBRARY_PATH几乎肯定会引起问题。

您可能需要研究将rpath$ORIGIN一起使用。

不幸的是,尝试对libpq进行静态链接不太可能解决您的问题。

libpq本身可能依赖于libc(glibc(。如果您静态地链接它,但动态地链接其他模块,这意味着您将拥有libc的两个副本:一个在libpq中,另一个由Perl本身引用并动态加载。这是非常危险的情况,尤其是当某个过程使用malloc分配内存并将指针传递回调用方时。如果您的内存是由malloc从libc的一个副本分配的,但free被另一个副本占用,那么您的程序(和Perl(肯定会崩溃。

换言之,如果您想进行静态编译,则必须执行所有操作-所有操作都必须100%静态编译,因此应用程序只能使用libc的一个副本。反之亦然——如果你是动态的,那么一切都应该是动态的——就像只使用libc的一个副本一样。只有当您的库没有使用libc中的任何内容(甚至没有sprintf(时,这些规则才适用。

即使您成功地进行了静态libpq编译,并且它会工作(不太可能(,如果没有安装DBI呢?我已经看到了足够多默认情况下不存在DBI的Linux盒子。那么你也静态编译DBI吗?如果Perl不存在(在Linux上不太可能(,或者它很旧,该怎么办?

正确的解决方案是使用本机操作系统包管理器安装:

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

如果您在有问题的主机上没有root,也许您应该考虑使用perlbrew——在主目录中安装您自己的Perl。这样,您就可以编译自己的libpq副本,并将其与perlbrew提供的Perl动态链接。

相关内容

  • 没有找到相关文章

最新更新