使用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文件:

% ls
configure


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

% ./configure
configure: creating ./config.status
config.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.c

Makefile: Makefile.in config.status
        ./config.status $@

config.status: configure
        ./config.status --recheck


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

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


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

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


代码位于try02目录。

你可能感兴趣的:(Make,autotools)