【问题标题】:autoconf: Set AC_CHECK_LIB compiler flagsautoconf:设置 AC_CHECK_LIB 编译器标志
【发布时间】:2015-10-02 03:31:53
【问题描述】:

我正在尝试设置我的项目以使用自动工具构建系统进行分发。但是,在包含一些额外的库时我遇到了问题。

我的代码依赖于几个库:

  • 我写的一个(我叫 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 的位置,因此我还需要能够指定 configure 检测这些库的位置。如何做到这一点?

【问题讨论】:

    标签: c++ autotools autoconf automake


    【解决方案1】:

    您需要做的就是:

    对于

    -std=c++11(已经处理好了)

    很好用ax_cxx_compile_stdcxx_11.m4
    要使用它,您需要从上面的链接下载并设置在 $(project_top)/m4/
    接下来,您在 configure.ac 中编写如下:

    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
      你应该参考Guide to pkg-configThe PKG_CHECK_MODULES Macro
      这将有助于接收包含路径和库路径。

    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_PUSHAC_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
      

    【讨论】:

    • 这不是很明显,这将补充LDFLAGS,以便通过链接器的-L path 参数可以使用位于偏僻位置的库.当使用AC_CHECK_LIB(或推荐的更好的AC_SEARCH_LIBS)确认库的存在时,这是否会自动发生? OTOH 无论如何尝试在configure.ac 条目中指定库位置可能是不正确的,因为它更恰当地属于configureLDFLAGS="-L/p/a/t/h" 参数以供最终用户/编译器使用...跨度>
    • 感谢 #4。 出于某种原因,当AC_SEARCH_LIBS 测试 C++ 文件时,automake 开发人员认为不适合包含 C++ 头文件。 (或者,如果他们有,他们已经很好地将它隐藏在手册中,所以我会很感激这个指针。)我花了一个小时才意识到这是一个 C++ 的东西(并且我发现这一点只是因为它适用于gmp,但不适用于gmpxx)。以此为指导编写 m4 脚本只用了不到 5 分钟。哇。
    【解决方案2】:

    对于任何偶然发现这个想知道同样事情的人,我通过查看来自另一个开源项目的 autotools 文件找到了答案:

    首先,要添加 --with-x-include=option 标志,请使用

    AC_ARG_WITH
    

    其次,进行此检查的粗略过程包括首先检查您想要的头文件是否存在于您说它应该使用的位置

    AC_CHECK_FILE
    

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

    检查标题
    AC_CHECK_HEADER
    

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      虽然你的mileage may vary...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-27
        相关资源
        最近更新 更多