使用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
我们再过一遍流程:
configure.ac
是autoconf的命令输入文件- 在
configure.ac
中,我们定义Makefile为待生成的配置文件,因此我们需要有Makefile.in
做为模版,里面有待替换的变量 - 执行autoreconf生成configure
- configure生成
config.status
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目录。
- 上一篇 RxJava的几种Scheduler
- 下一篇 使用Autotools编译项目(上)