【问题标题】:setting up autotools to link single system library statically设置自动工具以静态链接单个系统库
【发布时间】:2017-11-14 05:14:05
【问题描述】:

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

在 configure.ac 我有:

AC_CHECK_LIB(foobar, foobar_init)

在开发机器上,这个库安装在 /usr/lib/x86_64-linux-gnu 中。它被检测到,但它是动态链接的,这会导致问题,因为它在某些机器上不存在。静态链接(-Wl、-Bstatic 等)效果很好,但我不知道如何在自动工具中进行设置。我尝试将其强制到项目的 Makefile.am 链接标志中,但它仍然优先考虑动态库。 我也尝试将 --enable-static 与 ./configure 一起使用,但它似乎对系统库没有影响。

【问题讨论】:

    标签: gcc autotools


    【解决方案1】:

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

    您还应该考虑将其作为安装程序的问题,而不是构建系统的问题。让安装程序负责确保程序所需的所有共享库都由安装它的系统提供。这是非常常见的;事实上,它是 yum / dnfapt 等包管理系统及其底层打包格式的灵感之一。

    如果您坚持只静态链接一个库,而动态链接其他所有库,那么您将需要跳过更多的环节。目标是发出链接选项,仅导致该库被静态链接,而不更改其他库的链接。使用 GNU 工具链,并假设程序是动态链接的,这将是以下选项组合:

    -Wl,-Bstatic -lfoobar -Wl,-Bdynamic
    

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

    宏:AC_CHECK_LIB (library, function, [action-if-found], [action-if-not-found], [other-libraries])

    [...] action-if-found 是与库的链接成功时要运行的 shell 命令列表; action-if-not-found 是一个shell列表 链接失败时运行的命令。如果 action-if-found 不是 指定,默认操作将 -llibrary 前置到 LIBS 并定义 'HAVE_LIBlibrary'(全部大写)。 [...]

    请特别注意在未提供可选参数的情况下的默认行为(您目前的情况)——这不是您想要的,至少不是您想要的。我建议至少为 action-if-found 的情况提供一种替代行为,您也可以考虑在 action-if-not-found 的情况下使configure 失败。后者留作练习;仅实现前者可能如下所示:

    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 对库的可靠检测很重要。

    如果你发现你仍然没有得到你想要的,那么看看make实际执行的链接命令。在确定如何解决问题之前,您需要了解它们的问题所在。

    话虽如此,我观察到上述处理基本上是一种 hack,它使您的构建系统的弹性大大降低。它引入了对 GNU 工具链选项的依赖(一些其他工具链可能仍然接受),并假设动态链接正在整体上执行。使用额外的 Autoconf 代码或许可以解决这些问题,但我强烈建议您改用我描述的前两个替代方案之一。

    【讨论】:

    • 请注意,静态链接取决于库的静态版本。这是与共享版本不同且完全独立的文件,一个文件的存在并不要求或暗示另一个文件的存在。在 Unix 上,静态库的常规名称是 libfoobar.a,而共享库是 libfoobar.so
    • 我试图在 AC_CHECK_LIB(之前)中手动添加 -Wl,-Bstatic,但失败了。您的版本运行良好,这就是我想要的。可行的替代解决方案,但似乎更 hacky,是从 Makefile.in 中获取“链接”规则,将其复制到 Makefile.am 并在那里添加 -Wl,-Bstatic。
    • 我同意使用安装程序可能是正确的解决方案,但这更简单(目前)。最终将不得不调查它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 2020-04-11
    • 2020-01-13
    • 1970-01-01
    相关资源
    最近更新 更多