标签:
大家在下载很多自由软件的源码下来编译的时候,都要用到configure这个命令,然后make,make install等等,这里我们就浅显地介绍一下什么是autoconf:
1. 基本介绍
autoconf就是一个生成shell脚本(或者其他操作系统上的可解释脚本或程序)的程序,生成的shell脚本用来根据所在的编译环境对源码进行配置。举个很简单的例子,比如我在Linux和Mac上面编译同样一份源码,编译出的程序可能一个显示Linux版本信息,一个显示Mac的版本信息,这就是autoconf起到的作用,收集环境信息,大大方便了用户(可以想象一下,每次在系统下安装一个软件,都要自己配置系统信息,编译器版本会是一件多么麻烦的事情)。
2. Automake
介绍autoconf就必须介绍automake,作为GNU家族中不可分割的两个工具,二者大多数情况下也是相辅相成的,make所作的工具无非就是编译链接最后生成目标文件,如果你只是写一个hello world,那么用make就足矣(其实连make都不用),可以直接写一个Makefile如下:
hello:hello.c
gcc hello -o hello.c
很简单是吧,但是在一个大的C/C++工程中,会有很多模块,需要引入很多头文件,库文件等等,如果这样一个个写依赖,不仅仅效率低下,也是非常不易于管理的。因此作为make的辅助工具,autoconf应运而生,它往往起到这些作用:搜索系统中是否有工程依赖的库,如果有,路径又是什么?默认的编译器和其版本等等。
3. 生成configure脚本
configure脚本由autoconf程序生成,autoconf在源码路径下运行该程序的时候,该程序会搜索该路径下是否有configure.ac这个配置文件,还可以自己添加一个测试配置文件如aclocal.m4和acsite.m4,这些文件的具体作用可以自行Google,这里就不详细介绍。
下面的图介绍了如何生成配置文件的过程
your source filles --> [autoscan*] --> [configure.scan] --> configure configure.ac --.----× | *--------------> autoconf* ---------> configure [aclocal.m4] +-------+
| [acsite.m4] --------× * --------------> [autoheader*] -----> [config.h.in] Makefile.in
如果我们用Automake,下面的文件将会起到作用。
[acinclude.m4] ----,
|
[local macros] ---+ --> aclocal* ---> aclocal.m4
|
configure.ac ----,
configure.ac ------.
+---> automake* --> Makefile.in
Makefile.am ------,
配置软件过程中所用到的所有配置文件
*----------------> [config.cache]
configure* ----------------------+---------------->config.log
|
[config.h.in] -. V .-> [config.h] -.
+ -----> config.status* ------+ +-----> make*
Makefile.in ---, ‘-> Makefile ---
我们可以看出,最后的make只需要Makefile和config.h两个文件,那么之前的那些文件都是有什么用的呢,一个很简单的理解方式是之前的Makefile.in是Makefile的模板,configure配置之后将配置宏写到Makefile.in中就形成最后可执行的Makefile配置文件。
那么,如何编写configure.ac呢?
我们需要了解的是configure无非就是读取各种环境中的信息,autoconf已经提供了很多宏用来读取这些信息。这里插上一句,之前后缀为in的是configure程序处理的配置文件,而现在,更加推荐以ac作为后缀的命名方式。
autoconf是一个非常健壮的程序,可以兼容各种操作系统的不同,而我们不需要关心这一点,只需要用autoconf的方式来编写配置文件即可,考虑到大多数的configure环境都是在类Unix环境中,所以你可能会说,为什么不直接用shell呢,反正也是读取各种环境变量,理论上是肯定可以的,如果不用autoconf,就可以用shell进行配置信息的初始化,而实际情况是autoconf避免了我们重复造轮子,已经为我们写好了一些shell function读取环境参数,效率比写自己写shell更高,而且很少出错。其实细心的人都知道,autoconf也是将configure.ac编译成configure,用编辑器打开configure就会发现里面是shell命令。
3.1 autoconf配置语言
autoconf中都是使用各种宏命令来编写的,下面就来介绍写这些宏命令的规范:
1. 当宏命令有参数的时候,宏名称和括号中不能有空格
AC_INIT ([oops], [1,0]) # incorrect
AC_INIT([hello], [1,0]) # correct
2. 一般情况下,Macro需要用中括号,除非已知不是Macro命令可以不加中括号,看下面示例
AC_CHECK_HEADER([stdio.h],
[AC_DEFINE([HAVE_STDIO_H], [1],
[Define to 1 if you have <stdio.h>.])],
[AC_MSG_ERROR([sorry, can’t do anything for you])])
AC_CHECK_HEADER([stdio.h],
[AC_DEFINE([HAVE_STDIO_H], 1,
[Define to 1 if you have <stdio.h>.])],
[AC_MSG_ERROR([sorry, can’t do anything for you])])
因为1不可能包括宏命令,所以可以不用中括号,上面的写法是一种非常保守小心的写法,这常常会让用户比较反感,总是要加中括号,现在大多数人推崇的写法如下。
AC_CHECK_HEADER(stdio.h,
[AC_DEFINE(HAVE_STDIO_H, 1,
[Define to 1 if you have <stdio.h>.])],
[AC_MSG_ERROR([sorry, can’t do anything for you])])
我们可以看出,stdio.h和HAVE_STDIO_H没有加入中括号,但这也是比较安全的(只要你没有定义这些名字的宏,就不会被错误地解释),再给大家写一种错误危险的写法:
AC_CHECK_HEADER(stdio.h,
AC_DEFINE(HAVE_STDIO_H, 1, Define to 1 if you have .),
AC_MSG_ERROR([sorry, can’t do anything for you]))
为什么上面的写法就是错误危险的呢?因为
标签:
原文地址:http://www.cnblogs.com/RookieCoder/p/5067308.html