将 autotools 静态设置为 link 单个系统库
setting up autotools to link single system library statically
我有一个项目,我想 link 静态地使用其中一个系统库。该项目使用 GNU 构建系统。
在configure.ac我有:
AC_CHECK_LIB(foobar, foobar_init)
在开发机器上,此库安装在 /usr/lib/x86_64-linux-gnu 中。它被检测到,但它是动态 linked 的,这会导致问题,因为它不存在于某些机器上。静态链接(-Wl、-Bstatic 等)工作正常,但我不知道如何在 autotools 中设置它。我尝试将其强制为项目的 Makefile.am link 标志,但它仍然优先考虑动态库。
我也试过在 ./configure 中使用 --enable-static,但它似乎对系统库没有影响。
如果你想 link 整个程序静态,那么你应该将 --disable-shared
选项传递给 configure
。您可能需要也可能不需要传递 --enable-static
,具体取决于该选项的默认值(您可以通过 configure.ac
文件影响它)。你真的应该考虑这样做。
您还应该考虑将其作为安装程序的问题,而不是构建系统的问题。让安装者负责确保程序所需的所有共享库都由安装它的系统提供。这非常常见;事实上,它是 yum
/ dnf
和 apt
等包管理系统及其底层打包格式的灵感来源之一。
如果您坚持只静态地 linking 一个库,而 link 动态地 linking 其他所有库,那么您将需要再跳过几个环节。 objective 将发出 link 选项,使该库静态 linked,而不更改其他库的 linking。使用 GNU 工具链,并假设程序以其他方式被动态 linked,这将是以下选项的组合:
-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
实际执行的 link 命令。在确定如何解决问题之前,您需要了解它们的问题所在。
综上所述,我观察到上述处理基本上是一种 hack,它使您的构建系统的弹性大大降低。它引入了对 GNU 工具链选项的依赖(一些其他工具链可能仍然接受),并且它假设动态 linking 正在整体执行。使用额外的 Autoconf 代码也许可以解决这些问题,但我强烈建议您改用我描述的前两个备选方案之一。
我有一个项目,我想 link 静态地使用其中一个系统库。该项目使用 GNU 构建系统。
在configure.ac我有:
AC_CHECK_LIB(foobar, foobar_init)
在开发机器上,此库安装在 /usr/lib/x86_64-linux-gnu 中。它被检测到,但它是动态 linked 的,这会导致问题,因为它不存在于某些机器上。静态链接(-Wl、-Bstatic 等)工作正常,但我不知道如何在 autotools 中设置它。我尝试将其强制为项目的 Makefile.am link 标志,但它仍然优先考虑动态库。 我也试过在 ./configure 中使用 --enable-static,但它似乎对系统库没有影响。
如果你想 link 整个程序静态,那么你应该将 --disable-shared
选项传递给 configure
。您可能需要也可能不需要传递 --enable-static
,具体取决于该选项的默认值(您可以通过 configure.ac
文件影响它)。你真的应该考虑这样做。
您还应该考虑将其作为安装程序的问题,而不是构建系统的问题。让安装者负责确保程序所需的所有共享库都由安装它的系统提供。这非常常见;事实上,它是 yum
/ dnf
和 apt
等包管理系统及其底层打包格式的灵感来源之一。
如果您坚持只静态地 linking 一个库,而 link 动态地 linking 其他所有库,那么您将需要再跳过几个环节。 objective 将发出 link 选项,使该库静态 linked,而不更改其他库的 linking。使用 GNU 工具链,并假设程序以其他方式被动态 linked,这将是以下选项的组合:
-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
实际执行的 link 命令。在确定如何解决问题之前,您需要了解它们的问题所在。
综上所述,我观察到上述处理基本上是一种 hack,它使您的构建系统的弹性大大降低。它引入了对 GNU 工具链选项的依赖(一些其他工具链可能仍然接受),并且它假设动态 linking 正在整体执行。使用额外的 Autoconf 代码也许可以解决这些问题,但我强烈建议您改用我描述的前两个备选方案之一。