读书人

施用Autotools编译项目(下)

发布时间: 2012-08-13 13:21:53 作者: rapoo

使用Autotools编译项目(下)
autoconf可以帮我们生成configure脚本,替换Makefile中的变量,本文讲解其简单的使用方法。

假设我们有如下代码helloworld.c:

#include <stdio.h>int main() {        printf("Hello, world!\n");}


Makefile如下:

version = 1.0 name = helloworld helloworld: helloworld.c        $(CC) -o $@ helloworld.c


便形成了一个完整的,非常简单的使用make编译的c项目。那么用autoconf的情况下面如何写呢?首先我们要将Makefile重新命令为Makefile.in,内容如下:

version = @PACKAGE_VERSION@name = @PACKAGE_NAME@helloworld: helloworld.c        $(CC) -o $@ helloworld.c


注意到Makefile.in实际上相当于Makefile的一个模版,里面的@PACKAGE_VERSION@和@PACKAGE_NAME@相当于参量,将会被autoconf定义的参量替换。

autoconf需要一个文件做为输入,叫作configure.ac。创建这个文件,内容如下:

AC_INIT([helloworld], [1.0])AC_CONFIG_FILES([Makefile])AC_OUTPUT


上面第一行AC_INIT定义了PACKAGE_NAME和PACKAGE_VERSION,第二行告诉autoconf要生成的配置文件名为Makefile,注意autoconf会自动查找 配置文件名+.in 这样的文件做为输入模版,并替换里面的参量。因此Makefile对应的模版文件就是我们手写的Makefile.in。

第三行告诉autoconf按以上配置输出相关配置文件。下面执行autoconf:

autoreconf


autoreconf实际是一串命令的集合,比执行autoconf要简单。执行完成后,生成了configure文件:

% lsconfigure


configure文件将用于生成config.status文件。执行configure:

% ./configureconfigure: creating ./config.statusconfig.status: creating Makefile


生成了config.status。注意到,实际上是config.status负责创建Makefile。看看生成的Makefile内容:

version = 1.0 name = helloworld helloworld: helloworld.c        $(CC) -o $@ helloworld.c


我们再过一遍流程:

1. configure.ac是autoconf的命令输入文件
2. 在configure.ac中,我们定义Makefile为待生成的配置文件,因此我们需要有Makefile.in做为模版,里面有要替换的变量
3. 执行autoreconf生成configure
4. configure生成config.status
5. config.status通过Makefile.in生成Makefile

从上面的流程看出什么没?可以发现其实是config.status这个文件负责将Makefile.in转成Makefile。因此,上面的流程执行过一次以后,如果想修改Makefile,只需要修改Makefile.in就可以了,而1-4步可以不必再重复,除非configure.ac需要做出改动。

因此我们可以在Makefile.in中加入用于更新Makefile自身和config.status的rule:

version = @PACKAGE_VERSION@name = @PACKAGE_NAME@helloworld: helloworld.c        $(CC) -o $@ helloworld.cMakefile: Makefile.in config.status        ./config.status $@config.status: configure        ./config.status --recheck


这样,当1-5执行过一次后,以后想更新Makefile,只需要修改完Makefile.in后,执行:

% make Makefile./config.status Makefileconfig.status: creating Makefilemake: `Makefile' is up to date.


是不是很酷?我将上面的代码放在了github里面,可以clone出来玩玩看:

git clone git://github.com/liweinan/try-make.git


代码位于try02目录。

读书人网 >开源软件

热点推荐