使用 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++ 在非标准位置查找,您需要手动设置 CFLAGS
、CXXFLAGS
和 LDFLAGS
。
所以,在调用 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】:如果您碰巧使用GCC
或CLANG
,标准方法是使用环境变量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
注意您可以使用CPPFLAGS
或LDFLAGS
,但是,CPLUS_INCLUDE_PATH
/LIBRARY_PATH
完全符合您的要求。 CPPFLAGS/LDFLAGS
用于标志可以是很多东西,但*_PATH
用于PATHs
可移植性说明:虽然这适用于许多现代编译器,但并非所有编译器都会尊重这些变量。一些交叉编译器会完全忽略或覆盖它们,这会迫使人们诉诸 CFLAGS
和 LDFLAGS
修改,如其他答案中所述。
来源可能是因为我的回答中缺乏来源。这是 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_PATH
和 LIBRARY_PATH
。这意味着保留这些环境变量,以便用户可以向下划线编译器指示自定义选项,因为它们被两个主要的 OSS 编译器GCC and
CLANG` 理解。
我将编辑我的答案以指定我的解决方案满足问题的前提条件。以上是关于使用 autoconf 进行库解析?的主要内容,如果未能解决你的问题,请参考以下文章