gcc - 设置自动工具以静态链接单个系统库

标签 gcc autotools

我有一个项目,我想在其中静态链接系统库之一。该项目使用 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/dnfapt 等包管理系统及其底层打包格式的灵感之一。

如果您坚持只静态链接一个库,而动态链接其他所有库,那么您将需要跳过更多的环节。目标是发出链接选项,使该库静态链接,而不更改其他库的链接。使用 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. If action-if-found is not specified, the default action prepends -llibrary to LIBS 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 which LIBS is generated is important to reliable detection of libraries.

如果您发现仍然没有得到您想要的结果,请查看 make 实际执行的链接命令。您需要先了解它们出了什么问题,然后才能确定如何解决问题。

综上所述,我发现上述处理基本上是一种黑客攻击,它使您的构建系统的弹性大大降低。它引入了对 GNU 工具链选项的依赖(其他一些工具链可能仍然接受),并且假设动态链接正在整体执行。也许可以使用额外的 Autoconf 代码来解决这些问题,但我强烈建议您采用我描述的前两个替代方案之一。

关于gcc - 设置自动工具以静态链接单个系统库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44504321/

相关文章:

带有自动工具的 CDT 中的 C++11

c++ - Autoconf 没有正确定义变量

c - autotools Makefile 是否自动将包含的头文件视为依赖项?

c++ - 非标准 C++ 后缀的自动依赖跟踪

c - 超线程的最佳 gcc 优化开关

c++ - 堆分配变量的结构成员对齐

linux - 在没有 root 的非标准位置使用 glibc 构建 GCC

c - 程序需要加CFLAGS=-D_GNU_SOURCE才能编译,这个应该放哪里?

c - C 数组的对齐方式 - 数组元素的对齐方式大于元素大小

c - gcc:使用 -O1 并拼写 -O1 选项会导致不同的结果(一个有效;一个无效)