编写configure.ac
发布日期:2021-05-07 21:03:44 浏览次数:29 分类:精选文章

本文共 8552 字,大约阅读时间需要 28 分钟。

一、configure.ac

configure.ac由一些宏组成(如果已经有源代码,你可以运行autoscan *来产生一个configure.scan文件,在此基础修改成configure.ac将更加方便)

1) 示列

AC_PREREQ(2.61)AC_INIT([amhello], [1.0], [bug-automake@gnu.org])AM_INIT_AUTOMAKE([-Wall -Werror foreign])AC_PROG_CCAC_CONFIG_HEADERS([config.h])AC_CONFIG_FILES([ Makefile src/Makefile])AC_OUTPUT

2)可能出现的配置

2.1 AC_PREREQ(VERSION)

指示使用的autoconf的版本。

2.2 AC_INIT(PACKAGE, VERSION, BUG-REPORT-ADDRESS)

autoconf 强制性初始化。告诉autoconf包名称,版本,一个bug报告emall。

例如:

AC_INIT([hello], [1.0], [bug-report@address])

并且这些名称将出现在config.h,你可以在程序直接引用这些宏。

/* config.h.  Generated from config.h.in by configure.  *//* config.h.in.  Generated from configure.ac by autoheader.  *//* Name of package */#define PACKAGE "amhello"/* Define to the address where bug reports for this package should be sent. */#define PACKAGE_BUGREPORT "bug-automake@gnu.org"/* Define to the full name of this package. */#define PACKAGE_NAME "amhello"/* Define to the full name and version of this package. */#define PACKAGE_STRING "amhello 1.0"/* Define to the one symbol short name of this package. */#define PACKAGE_TARNAME "amhello"/* Define to the home page for this package. */#define PACKAGE_URL ""/* Define to the version of this package. */#define PACKAGE_VERSION "1.0"/* Version number of package */#define VERSION "1.0"

2.3 AM_INIT_AUTOMAKE([OPTIONS…])

检查automake尝试Makefile时的必要的工具。 例如:AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])

一些可选的选项:

选项 解释
-Wall 打开全部警告
-Werror 将警告当错误处理
-foreign 放宽一些GNU标准需求
-1.11.1 需要automake的最低版本
-dist-bzip2 在使用make dist和make distcheck期间同时创建tar.bz2存档
-tar-ustar 使用ustar格式创建tar存档

2.4 AC_CONFIG_SRCDIR(FILE)

一个安全的检查。FILE将是一个发布的源文件。这让configure脚本确保自己运行在正确的目录中。如:AC_CONFIG_SRCDIR([src/main.c])

2.5 AC_CONFIG_AUX_DIR(DIRECTORY)

配置辅助脚本位置,如install-sh和depcomp等。如:AC_CONFIG_AUX_DIR([build-aux])

2.6 AC_PROG_CC, AC_PROG_CXX, AC_PROG_F77, …

编译器检测。

2.7 AC_PROG_SED, AC_PROG_YACC, AC_PROG_LEX, …

发现好的实现并且设置变量SED,YACC,$LEX等。

2.8 AC_CHECK_PROGS(VAR, PROGS, [VAL-IF-NOT-FOUND])

将VAR定义为第一个发现的程序,如果没有发现就设置为VAL-IF-NOT-FOUND

AC_CHECK_PROGS([TAR], [tar gtar], [:])if test "$TAR" = :; thenAC_MSG_ERROR([This package needs tar.])fi

如果发现tar,gtar,就设置到变量$TAR中,如果没有发现就是设置为‘:’

2.9 AC_MSG_ERROR(ERROR-DESCRIPTION, [EXIT-STATUS])

打印错误信息ERROR-DESCRIPTION并退出,EXIT-STATUS设置退出状态。

2.10 AC_MSG_WARN(ERROR-DESCRIPTION)

打印但是不退出。

2.11 AC_DEFINE(VARIABLE, VALUE, DESCRIPTION)

输出到configu.h中。

/* DESCRIPTION */#define VARIABLE VALUE

2.12 AC_SUBST(VARIABLE, [VALUE])

定义变量$VARIABLE=VALUE,进入Makefile。

如:AC_SUBST([FOO],[foo])
等价于
FOO=foo
AC_SUBST([FOO])
或者
AC_SUBST([FOO])
FOO=foo

2.13 AC_CHECK_LIB(LIBRARY, FUNCT, [ACT-IF-FOUND], [ACT-IF-NOT])

检查库是否存在并且包括函数FUNCT。如果发现库就执行ACT-IF-FOUND,否则执行ACT-IF-NOT。

例如:

AC_CHECK_LIB([efence], [malloc], [EFENCELIB=-lefence])AC_SUBST([EFENCELIB])

