使用 autoconf 进行库解析?

Posted

技术标签:

【中文标题】使用 autoconf 进行库解析?【英文标题】:Library resolution with autoconf? 【发布时间】:2010-10-05 18:41:06 【问题描述】:

我正在构建我的第一个 autoconf 托管软件包。

但是,我在任何地方都找不到任何简单的示例来说明如何指定所需的库,并在不同的地方找到该库。

我目前有:

AC_CHECK_LIB(['event'], ['event_init'])

但是:

    没有找到安装在/opt/local/lib中的版本 如果实际上没有找到库,它不会抱怨 我也需要将包含路径设置为/opt/local/include

非常感谢任何帮助或指向体面教程的链接...

【问题讨论】:

这Documentation on AC_CHECK_LIB 有帮助吗? 【参考方案1】:

autoconf 脚本无法猜测“可选”库位置,这些位置可能因平台而异。所以你可以说

CPPFLAGS="-I/opt/local/include" LDFLAGS="-L/opt/local/lib" ./configure

对于AC_CHECK_LIB(),您需要在“action-if-false”参数中明确指定失败条件:

dnl This is simply print "no" and continue:
AC_CHECK_LIB([m], [sqrt123])
dnl This will stop:
AC_CHECK_LIB([m], [sqrt123], [], [AC_MSG_ERROR([sqrt123 was not found in libm])])

输出:

checking for sqrt123 in -lm... no
checking for sqrt123 in -lm... no
configure: error: sqrt123 was not found in libm

AC_CHECK_LIB() 默认情况下不会失败,原因很明显:人们可能会检查几个提供类似功能的不同库并选择其中之一:)

也可以查看this post 了解类似主题。

【讨论】:

更好的是,./configure CPPFLAGS=... 会记住后续./config.status --recheck 中的变量,例如。见gnu.org/software/autoconf/manual/autoconf-2.67/html_node/…【参考方案2】:

如果您希望 gcc/g++ 在非标准位置查找,您需要手动设置 CFLAGSCXXFLAGSLDFLAGS

所以,在调用 AC_CHECK_LIB() 之前,请执行以下操作

CFLAGS="$CFLAGS -I/opt/local/include"
CXXFLAGS="$CXXFLAGS -I/opt/local/include"
LDFLAGS="$LDFLAGS -L/opt/local/lib"

如果您只在整个配置脚本中使用 gcc,则不需要 CXXFLAGS。

【讨论】:

我认为第一行应该是 CPPFLAGS,而不是 CFLAGS? 我的意思是第一行中的 CFLAGS,但就包含标题而言,CPPFLAGS 也应该可以解决问题。 我同意 Alnitak 的观点,即建议使用 CFLAGS/CXXFLAGS(取决于您打算使用的 C/C++ 编译器)仅用于编译器参数(如“-g”, “-O3”)。包含应该转到 CPPFLAGS(C 预处理器)。 不,不,不,不,不。绝对不能在 configure.ac 中分配 CFLAGS 来自 autoconf 文档:“......包本身不应该设置用户变量......” “CFLAGS 就是这样一个变量。” *FLAGS 只能在 configure.ac 中临时设置,例如迎合 AC_CHECK_foo。最终必须恢复原始值。【参考方案3】:

如果库提供 .pc 文件,请考虑使用 PKG_CHECK_MODULES() 宏来执行您想要的操作。如果是您自己的库,只需将 .pc 文件发送到 /usr/lib/pkgconfig 中,其他开发人员可以更轻松地依赖/使用它。

【讨论】:

我的库附带一个 .pc 文件。在哪里放置 PKG_CHECK_MODULES() 宏?谢谢。【参考方案4】:

我知道这是一个旧线程,但我想这可能会帮助一些人。这就是我找到一些东西的方式。

