我有一个项目,我希望静态链接其中一个系统库。该项目使用GNU构建系统。
在configure.ac中我有:
AC_CHECK_LIB(foobar, foobar_init)
在开发机器上,此库安装在/ usr / lib / x86_64-linux-gnu中。它被检测到,但它是动态链接的,这会导致问题,因为它在某些机器上不存在。静态链接(-Wl,-Bstatic等)工作正常,但我不知道如何在autotools中设置它。我尝试将此强制转换为项目的Makefile.am链接标志,但它仍然优先考虑动态库。 我也尝试过使用带有./configure的--enable-static,但它似乎对系统库没有影响。
答案 0 :(得分:3)
如果要静态链接整个程序,则应将--disable-shared
选项传递给configure
。您可能也可能不需要传递--enable-static
,具体取决于该选项的默认值(您可以通过configure.ac
文件影响该值)。你真的应该考虑这样做。
您还应该考虑将此问题作为安装程序的问题,而不是构建系统。安装人员有责任确保程序所需的所有共享库都由安装它的系统提供。这非常常见;事实上,它是包{}} / yum
和dnf
等包裹管理系统的灵感之一,以及它们的底层包装格式。
如果你坚持只静态链接一个库,在动态链接其他所有内容的时候,那么你需要跳过几个箍。目标是发出链接选项,只导致该库静态链接,而不更改其他库的链接。使用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代码来解决这些问题,但我建议您使用我描述的前两个替代方案中的一个。