autoconf/automake:基于库存在的条件编译? [英] autoconf/automake: conditional compilation based on presence of library?
问题描述
我需要根据库的存在条件有条件地编译一些代码.使用autoconf/automake看起来像这样应该很容易,但是我无法弄清楚.
I need to conditionally compile some code based on the presence of a library. Seems like this should be easy with autoconf/automake but I can't figure it out.
例如,如果存在一个PNG库,我想包括使用它的代码.我的configure.ac具有:
For example, if there is a PNG library present, I want to include code to use it. My configure.ac has:
AC_CHECK_LIB([png], [png_create_write_struct_2])
和我的Makefile.am有:
and my Makefile.am has:
if USE_LIBPNG
libdev_la_SOURCES += png.c
endif
(将png.c添加到libdev的源列表中,以便对其进行编译).
(which adds png.c to the list of sources for libdev so it gets compiled).
像USE_LIBPNG这样的自动生成条件需要在configure.ac中定义该条件,所以我需要:
An automake conditional like USE_LIBPNG requires the conditional be defined in configure.ac, so i need:
AM_CONDITIONAL([USE_LIBPNG], [test SOMETHINGOROTHER])
问题是,什么可以测试SOMETHINGOROTHER? AC_CHECK_LIB定义了我可以测试的内容?
The question is, what can test SOMETHINGOROTHER be? What does AC_CHECK_LIB define that I can test for?
AC_CHECK_LIB的默认行为是定义一个符号(在config.h中),该符号可以在源代码中使用,但这对Makefile没有帮助,因为AM_CONDITIONAL需要进行 shell测试
AC_CHECK_LIB's default behavior is to define a symbol (in config.h) which can be used in source code, but that doesn't help the Makefile since the AM_CONDITIONAL needs a shell test
我尝试覆盖默认的AC_CHECK_LIB行为,如下所示:
I tried overriding the default AC_CHECK_LIB behavior like so:
AC_CHECK_LIB([png], [png_create_write_struct_2], [HAS_LIBPNG=1])
之后我可以对其进行测试:
after which I could test for it:
AM_CONDITIONAL([USE_LIBPNG], [test "x$HAS_LIBPNG" = "x1"])
这很丑陋,但是适用于Makefile ...但是却产生了一个新问题:因为它丢弃了原始的AC_CHECK_LIB行为,并且我不再需要将符号添加到config.h中.
This is ugly, but works for the Makefile... but creates a new problem: since it discards the original AC_CHECK_LIB behavior, and I no longer get a symbol added to config.h, which I need.
我必须缺少一些基本的知识,或者可能做错了.已经闲逛了几个小时,没有找到答案.
I must be missing something basic, or possible Doing It Wrong. Have been digging around for hours and found no answer.
有人吗?
推荐答案
如果您要检查的库提供了供pkg-config
使用的.pc
文件,那么最好使用PKG_CHECK_MODULES
得到正确的标志. libpng可以:
If the library you're checking for supplies a .pc
file for use with pkg-config
, then you're much better off using PKG_CHECK_MODULES
to get the correct flags. libpng does:
(在configure.ac
中)
PKG_CHECK_MODULES([libpng], [libpng12])
这使您可以访问要添加到Makefile.am
的变量$(libpng_CFLAGS)
和$(libpng_LIBS)
(可能在AM_CFLAGS
/AM_CXXFLAGS
和LDADD
或它们的目标特定版本中).
This gives you access to the variables $(libpng_CFLAGS)
and $(libpng_LIBS)
which you will want to add to Makefile.am
(probably in AM_CFLAGS
/AM_CXXFLAGS
and LDADD
, or target-specific versions thereof).
如果未找到libpng12.pc
,也会导致configure
失败并显示错误.如果要继续configure
,则需要为PKG_CHECK_MODULES
提供第三个和第四个参数,分别是ACTION-IF-FOUND
和ACTION-IF-NOT-FOUND
:
It will also cause configure
to fail with an error if libpng12.pc
isn't found. If you want configure
to continue, you'll need to supply the third and fourth arguments to PKG_CHECK_MODULES
, which are ACTION-IF-FOUND
and ACTION-IF-NOT-FOUND
:
(在configure.ac
中)
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
现在,如果您需要一个automake
条件,则可以执行以下操作:
Now, if you need an automake
conditional, you can do something like:
(在configure.ac
中)
AM_CONDITIONAL([USE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])
如果您还需要预处理器定义,则可以这样使用AC_DEFINE
:
If you also need the preprocessor definition, you could use AC_DEFINE
like so:
(在configure.ac
中)
AS_IF([test "$USE_LIBPNG" -eq 1], [AC_DEFINE([USE_LIBPNG], [1], [Define if using libpng.])])
可能更好的方法是在Makefile.am
中设置定义:
Possibly nicer is to set the definition in Makefile.am
:
(在Makefile.am
中)
AM_CPPFLAGS =
if USE_LIBPNG
AM_CPPFLAGS += -DUSE_LIBPNG
endif
这将使您的命令行混乱,但是,如果您使用AC_CONFIG_HEADERS
,则AC_DEFINE
可以将定义放在标头中.我想这是否真的不重要,如果您使用AM_SILENT_RULES([yes])
还是不在乎您的命令行是否整洁(并且说实话,automake
还是会生成一些非常粗糙的命令行).
This will clutter your command line, though, whereas AC_DEFINE
can put the definition in a header if you use AC_CONFIG_HEADERS
. I guess this doesn't really matter if you use AM_SILENT_RULES([yes])
or don't care about your command line being neat (and let's be honest, automake
generates some pretty gnarly command lines anyway).
基于检查是否成功而建立可选支持的形式被认为是糟糕的形式(请参见有关此gentoo文档).这是我编码对libpng的可选支持的方式:
It is considered poor form to build optional support based on whether or not a check succeeded (see this gentoo doc for details). Here's how I'd code optional support for 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
设置一个缓存变量,因此您可以进行测试而不是替换AC_CHECK_LIB
的ACTION-IF-FOUND
:
If your library doesn't have a .pc
file
For completeness, here's how I'd check for a library that didn't have a .pc
file. I'll skip over the details of following good autoconf
style. AC_CHECK_LIB
sets a cache variable, so you can test that instead of replacing the 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, you should only do it this way if you have no other option.
这篇关于autoconf/automake:基于库存在的条件编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!