2

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

是否有捷径可寻?我尝试更改 Makefile.PL 的 LIBS 指令中的链接选项,但 MakeMaker 忽略了我的选项。

4

2 回答 2

2

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

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

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

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

您可能想考虑使用rpathwith $ORIGIN

于 2013-01-15T03:08:05.130 回答
2

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

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

换句话说,如果你想去静态,你必须从头到尾——所有的东西,100% 必须是静态编译的,所以libc你的应用程序只使用一个副本。反之亦然——如果你是动态的,那么一切都应该是动态的,因为只使用一个libc. 仅当您的库不使用来自libc(甚至不sprintf)的任何内容时,这些规则才适用。

即使你在静态libpq编译中成功并且它会工作(不太可能),如果DBI没有安装怎么办?我已经看到足够多的 Linux 机器默认不存在 DBI。您是否也静态编译 DBI?如果Perl不存在(在 Linux 上不太可能),或者它很旧怎么办?

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

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

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

于 2013-01-15T05:07:55.913 回答