我有一个项目,我想在其中静态链接系统库之一。该项目使用 GNU 构建系统。
在configure.ac中我有:
AC_CHECK_LIB(foobar, foobar_init)
在开发机器上,该库安装在/usr/lib/x86_64-linux-gnu 中。它被检测到,但它是动态链接的,这会导致问题,因为它在某些计算机上不存在。静态链接它(-Wl、-Bstatic 等)工作正常,但我不知道如何在自动工具中进行设置。我尝试将其强制写入项目的 Makefile.am 链接标志中,但它仍然优先考虑动态库。 我也尝试过在 ./configure 中使用 --enable-static,但它似乎对系统库没有影响。
最佳答案
如果你想静态链接整个程序,那么你应该将--disable-shared
选项传递给configure
。您可能也可能不需要传递 --enable-static
,具体取决于该选项的默认值(您可以通过 configure.ac
文件影响)。你确实应该考虑这样做。
您还应该考虑将此问题视为安装程序的问题,而不是构建系统的问题。安装程序有责任确保程序所需的所有共享库均由安装该程序的系统提供。这是非常常见的;事实上,它是 yum
/dnf
和 apt
等包管理系统及其底层打包格式的灵感之一。
如果您坚持只静态链接一个库,而动态链接其他所有库,那么您将需要跳过更多的环节。目标是发出链接选项,使该库静态链接,而不更改其他库的链接。使用 GNU 工具链,并假设程序以其他方式动态链接,这将是选项的组合:
-Wl,-Bstatic -lfoobar -Wl,-Bdynamic
现在考虑the documentation of the AC_CHECK_LIB()
macro :
Macro:
AC_CHECK_LIB
(library
,function
, [action-if-found
], [action-if-not-found
], [other-libraries
])[...]
action-if-found
is a list of shell commands to run if the link with the library succeeds;action-if-not-found
is a list of shell commands to run if the link fails. Ifaction-if-found
is not specified, the default action prepends-llibrary
toLIBS
and defines 'HAVE_LIBlibrary
' (in all capitals). [...]
特别注意在未提供可选参数的情况下的默认行为(您目前的情况)——这并不完全是您想要的,至少不是它本身。我建议至少为 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()
调用的顺序。正如其文档继续所说:
This macro is intended to support building
LIBS
in a right-to-left (least-dependent to most-dependent) fashion such that library dependencies are satisfied as a natural side effect of consecutive tests. Linkers are sensitive to library ordering so the order in whichLIBS
is generated is important to reliable detection of libraries.
如果您发现仍然没有得到您想要的结果,请查看 make
实际执行的链接命令。您需要先了解它们出了什么问题,然后才能确定如何解决问题。
关于gcc - 设置自动工具以静态链接单个系统库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44504321/