我正在尝试通过Makefile.PL在linux主机上构建DBD :: Pg;我的要求是这样的,我必须能够动态链接perl,但静态链接libpq.so(因为它可能不是所有的盒子都可用)。
有一种简单的方法吗?我已经尝试更改Makefile.PL的LIBS指令中的链接选项,但MakeMaker忽略了我的选项。
答案 0 :(得分:2)
IMO你错误地指明了你的要求。
您不需要静态链接到libpq
,因为它可能并非在所有系统上都可用。
您通常应该做的是动态链接到libq
并在包装脚本中设置LD_LIBRARY_PATH
或使用rpath
链接以便{{1可以找到。
请注意,无论是静态链接还是动态链接,如果某个其他模块将libpq
加载到同一个Perl中,您将获得两个不兼容的libpq
链接到同一个可执行文件(繁荣)或其中一个模块使用libpq
而不是它编译的模块(也是繁荣)。如果您使用rpath链接,libpq
对链接范围的了解可能会让您逃脱,但设置ld.so
几乎肯定会导致问题。
您可能希望将LD_LIBRARY_PATH
与rpath
一起使用。
答案 1 :(得分:2)
不幸的是,尝试进行libpq
的静态链接不太可能解决您的问题。
libpq
本身可能依赖于libc
(glibc
)。如果您静态链接它,但动态地链接其他模块,则意味着您将拥有2个libc
副本:一个在libpq
内,另一个由Perl本身引用并动态加载。这是非常危险的情况,特别是如果某些过程使用malloc
分配内存并将指针传递回调用者。如果malloc从libc
的一个副本分配内存,但free
由另一个副本分配,则程序(和Perl)肯定会崩溃。
换句话说,如果你想要静态,你必须全力以赴 - 一切,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动态链接。