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

时间:2013-01-15 03:04:06

标签: perl postgresql static-linking dbd makemaker

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

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

2 个答案:

答案 0 :(得分:2)

IMO你错误地指明了你的要求。

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

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

请注意,无论是静态链接还是动态链接,如果某个其他模块将libpq加载到同一个Perl中,您将获得两个不兼容的libpq链接到同一个可执行文件(繁荣)或其中一个模块使用libpq而不是它编译的模块(也是繁荣)。如果您使用rpath链接,libpq对链接范围的了解可能会让您逃脱,但设置ld.so几乎肯定会导致问题。

您可能希望将LD_LIBRARY_PATHrpath一起使用。

答案 1 :(得分:2)

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

libpq本身可能依赖于libcglibc)。如果您静态链接它,但动态地链接其他模块,则意味着您将拥有2个libc副本:一个在libpq内,另一个由Perl本身引用并动态加载。这是非常危险的情况,特别是如果某些过程使用malloc分配内存并将指针传递回调用者。如果malloc从libc的一个副本分配内存,但free由另一个副本分配,则程序(和Per​​l)肯定会崩溃。

换句话说,如果你想要静态,你必须全力以赴 - 一切,100%必须静态编译,所以只有一份libc被你使用应用。反之亦然 - 如果你是动态的,一切都应该是动态的,因为只使用libc的一个副本。仅当您的图书馆未使用libc中的任何内容(甚至不是sprintf)时,这些规则才适用。

即使您成功进行静态libpq编译并且它可以正常工作(不太可能),如果未安装DBI该怎么办?我见过足够的Linux盒子,默认情况下不存在DBI。你是否静态编译DBI?如果Perl不存在(在Linux上不太可能),或者它已经很老了,该怎么办?

正确的解决方案是使用本机OS包管理器安装它:

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

如果您在相关主机上没有root,也许您应该考虑使用perlbrew - 在主目录中安装您自己的Perl。有了这个,您应该能够编译自己的libpq副本,并将其与perlbrew提供的Perl动态链接。