稍后可以使用(EFENCELIB)在链接规则中。如果没有使用ACT−IF−FOUND项,并且库被发现存在。ACCHECKLIB将会做下面的操作,LIBS=”−lLIBRARY(EFENCELIB)在链接规则中。如果没有使用ACT−IF−FOUND项,并且库被发现存在。ACCHECKLIB将会做下面的操作,LIBS=”−lLIBRARYLIBS"和#dedefine HAVE_LIB{LIBRARY}。Autmake会在链接的时候使用$LIBS。

2.14 AC_CHECK_HEADERS(HEADERS…)

检查头HEADERS并且给每一个发现的头文件定义#define HAVE_HEADER_H

例如:

AC_CHECK_HEADERS([unistd.h windows.h])

这个宏将在当前建造环境下检查unistd.h,windows.h是否存在。并将两个参数写入到配置头文件中。一般是config.h,你可以使用AC_CONFIG_HEADERS([headers])来指定。

AC_CONFIG_HEADERS([config.h])

如果存在就会出现在config.h中例如下面:

/* Define to 1 if you have the 
header file. */#define HAVE_UNISTD_H 1/* Define to 1 if you have the
header file. */#define HAVE_WINDOWS_H 1

2.15 AC_CHECK_HEADER(HEADER, [ACT-IF-FOUND], [ACT-IF-NOT])

检查一个头文件。

2.16 AC_CONFIG_HEADERS(HEADERS…)

创建头文件的HEADER.in,HEADERS包含使用AC_DEFINE的定义。

例如:
AC_CONFIG_HEADERS([config.h])
将从config.h.in创建config.h。

2.17 AC_CONFIG_FILES([Makefile sub/Makefile script.sh:script.in])

Automake创建FILE.in从每一个有FILE.am的FILE。他也可以出来非Makefile。

script.in

#!/bin/shSED='@SED@'TAR='@TAR@'d=$1; shift; mkdir "$d"for f; do"$SED" 's/#.*//' "$f" \>"$d/$f"done"$TAR" cf "$d.tar" "$d"

.in是文件模板。@SED@、@TAR@将被AC_SUBST([SED]),AC_SUBST([TAR])替换。这样你就可以将配置中的变量传送到其他文件中去。

Makefile.in也使用@XYZ@作为替换部分,但是Automake已经做了将所有的XYZ=@XYZ@的定义,你只需要简单使用$(XYZ)就可以了。

2.18 AC_CONFIG_FILES([Makefile sub/Makefile])

写入Makefile.am和sub/Makefile.am文件

2.19 AM CONDITIONAL(NAME, CONDITION)

定义一个条件名NAME,CONDITION将由shell解释执行,如果成功NAME将被打开。

举例:configure.ac

AC_CHECK_HEADER([bar.h], [use_bar=yes])AM_CONDITIONAL([WANT_BAR], [test "$use_bar" = yes])

仅当当前系统中存在bar.h文件时打开WANT_BAR。

2.20 AC_CHECK_FUNC (function, [action-if-found], [action-if-not-found])

AC_CHECK_FUNCS (function…, [action-if-found], [action-if-not-found])

检查函数是否存在,如果存在执行动作action-if-found,没有发现执行动作action-if-not-found。

如果你没给出action-if-found和action-if-not-found,在发现函数的时候回定义对应的变量,以HAVE_开头,函数的名称都转换成大写。例如:

AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork)

如果发现clock_gettime将会定义变量#define HAVE_CLOCK_GETTIME 1在对应的配置头文件中。

如果没发现将不会定义。但是也会有一个注释行/* #undef HAVE_CLOCK_GETTIME */

2.21 AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])

这个宏可以给configure增加–with-package这样模式的参数。很多软件都有可选项用来打开扩展功能,AC_ARG_WITH就是干这个的。它的第一参数给出扩展包的名称,出现在–with-后面。第二个参数给出一个参数说明,用在./configure –help中。[action-if-given]如果有该选项就被执行,[action-if-not-given]如果没有加这个选项就执行。

例如:

AC_ARG_WITH([militant],    [AS_HELP_STRING([--with-militant],        [Enable militant API assertions])],    [zmq_militant="yes"],    [])if test "x$zmq_militant" = "xyes"; then    AC_DEFINE(ZMQ_ACT_MILITANT, 1, [Enable militant API assertions])fi

AS_HELP_STRING([–with-militant],

[Enable militant API assertions])
定义一个帮助字串,将在configure –help中被显示出来。
它可以这么使用configure –width-militant,这导致zmq_militant=”yes”被执行,随后通过测试来定义一个变量ZMQ_ACT_MILITANT=1。

