设置autotools静态链接单个系统库

时间:2017-06-12 16:26:14

标签: gcc autotools

我有一个项目,我希望静态链接其中一个系统库。该项目使用GNU构建系统。

在configure.ac中我有:

AC_CHECK_LIB(foobar, foobar_init)

在开发机器上,此库安装在/ usr / lib / x86_64-linux-gnu中。它被检测到,但它是动态链接的,这会导致问题,因为它在某些机器上不存在。静态链接(-Wl,-Bstatic等)工作正常,但我不知道如何在autotools中设置它。我尝试将此强制转换为项目的Makefile.am链接标志,但它仍然优先考虑动态库。 我也尝试过使用带有./configure的--enable-static,但它似乎对系统库没有影响。

1 个答案:

答案 0 :(得分:3)

如果要静态链接整个程序,则应将--disable-shared选项传递给configure。您可能也可能不需要传递--enable-static,具体取决于该选项的默认值(您可以通过configure.ac文件影响该值)。你真的应该考虑这样做。

您还应该考虑将此问题作为安装程序的问题,而不是构建系统。安装人员有责任确保程序所需的所有共享库都由安装它的系统提供。这非常常见;事实上,它是包{}} / yumdnf等包裹管理系统的灵感之一,以及它们的底层包装格式。

如果你坚持只静态链接一个库,在动态链接其他所有内容的时候,那么你需要跳过几个箍。目标是发出链接选项,只导致该库静态链接,而不更改其他库的链接。使用GNU工具链,并假设程序以其他方式动态链接,这将是这些选项的组合:

apt

现在考虑the documentation of the AC_CHECK_LIB() macro

  

宏:-Wl,-Bstatic -lfoobar -Wl,-Bdynamic AC_CHECK_LIB library ,[ function ]   [ action-if-found ],[ action-if-not-found ])

     

[...] other-libraries 是一个shell命令列表,如果与库的链接成功则运行; action-if-found 是一个shell列表   链接失败时运行的命令。如果 action-if-not-found 不是   指定后,默认操作会将action-if-found添加到-llibrary并定义   'LIBS'(在所有首都)。 [...]

特别注意在未提供可选参数的情况下的默认行为(您的当前情况) - 这不是您想要的,至少不是它本身。我建议至少为 HAVE_LIBlibrary 案例提供替代行为,您也可以考虑在 action-if-found 案例中使configure失败。后者留作练习;实施前者可能看起来像这样:

action-if-not-found

您还应该注意AC_CHECK_LIB([foobar], [foobar_init], [ LIBS="-Wl,-Bstatic -lfoobar -Wl,-Bdynamic $LIBS" AC_DEFINE([HAVE_LIBFOOBAR], [1], [Define to 1 if you have libfoobar.]) ]) 次调用的顺序。正如其文档继续说:

  

此宏旨在支持从右到左构建AC_CHECK_LIB()   (最不依赖于最依赖的)时尚,如图书馆   依赖性被认为是连续的自然副作用   试验。链接器对库的排序很敏感,所以顺序在哪里   生成LIBS对于可靠地检测库非常重要。

如果您发现仍然无法获得所需内容,请查看LIBS实际执行的链接命令。在确定如何解决问题之前,您需要了解它们的错误。

总而言之,我观察到上述处理基本上是一种破解,它会使你的构建系统的弹性降低。它引入了对GNU工具链选项的依赖性(其他一些工具链可能接受),并假设整体上执行动态链接。可以通过额外的Autoconf代码来解决这些问题,但我建议您使用我描述的前两个替代方案中的一个。