hdff="no"
hdffprefix="ERROR"
AC_ARG_WITH(hdf,[  --with-hdf              Compile with hdf library, for output.],[hdffprefix=$withval hdff="yes"],[])
# if there is no value given, it appears tha hdffprefix is set to "yes"
if test $hdffprefix = "yes" -a $hdff = "yes"
then
    echo "HDF: Attempting to find HDF"
    hdffprefix="ERROR"

    # check if hdffprefix is set, if it is not, it sets it to "ERROR" and the 
    # 'if' comparison evaluates to true
    if [[ "$hdffprefix" == "ERROR" ]]
    then
        echo "HDF: hdffprefix not set, searching PATH"
        for i in `echo $PATH | tr ':' '\n'`
        do
            if [[ $i == *hdf* ]]
            then
                if [[ $i == *bin/* ]]
                then
                    hdffprefix=$i%bin/
                    # if it doesn't exist, re-set to ERROR
                    if [[ ! -f $hdffprefixinclude/hdf.h ]]
                    then
                    hdffprefix="ERROR"
                    fi
                elif [[ $i == *bin* ]]
                then
                    hdffprefix=$i%bin
                    # if it doesn't exist, re-set to ERROR
                    if [[ ! -f $hdffprefixinclude/hdf.h ]]
                    then
                    hdffprefix="ERROR"
                    fi
                fi
            fi
        done
        if [[ "$hdffprefix" == "ERROR" ]]
        then
            echo "HDF: hdffprefix not found in PATH, trying 'which'"
            WHICH_TEST_HDF=`which hdf2gif`
            if [[ WHICH_TEST_HDF != "" ]]
            then
                hdffprefix=$WHICH_TEST_HDF%bin/hdf2gif
            else
                echo "HDF: Warning - hdf not found"
            fi
        fi
    fi
    if [[ "$hdffprefix" != "ERROR" ]]
    then
        hdff="yes"
        echo "HDF found: $hdffprefix"
    fi
fi
if test $hdff = 'yes'; then
        hdfincs=" -DUSE_HDF -I"$hdffprefix"include"
        scriptotherlibsinc=$scriptotherlibsinc" -L"$hdffprefix"/lib"
        scriptotherlibs=$scriptotherlibs" -lmfhdf -ldf -ljpeg -lz"
    AC_CHECK_HEADERS([$hdffprefix/include/hdf.h],,[AC_MSG_ERROR([Cannot find hdf.h])])
    AC_CHECK_HEADERS([$hdffprefix/include/mfhdf.h],,[AC_MSG_ERROR([Cannot find mfhdf.h])])
fi

【讨论】:

【参考方案5】:

这是怎么做的:

# We need the math library for some tests.
AC_CHECK_LIB([m], [floor], [],
                  [AC_MSG_ERROR([Can't find or link to the math library.])])

请注意,找不到库时它不会自动出错,您必须按照上面的代码调用 AC_MSG_ERROR()。

【讨论】:

【参考方案6】:

所以你想设置 autoconf 来自动找到这些目录,codelogic 给出了答案;但假设您不想在所有系统上搜索,只在 Mac 上搜索。您可以添加以下内容

AC_CANONICAL_HOST
case $host_os in
    darwin* )
        CFLAGS="$CFLAGS -I/opt/local/include"
        CXXFLAGS="$CXXFLAGS -I/opt/local/include"
        LDFLAGS="$LDFLAGS -L/opt/local/lib"
        ;;

esac

请注意,我将其添加为案例树,以便您以后可以为各种操作系统添加内容(例如 linux* 和 BSD)。

【讨论】:

【参考方案7】:

如果您碰巧使用GCCCLANG,标准方法是使用环境变量CPLUS_INCLUDE_PATH 与非官方包含 文件的路径和LIBRARY_PATH对于图书馆。提醒您不必更改 configure.ac 中的任何内容。所以你可以这样调用配置:

$ export CPLUS_INCLUDE_PATH=/opt/local/include
$ export LIBRARY_PATH=/opt/local/lib
$ ./configure  

事实标准变量

Variable           | lang | Usage
-------------------|------|---------
C_INCLUDE_PATH     | C    | colon separated list of include directory paths
CPLUS_INCLUDE_PATH | C++  | colon separated list of include directory paths
LIBRARY_PATH       | C/C++| colon separated compiling time static linking dirs
LD_RUN_PATH        | C/C++| colon separated compiling time dynamic linking dirs
LD_LIBRARY_PATH    | C/C++| colon separated run-time dynamic linking dirs
CPPFLAGS           | C/C++| prepocessor flags
CFLAGS             | C    | Compiling flags
CXXFLAGS           | C++  | Compiling flags
LDFLAGS            | C++  | Linking flags

注意您可以使用CPPFLAGSLDFLAGS,但是,CPLUS_INCLUDE_PATH /LIBRARY_PATH 完全符合您的要求。 CPPFLAGS/LDFLAGS 用于标志可以是很多东西,但*_PATH 用于PATHs

可移植性说明:虽然这适用于许多现代编译器,但并非所有编译器都会尊重这些变量。一些交叉编译器会完全忽略或覆盖它们,这会迫使人们诉诸 CFLAGSLDFLAGS 修改,如其他答案中所述。

来源可能是因为我的回答中缺乏来源。这是 GCC 中的CPLUS_INCLUDE_PATH:https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html

【讨论】:

我使用过很多编译器,但从未见过 CPLUS_INCLUDE 和 LIBRARY_PATH。相反,请使用 CPPFLAGS 和 LDFLAGS,它们是在 Linux 系统上构建的标准标志。 我们在我的项目中大量使用这些环境变量来安装前缀 /usr/local 的库。 CPPFLAGS 是一个完全不同的变量。在CPPFLAGS 中,您将编写CPPFLAGS="-I/opt/local/include",它们实际上是预处理器标志而不是包含路径,例如CPLUS_INCLUDE_PATH。您能否提供:在 Linux 系统上构建的标准标志。 请参阅gnu.org/software/automake/manual/html_node/… 了解 autoconf/automake/libtool 软件包经常使用的标志。 我明白了,在您的消息来源中,它表明 autotools 包忽略了 CPLUS_INCLUDE_PATHLIBRARY_PATH。这意味着保留这些环境变量,以便用户可以向下划线编译器指示自定义选项,因为它们被两个主要的 OSS 编译器GCC and CLANG` 理解。 我将编辑我的答案以指定我的解决方案满足问题的前提条件。

以上是关于使用 autoconf 进行库解析?的主要内容,如果未能解决你的问题,请参考以下文章

对 C++ 库进行 autoconf 搜索

使用 Autoconf 为 ARM 进行交叉编译

包括使用 automake 和 autoconf 的动态库

Kconfig的简单例子

autoconf/automake:基于库存在的条件编译?

如何通过 autoconf/automake 排除 boost 库/头文件包含问题?