我需要根据库的存在有条件地编译一些代码。看起来,使用autoconf/automake应该很容易,但我想不出来。
例如,如果有一个PNG库,我希望包含使用它的代码。我的configure.ac有:
AC_CHECK_LIB([png], [png_create_write_struct_2])
我的Makefile.am有:
if USE_LIBPNG
libdev_la_SOURCES += png.c
endif
(它将png.c添加到libdev的源代码列表中,以便进行编译)。
像USE_LIBPNG这样的自动条件要求在configure.ac中定义条件,所以我需要:
AM_CONDITIONAL([USE_LIBPNG], [test SOMETHINGOROTHER])
问题是,什么东西可以测试或其他东西是什么?AC_CHECK_LIB定义了我可以测试的内容吗?
AC_CHECK_LIB的默认行为是定义一个符号(在config.h中),它可以在源代码中使用,但这无助于Makefile,因为AM_CONDITIONAL需要一个shell测试
我试图重写默认的AC_CHECK_LIB行为如下:
AC_CHECK_LIB([png], [png_create_write_struct_2], [HAS_LIBPNG=1])
在那之后我可以测试它:
AM_CONDITIONAL([USE_LIBPNG], [test "x$HAS_LIBPNG" = "x1"])
这太丑了,但在Makefile工作.但是造成了一个新的问题:因为它丢弃了原始的AC_CHECK_LIB行为,所以我不再需要添加到config.h的符号。
我一定是错过了一些基本的东西,或者可能做错了什么。已经挖了好几个小时了却没找到答案。
有没有人?
发布于 2011-03-03 06:28:10
如果您正在检查的库提供了一个.pc
文件,以便与pkg-config
一起使用,那么最好使用PKG_CHECK_MODULES
来获得正确的标志。libpng确实:
( configure.ac
)
PKG_CHECK_MODULES([libpng], [libpng12])
这使您可以访问要添加到$(libpng_CFLAGS)
中的变量$(libpng_LIBS)
(可能在AM_CFLAGS
/AM_CXXFLAGS
和LDADD
中,或者在特定于目标的版本中)。
如果找不到configure
,也会导致libpng12.pc
失败。如果希望configure
继续,则需要向PKG_CHECK_MODULES
提供第三个和第四个参数,即ACTION-IF-FOUND
和ACTION-IF-NOT-FOUND
( configure.ac
)
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
现在,如果您需要一个automake
条件,您可以执行如下操作:
( configure.ac
)
AM_CONDITIONAL([USE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])
如果您还需要预处理器定义,您可以使用AC_DEFINE
,如下所示:
( configure.ac
)
AS_IF([test "$USE_LIBPNG" -eq 1], [AC_DEFINE([USE_LIBPNG], [1], [Define if using libpng.])])
可能更好的做法是在Makefile.am
中设置定义
( Makefile.am
)
AM_CPPFLAGS =
if USE_LIBPNG
AM_CPPFLAGS += -DUSE_LIBPNG
endif
然而,这将使命令行混乱,而如果使用AC_DEFINE
,则AC_CONFIG_HEADERS
可以将定义放入标头中。我想如果您使用AM_SILENT_RULES([yes])
或者不关心您的命令行是否整洁(老实说,automake
生成了一些非常粗糙的命令行),这并不重要。
关于良好autoconf
风格的一点注记
基于检查是否成功,构建可选支持被认为是糟糕的形式(详见这个绅士医生 )。下面是我如何为libpng编写可选的支持:
( configure.ac
)
# This is because the first PKG_CHECK_MODULES call is inside a conditional.
PKG_PROG_PKG_CONFIG
AC_ARG_WITH([libpng],
[AS_HELP_STRING([--with-libpng],
[support handling png files @<:@default=check@:>@])],
[],
[with_libpng=check])
AS_CASE(["$with_libpng"],
[yes], [PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1])],
[no], [],
[PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])])
AM_CONDITIONAL([USE_LIBPNG], [test "$with_libpng" != no -a "$HAVE_LIBPNG" -eq 1])
( Makefile.am
)
if USE_LIBPNG
AM_CPPFLAGS += -DUSE_LIBPNG
AM_CFLAGS += $(libpng_CFLAGS)
LDADD += $(libpng_LIBS)
libdev_la_SOURCES += png.c
endif
如果您的库没有.pc
文件
为了完整起见,我将检查一个没有.pc
文件的库。我将跳过以下好的autoconf
风格的细节。AC_CHECK_LIB
设置了一个缓存变量,所以您可以测试它,而不是替换ACTION-IF-FOUND
of AC_CHECK_LIB
( configure.ac
)
AC_CHECK_LIB([png], [png_create_write_struct_2])
# Then test:
AS_IF([test "$ac_cv_lib_png_png_create_write_struct_2" = yes], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
# Or set conditional:
AM_CONDITIONAL([USE_LIBPNG], [test "$ac_cv_lib_png_png_create_write_struct_2" = yes])
IMHO,只有在没有其他选择的情况下,你才应该这样做。
发布于 2011-03-03 18:02:46
谢谢你的回复。
杰克:我正在努力实现最大的可移植性,所以不能假设库是作为包的一部分安装的(它们不是在我自己的盒子上!),这意味着您建议的没有其他选项的解决方案就是我已经尝试过的--手动设置一个shell变量--但也手动执行了AC_CHECK_LIB应该完成的额外步骤:将库放在LIBS前面,并定义HAVE_LIBxxx。
但是有一个问题:自动报头抱怨裸露的AC_DEFINE:
autoheader: warning: missing template: HAVE_LIBPNG
autoheader: Use AC_DEFINE([HAVE_LIBPNG], [], [Description])
如果autoheader在将来起作用的话,我会很高兴的,所以我不得不将AC_DEFINE改为完整的monty:
AC_CHECK_LIB([png], [png_create_write_struct_2],
[HAS_LIBPNG=1
LIBS="-lpng $LIBS"
AC_DEFINE([HAVE_LIBPNG], 1, [Define to 1 if you have the `png' library (-lpng)])])
这是可行的,但我不太喜欢复制AC_CHECK_LIB的默认行为。
威廉:是的,我可以用grep来定义concondes.h中的符号,这也很管用。
这两种解决方案各有优缺点(什么不是呢?)不知道我会走哪条路,但有选择是很好的。
再次感谢。
https://stackoverflow.com/questions/5176929
复制相似问题