autoconf:设置AC_CHECK_LIB编译器标志

autoconf: Set AC_CHECK_LIB compiler flags

本文关键字:LIB 编译器 标志 CHECK autoconf 设置 AC      更新时间:2023-10-16

我正试图设置我的项目使用autotools构建系统进行分发。然而,当涉及到包括一些额外的库时,我遇到了一个问题。

我的代码依赖于几个库:

  • 一个我写的(我将命名为libfoo)

  • 第三方(我将调用libbar)

  • Eigen3(这只是头文件)

这些都已经编译并安装在我的$HOME目录中。我不需要把它们作为这个项目的一部分来构建。

我需要的标志是

-std=c++11 (Got this taken care of)

-I/path/to/include/libfoo (or libbar, or Eigen3)

-L/path/to/lib/ (Where libfoo and libbar reside)

-lfoo

编译和链接libfoo和libbar

问题是我想设置检查libfoo和libbar及其头的存在(我已经检查了Eigen3的设置)。问题是,像AC_CHECK_HEADERS和AC_CHECK_LIB这样的宏似乎不希望包含所需的CPPFLAGS或LDFLAGS,无论我如何尝试定义它们,因此配置步骤失败。

AC_LANG_PUSH([C++])
AC_CHECK_HEADERS([libfoo/foo.h], , [echo "Did not find libfoo headers"; exit -1])
AC_LANG_POP([C++])

读取config.log显示configure试图使用

对头文件进行编译
g++ -std=c++11 (other flags...)

但由于上面缺少标志而失败(错误是"无法找到Eigen3/dense",或类似,表明缺少-I标志)

我是autotools的新手,所以我可能错过了一些明显的东西,但是我已经阅读了大量的帮助和手册,到目前为止还没有弄清楚我需要做什么来设置这个。

相关:如果需要,我希望用户能够通过——with-libfoo-include(等)手动指定libfoo和libbar的位置,所以我还需要能够指定配置检测这些库的位置。如何做到这一点?

你所需要做的就是:

-std=c++11 (Got this care)

最好使用ax_cxx_compile_stdcxx_11.m4
要使用它,您需要从上面的链接下载它并将其设置在$(project_top)/m4/
接下来,在configure中编写如下代码。交流:

AX_CXX_COMPILE_STDCXX_11([noext], [mandatory])

和exec,你可以检查是否可能使用c++ 11的特性在平台

$ autoreconf -vi -I m4
$ ./configure

-I/path/to/include/libfoo(或libbar,或Eigen3)
-L/path/to/lib/(libfoo和libbar所在的目录)
- lfoo

这很难简单地解释,

  1. 标准库提供。pc 文件
    你应该使用PKG_CHECK_MODULES宏你应该参考pkg-config指南和PKG_CHECK_MODULES宏
    这有助于接收include路径和库路径。

  2. 库提供foo-config shell
    例如,libcurl提供curl-config, libxml2提供xml2-config。因此,我们可以使用这个shell获取include/lib路径。

    CURL_LIBS=`$CURLCONFIG --libs`  
    CURL_CFLAGS=`$CURLCONFIG --cflags`  
    
  3. 用C编写的库,不提供任何功能你应该使用AC_CHECK_HEADER/AC_CHECK_LIB
    你可以参考AC_CHECK_HEADER, AC_CHECK_LIB

  4. 用c++编写的库,不提供任何功能
    使用 AC_TRY_LINK/AC_LANG_PUSH , AC_LANG_POP 像下面…

    AC_MSG_CHECKING([for some_cpp_lib])
    AC_LANG_PUSH(C++)
    SAVE_LIBS="$LIBS"
    LIBS="$LIBS -lsome_cpp_lib"
    AC_TRY_LINK([#include <some_cpp_lib.hpp>], 
            [SomeCppLib object;],
            has_some_cpp_lib=1,
            has_some_cpp_lib=0)
    AC_LANG_POP(C++)
    if test $has_some_cpp_lib = 0; then
      AC_MSG_RESULT([no])
    else
      AC_MSG_RESULT([yes])
    fi
    

对于那些想知道同样事情的人,我通过查看另一个开源项目中的autotools文件找到了我的答案:

首先,要添加——with-x-include=选项标志,使用

AC_ARG_WITH
第二,做这个检查的粗略过程包括首先检查你想要的头文件是否存在于你说它应该使用 的地方
AC_CHECK_FILE

,然后保存旧的CPPFLAGS,然后添加所需的include。然后我可以使用

检查标题
AC_CHECK_HEADER

,最后,使用宏的on-success参数,设置一个稍后测试的变量。如果为true,我使用用户指定的include路径定义变量LIBFOO_INC。

最后,我还找到了宏AX_CXX_CHECK_LIB,它允许在c++库中检查库。它可以在ac-archive

中获得。

值得注意的是,在我的例子中,我需要为CPPFLAGS和CXXFLAGS定义其中的一些标志,因此这需要在某些地方手动设置它们。它可能并不总是影响人们,但它是一个潜在的陷阱。

我发现获得编译器和链接器标志的最简单方法是使用PKG_CHECK_MODULES,它在幕后使用pkg-config来让库提供正确的标志。

 PKG_CHECK_MODULES([FOO], [foo >= 3])