我正在尝试通过 Makefile.PL 在 linux 主机上构建 DBD::Pg;我的要求是,我必须能够动态链接到 perl,但静态链接到 libpq.so(因为它可能并非在所有盒子上都可用)。
是否有捷径可寻?我尝试更改 Makefile.PL 的 LIBS 指令中的链接选项,但 MakeMaker 忽略了我的选项。
我正在尝试通过 Makefile.PL 在 linux 主机上构建 DBD::Pg;我的要求是,我必须能够动态链接到 perl,但静态链接到 libpq.so(因为它可能并非在所有盒子上都可用)。
是否有捷径可寻?我尝试更改 Makefile.PL 的 LIBS 指令中的链接选项,但 MakeMaker 忽略了我的选项。
IMO 您错误地指定了您的要求。
您不需要静态链接,libpq
因为它可能并非在所有系统上都可用。
您通常应该做的是动态链接到libq
并LD_LIBRARY_PATH
在包装脚本中设置或使用rpath
链接以便libpq
可以找到。
请注意,无论是静态链接还是动态链接,如果某个其他模块将 a 加载libpq
到同一个 Perl 中,您要么将两个不兼容libpq
的 s 链接到同一个可执行文件(boom)中,要么其中一个模块使用libpq
与它编译的模块不同的模块反对(也繁荣)。如果您使用 rpath 链接,ld.so
对链接范围的认识可能会让您侥幸逃脱,但设置LD_LIBRARY_PATH
几乎肯定会导致问题。
您可能想考虑使用rpath
with $ORIGIN
。
不幸的是,尝试进行静态链接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
。