2.22 AC_DEFINE(VARIABLE, VALUE, DESCRIPTION)

这个宏会在AC_CONFIG_HEADERS定义的头文件中增加一个定义项。例如:

/* DESCRIPTION */#define VARIABLE VALUE

另外使用AC_ARG_ENABLE宏可以为configure增加–enable-feature 或者 –disable-feature这样的选项。

2.23 AC_ARG_ENABLE (feature, help-string, [action-if-given], [action-if-not-given])

如果configure中加了给定的选项,就执行action-if-given,否则执行action-if-not-given。

例如:

AC_ARG_ENABLE([eventfd],    [AS_HELP_STRING([--disable-eventfd], [disable eventfd [default=no]])],    [zmq_enable_eventfd=$enableval],    [zmq_enable_eventfd=yes])if test "x$zmq_enable_eventfd" = "xyes"; then    # Check if we have eventfd.h header file.    AC_CHECK_HEADERS(sys/eventfd.h,        [AC_DEFINE(ZMQ_HAVE_EVENTFD, 1, [Have eventfd extension.])])fi

2.24 共享库和静态库

编译动态库或者静态库,你需要再你的configure.ac中加入下面的宏:

LT_PREREQ([2.4.0])LT_INIT([disable-static win32-dll dlopen])AC_PROG_LIBTOOL

LT_PREREQ给出一个版本需求检查。LT_INIT可以实现一些配置,例如win32-dll允许建造动态库,disable-static默认关闭静态库的建造。默认动态库和静态库是同时打开的。

AC_PROG_LIBTOOL检查libtool脚本。做完这些在你的configure中会增加一些选项–enable-static , –enable-shared。
细节参数可以看:

2.25 AC_RUN_IFELSE (input, [action-if-true], [action-if-false], [action-if-cross-compiling = ‘AC_MSG_FAILURE’])

编译运行input程序,如果程序成功运行返回0,执行action-if-true,否则执行action-if-false。如果交叉编译打开,那么编译出来的代码不能在本机执行,这时其他的动作都不会执行,如果action-if-cross-compiling存在将被执行。

另外这里的input必须是有一个宏指定的源代码。 AC_LANG_PROGRAM (prologue, body)
例如:

[AC_LANG_PROGRAM([[const char hw[] = "Hello, World\n";]],                      [[fputs (hw, stdout);]])])

将被展开为下面的代码:

#define PACKAGE_NAME "Hello"#define PACKAGE_TARNAME "hello"#define PACKAGE_VERSION "1.0"#define PACKAGE_STRING "Hello 1.0"#define PACKAGE_BUGREPORT "bug-hello@example.org"#define PACKAGE_URL "http://www.example.org/"#define HELLO_WORLD "Hello, World\n"const char hw[] = "Hello, World\n";intmain (){   fputs (hw, stdout);  ;  return 0;}

下面看一个完整的例子:

AC_MSG_CHECKING([if TIPC is available and supports nonblocking connect])AC_RUN_IFELSE(    [AC_LANG_PROGRAM([[            #include 
#include
#include
#include
#include
#include
]],[[ struct sockaddr_tipc topsrv; int sd = socket(AF_TIPC, SOCK_SEQPACKET, 0); if (sd == -EAFNOSUPPORT) { return 1; } memset(&topsrv, 0, sizeof(topsrv)); topsrv.family = AF_TIPC; topsrv.addrtype = TIPC_ADDR_NAME; topsrv.addr.name.name.type = TIPC_TOP_SRV; topsrv.addr.name.name.instance = TIPC_TOP_SRV; fcntl(sd, F_SETFL, O_NONBLOCK); if (connect(sd, (struct sockaddr *)&topsrv, sizeof(topsrv)) != 0) { if (errno != EINPROGRESS) return -1; } ]]) ], [libzmq_tipc_support=yes], [libzmq_tipc_support=no], [libzmq_tipc_support=no])AC_MSG_RESULT([$libzmq_tipc_support])

AC_MSG_CHECKING和AC_MSG_RESULT共同显示一个检查信息。这些信息将显示在执行configure脚本时。

上面的宏在编译执行完给定代码后,如何成功就执行libzmq_tipc_support=yes,这同样导致configure打印一个信息if TIPC is available and supports nonblocking connect : yes
下面你可以使用libzmq_tipc_support来定义一个宏到头文件中。

if test "x$libzmq_tipc_support" = "xyes"; then    AC_DEFINE(ZMQ_HAVE_TIPC, 1, [Have TIPC support])fi
上一篇:变量在configure.ac,makefile.am,makefile,config.h中的传递
下一篇:编写Makefile.am

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2025年03月23日 21时09分36秒