如何通过AC_SEARCH_LIBS保存找到的库名到自定义变量并解决跨平台差异?
Autotools 库检测与链接的优雅解决方案
背景与问题
我当前的项目仓库结构如下:
configure.ac GNUmakefile.in src |--lib |--bin
其中src/lib存放待构建的共享库源码,src/bin包含多个二进制程序的源码(其中一个由同目录下的多个静态库组成)。
我遇到两个具体问题:
- 问题1:部分二进制文件需要链接第三方库,但并非所有二进制都需要。
- 问题2:某个依赖库在Linux和FreeBSD上的名称不同,我想找到一种优雅的方式检测并记录第一个找到的库名,替代当前两次调用
AC_CHECK_LIB的繁琐写法。
当前我尝试过用AC_SEARCH_LIBS,但不知道如何把找到的第一个库名存到自定义变量里,比如:
AC_SEARCH_LIBS([func], [lib_name_on_linux lib_name_on_freebsd], [AC_SUBST([MYLIB], [????])])
目前的变通方案是两次调用AC_CHECK_LIB:
AC_CHECK_LIB([lib_name_on_linux], [func], [AC_SUBST([MYLIB], ["-llib_name_on_linux"])]) AC_CHECK_LIB([lib_name_on_freebsd], [func], [AC_SUBST([MYLIB], ["-llib_name_on_freebsd"])])
这个方法能工作(因为两个系统只会匹配其中一个),但不够优雅,而且要处理两个都找不到的错误还得加额外代码,想知道正确的处理方式是什么?
正确解决方案:利用AC_SEARCH_LIBS的内置变量
其实AC_SEARCH_LIBS本身就提供了内置变量来获取成功找到的库名,不需要手动去猜或者多次调用AC_CHECK_LIB。
核心思路
当AC_SEARCH_LIBS成功找到某个库时,会自动设置$ac_cv_search_<func>变量(把<func>替换成你检测的实际函数名),这个变量的值就是链接该库所需的完整参数——比如-llibfoo,如果函数本身在标准库(比如libc)里,变量值就是空字符串,完全符合我们的需求。我们可以直接把这个变量的值通过AC_SUBST存到自定义变量里。
示例代码
针对你的场景,代码可以这样写:
AC_SEARCH_LIBS([func], [lib_name_on_linux lib_name_on_freebsd], [ # 把找到的库链接参数存入MYLIB变量 AC_SUBST([MYLIB], [$ac_cv_search_func]) ], [ # 如果所有指定的库都找不到,在这里抛出错误提示 AC_MSG_ERROR([无法找到提供func函数的依赖库,请确保对应库已安装]) ])
额外技巧与问题1的解决
- 变量命名注意事项:
$ac_cv_search_后面的函数名必须和AC_SEARCH_LIBS的第一个参数完全一致,大小写也要严格匹配,否则会找不到对应的内置变量。 - 精准控制二进制链接:针对问题1中“部分二进制需要链接第三方库”的需求,你只需要在
GNUmakefile.in里给对应的目标单独添加MYLIB变量即可,比如:
# 需要链接第三方库的二进制程序foo foo_LDADD = $(MYLIB) # 不需要链接的二进制程序bar则不添加 bar_LDADD =
这样就能精准控制哪些程序需要链接第三方库,避免不必要的依赖。
内容的提问来源于stack exchange,提问作者Aayla Secura
相关产品推荐
相关产品推荐

