1. 常用的autoconf宏
1.1 AC_PREREQ()
AC_PREREQ宏指定autoconf的最低版本。例子如下:
AC_PREREQ(2.69)
1.2 AC_INIT()
AC_INIT宏初始化autoconf系统。
AC_INIT最多接受五个参数:package名称,version,和可选的bug-report地址,tarname和url。如下的例子指定了前三个。
package名称使用一种标准化的形式。automake生成的压缩包被默认命名为tarname-version.tar.gz,tarname被设置为标准化的软件包名(小写,所有标点被转化为下划线)。
bug-report参数,通常设置为一个E-Mail地址,但是任何文本字符串都是有效的。
version参数,最为广泛使用的惯例是传递marjor.minor。但用marjor.minor.reversion也没有错误。如果你喜欢,你甚至可以添加非数字文本到这个宏,例如0.15.alpha。
autoconf从AC_INIT的参数,生成一些替换变量,如:
@PACKAGE_NAME@,
@PACKAGE_VERSION@,
@PACKAGE_TARNAME@,
@PACKAGE_STRING@ ,
@PACKAGE_BUGREPORT@
1.3 AM_INIT_AUTOMAKE
AM_INIT_AUTOMAKEH是auotmake的宏。它初始化automake,参数是调用automake使用的参数(与编译器没有关系)。
例子如下:
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
1.4 PKG_CHECK_MODULES
PKG_CHECK_MODULES是pkg-config工具提供的宏。它检查指定的库是否存在并符合要求。如果是,则设置变量XXX_CFLAGS和XXX_LIBS的值。其中XXX是PKG_CHECK_MODULES宏的第一个参数。
如下的例子,检查libdrm.so是否存在并且版本不低于2.4。如果是,设置变量video_drm的值为yes,否则设置为no。
PKG_CHECK_MODULES(DRM, [libdrm >= 2.4], video_drm="yes",video_drm="no")
1.5 AC_CONFIG_SRCDIR
AC_CONFIG_SRCDIR宏的目的,是让configure脚本知道,它执行的目录是否真是工程的目录。
configure需要能定位自己,因为工程代码可能是来自一个远程目录。AC_CONFIG_SRCDIR给了一个在正确位置查找的重要提示。
AC_CONFIG_SRCDIR指定的文件,应该尽量选择你的项目独有的文件,这样configure不容易把其它项目的目录当成是自己的。
如下的例子指定src/main.c作为这个文件。
AC_CONFIG_SRCDIR([src/main.c])
1.6 AC_CONFIG_HEADERS
AC_CONFIG_HEADERS宏允许指定一个或多个config.status从模板文件生成的头文件。可以在你的头文件模板里放置多个像这样的声明,每行一个。
如下面的例子指定了头文件config.h。当configure.ac修改时,config.status会基于AC_CONFIG_HEADERS宏重新生成config.h。
AC_CONFIG_HEADERS([config.h])
1.7 AC_CHECK_PROG
AC_CHECK_PROG宏检查指定的程序是否存在。
如下面的例子,如果ranlib存在,则变量RANLIB设置为ranlib,否则设置为:。
AC_CHECK_PROG([RANLIB], [ranlib], [:])
1.8 AC_CHECK_TOOL
AC_CHECK_TOOL宏与AC_CHECK_PROG功能类似,它检查指定的程序是否存在。不同的是,它会先检查–host值作为前缀的命令。
举一个例子。如果如下调用configure:
./configure --build=x86_64-gnu --host=i386-gnu
则AC_CHECK_TOOL宏先检查i386-gnu-ranlib是否存在,如果不存在,才继续检查ranlib是否存在。如果程序存在,将RANLIB变量相应地设置为i386-gnu-ranlib或ranlib。
AC_CHECK_TOOL([RANLIB], [ranlib], [:])
1.9 AC_PROG_CC 与 AC_PROG_CXX
AC_PROG_CC宏决定使用哪个C编译器。如果指定了参数,则按照参数指定的顺序检查编译器是否可用。最后将编译器名称写入变量CC。
如下的例子指定按gcc、cc的顺序进行检查。
AC_PROG_CC([gcc cc])
AC_PROG_CXX宏与AC_PROG_CC功能类似,不同的是,它决定使用哪个C++编译器,编译器名称写入变量CXX。
1.10 AC_PROG_INSTALL
AC_PROG_INTALL宏设置变量INSTALL。如果在当前PATH环境下能找到install程序,则将INSTALL设置为install,否则设置为’install-sh -c’。autoconf包中有install-sh,应该将它复制到工程中。
如下是一个例子。
AC_PROG_INSTALL
1.11 AC_SUBST
对于AC_SUBST宏, automake会在Makefile.in中生成一个输出变量,这样Makefile.am中可以使用这个变量,变量的值是它的当前值。
如下的例子生成变量HBLIBSUFFIX。
AC_SUBST(HBLIBSUFFIX)
Makefile.am可以如下使用HBLIBSUFFIX。
lib_LTLIBRARIES += libharfbuzz@HBLIBSUFFIX@.la
1.12 AC_DEFINE 和 AC_DEFINE_UNQUOTED
AC_DEFINE宏和AC_DEFINE_UNQUOTED宏,定义C预编译符号。
缺省情况下,AC_OUTPUT宏把这些符号输出到变量DEFS中,configure将它们传递给编译器;如果configure.ac中调用了AC_CONFIG_HEADERS宏,AC_OUTPUT把它们保存在头文件中,每个符号对应一个#define行。
如下AC_DEFINE的例子定义符号HAVE_VPRINTF=1。第三个参数是说明。只有调用了AC_CONFIG_HEADERS宏才有意义,它是附加在#define行后的注释。
AC_DEFINE([HAVE_VPRINTF], [1], [Define if vprintf exists.])
AC_DEFINE_UNQUOTED与AC_DEFINE不同的地方在于,它能扩展shell符号,包括$(变量展开), `(命令替换),和\ (换行消除)。
如下的例子,先展开conf变量,然后定义符号ETCFILENAME。
AC_DEFINE_UNQUOTED(ETCFILENAME, "${conf}", [MiniGUI configure file name])
1.13 AC_CHECK_HEADERS
AC_CHECK_HEADERS宏检查指定的系统头文件是否存在。
如下的例子检查系统头文件stdlib.h是否存在。
AC_CHECK_HEADERS([stdlib.h])
1.14 AC_CHECK_LIB
AC_CHECK_LIB宏检查指定库中指定的函数是否存在。如果存在,向输出变量LIBS中,加入-llib。
如下的例子检查pthread库是否存在函数pthread_rwlock_init()。
AC_CHECK_LIB([pthread], [pthread_rwlock_init])
1.15 AC_CHECK_FUNC 与 AC_CHECK_FUNCS
AC_CHECK_FUNC宏检查指定的C函数是否可用。如果可用,则定义ac_cv_func_XXX变量并且设置为yes。
如下的例子检查函数vprintf()是否可用。如果可用,则调用AC_DEFINE宏定义变量HAVE_VPRINTF=1。然后根据检查结果继续处理。如果可用(ac_cv_func_vprintf=yes),则继续检查__doprnt()是否可用。
AC_CHECK_FUNC([vprintf], [AC_DEFINE([HAVE_VPRINTF], [1], [Define if vprintf exists.])])
if test "x$ac_cv_func_vprintf" != xyes; then
AC_CHECK_FUNC([_doprnt], [AC_DEFINE([HAVE_DOPRNT], [1], [Define if _doprnt exists.])])
fi
AC_CHECK_FUNCS宏检查一组函数(名字用空白符分割)是否可用,对于每个可用的函数,定义变量HAVE_XXX。
如下的例子检查C函数time(), mktime(),和localtime()是否可用。
AC_CHECK_FUNCS(time mktime localtime)
1.16 AC_CHECK_DECL 与 AC_CHECK_DECLS
AC_CHECK_DECL宏检查指定的符号(函数、变量、或常量)是否定义。
如下的例子检查变量_MGRM_PROCESSES是否定义。如果是,则变量minigui_runmode赋值procs。
AC_CHECK_DECL(_MGRM_PROCESSES, minigui_runmode="procs")
AC_CHECK_DECLS宏检查一组符号是否定义。这组符号以逗号分隔。对于每一个符号,如果存在,则定义变量HAVE_DECL_XXX,并赋值为1, 否则赋值为0。其中XXX是符号名。
如下的例子。如果列表中的函数(如malloc)已定义,则定义变量HAVE_DECL_MALLOC=1。
AC_CHECK_DECLS([malloc, realloc, calloc, free])
1.17 AS_HELP_STRING
AS_HELP_STRING宏是用于打印"configure --help"输出中,类似如下的格式化信息。
--with-foo use foo (default is no)
AS_HELP_STRING有两个参数,对应于信息的左右两边,“–with-foo” 和 “use foo (default is no)”。如下是AS_HELP_STRING对应的例子。
AS_HELP_STRING([--with-foo], [use foo (default is no)])
1.18 AC_ARG_ENABLE
你的软件包可能有些可选的特性。执行configure时,用户可以选择使能或禁用某个特性。
configure --enable-feature=yes
使用AC_ARG_ENABLE宏可以创建一个–enable-XXX选项。四个参数依次是特性名称、提示字符串、用户指定–enable-XXX选项时的动作(yes或no),没指定选项时的动作。
如果用户指定了–enable-XXX选项,则指定的值会保存在变量enableval中。
如下的例子指定了特性debug。如果用户指定了选项,则检查enableval值,如果要求使能选项,则设置变量debug为true,否则设置为false,其他值报告错误;如果没指定选项,设置debug为false。
AC_ARG_ENABLE([debug],
[--enable-debug Turn on debugging],
[case "${enableval}" in
yes) debug = true ;;
no) debug = false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],
[debug = false])
1.19 AC_ARG_WITH
工程可能依赖第三方软件包,这个包是否存在,会导致你的软件的不同行为。执行configure时,可以允许软件的使用者指定是否使用第三方包。
configure --with-foo=yes
使用AC_ARG_WITH宏可以创建一个–with-XXX选项。宏的四个参数依次是第三方包的名称、提示字符串、用户指定–with-XXX选项时的动作(不管是yes,还是no或其他),没指定选项时的动作。
如果用户指定了–with-XXX选项,则指定的值会保存在变量withval中。
如下的例子指定了包名foo,用户指定选项时,设置use_foo变量为$withval,没指定则设置为no。注意,这里用AS_HELP_STRING宏构造了提供格式化的字符串。
AC_ARG_WITH([foo],
[AS_HELP_STRING([--with-foo], [use foo (default is no)])],
[use_foo=$withval],
[use_foo=no])
1.20 AM_CONDITIONAL
AM_CONDITIONAL宏检查指定的条件,并定义变量和赋值。这个变量是在configure运行时赋值的,比如根据用户给configure指定的参数。
下面的例子定义DEBUG变量,并根据AC_ARG_ENABLE宏定义的变量debug赋值。
AC_ARG_ENABLE([debug],
[--enable-debug Turn on debugging],
[case "${enableval}" in
yes) debug = true ;;
no) debug = false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac], [debug = false])
AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])
1.21 AC_CONFIG_FILES
AC_CONFIG_FILES宏将模板文件实例化,输出文件。它的参数是用空白符或换行符分割的一组文件名。参数中的文件是输出文件名,它假设模板文件名是输出文件名加后缀.in。
如下面的例子,从模板文件Makefile.in,生成Makefile,从src/Makefile.in生成src/Makefile。这样在Makefile.in修改后,对应的Makefile会相应得到更新。
AC_CONFIG_FILES([Makefile src/Makefile])
1.22 AC_OUTPUT
AC_OUTPUT宏产生config.status,并执行它。config.status负责产生Makefile和其他文件。
AC_OUTPUT
1.23 AC_MSG_CHECKING 与 AC_MSG_RESULT
这两个宏是配对使用的,用于检查某个系统特性。
AC_MSG_CHECKING宏打印出类似"Checking XXX …"的提示,XXX是是它的参数。AC_MSG_RESULT宏输出检查结果,如yes、no或其他内容。
如下是一个例子:
hb_os_win32=no
AC_MSG_CHECKING([for native Win32])
case "$host" in
*-*-mingw*)
hb_os_win32=yes
;;
esac
AC_MSG_RESULT([$hb_os_win32])
它的输出可能是:
Checking for native Win32 ... yes
1.24 AC_MSG_XXX
有一组宏用于打印不同级别的脚本调试信息。
AC_MSG_NOTICE:打印调试信息。
AC_MSG_WARN:打印警告信息,不终止configure运行。
AC_MSG_ERROR:打印错误信息,中止configure运行。
AC_MSG_FAILURE:打印错误信息,写入config.log
如下是AC_MSG_NOTICE宏的例子,它展开enable_doc变量,然后打印字符串。
AC_MSG_NOTICE([build configuration: documentation:${enable_doc}])
2. configure.ac的例子
如下是helloauto工程的布局。其中用[]包括的文件是用autotools生成的文件。configure.ac也可以在autoscan工具生成的configure.scan基础上修改得到。
- helloauto
├── src
│ ├── main.c
│ ├── Makefile.am
│ ├── [config.h.in]
│ └── [config.h]
├── configure.ac
├── Makefile.am
└── [configure]
使用的configure.ac如下:
# configure.ac
AC_PREREQ([2.69])
AC_INIT([helloauto], [1.0], [helloauto-bugs@example.org])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h])
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT