GNU Autotools的用法
1.介绍
大部分时候,你从网上下载了一个开放源代码的软件,在解压后,你一般会敲入以下三个命令来编译和安装你的程序:
1)./configure
2)make
3)make install
其中,configure脚本分析你的系统以找到合适的工具和库,make是真正用来编译构建软件的工具,make install来安装软件。在开放源代码世界,configure脚本获得了广泛的使用,它使从源代码安装软件变得非常容易,本文主要就是介绍如何使用GNU autotools,以便使你能够以上面这种方式来编译和安装你的程序。
2.什么是GNU autotools
GNU autotools主要包括下面三个工具:
Autoconf – 这个工具用来生成configure脚本。就像前面提到的,这个脚本主要用来分析你的系统以找到合适的工具和库。譬如:你的系统的C编译器是“cc”还是“gcc”?
Automake – 这个工具用来生成Makefiles。它需要使用到Autoconf提供的信息。譬如,如果Autoconf检测到你的系统使用“gcc”,那Makefile就使用gcc作为C编译器。反之,如果找到“cc”,那就使用“cc”。
Libtools – 这个工具创建共享库。它是平台无关的。
3.为“Hello,world”添加Autoconf
1) 创建一个“Hello,world!”
写一个简单的“Hello,world!”程序
hello.c:
#include <stdio.h>
int main(void)
{
printf ("Hello World./n");
}
写一个简单的Makefile
Makefile
EXEC:=hello
all: $(EXEC)
.PHONY:
clean
clean:
rm -f hello *.o
2) 添加Autoconf
现在,我们将添加autoconf到这个程序。首先,我们需要创建一个叫做“configure.ac”的文件。这个文件将指导Autoconf如何生成“configure”脚本。因为用手工创建这个文件非常乏味,所以Autoconf提供了一个程序来帮助你创建这个文件。这个程序就是“autoscan”.“autoscan”扫描你的源程序并创建一个相应的“configure.ac”文件。但是注意它并不是直接创建“configure.ac”,相反,它创建了一个叫做“configure.scan”的文件。所以,我们需要把它重命名为“configure.ac”.为什么“autoscan”不直接创建“configure.ac”呢?当然,现在你也许不需要自己来写“configure.ac”,但是,以后你可能会自己写。你当然不希望一不小心把“configure.ac”覆盖掉了。所以“autoscan
”不会直接写到“configure.ac”。
现在,我们可以运行“autoconf”来生成“configure”了.
也许,你现在就想输入“./configure”,但是,别急。“configure”脚本是被用来生成一个新的Makefile。但是“configure”需要一个叫做“Makefile.in”的文件来生成新的Makefile。所以,现在,我们需要一个“Makefile.in”。“Makefile.in”就是一个“Makefile”的模板,它被用来生成一个新的Makefile。所以,现在,我们只是简单的把“Makefile”改为“Makefile.in”。我们将在后面对其进行介绍:
现在,我们已经可以运行“./configure”和“make”.
虽然上面有个error,说找不到config.h.in,但是对于整个脚本的目标—生成Makefile,并没有太大影响。config.h.in,将在下面讲到。
3)总结
写代码、Makefile等
运行“autoscan”(“autoscan”创建“configure.scan”)
把“configure.scan”改为“configure.ac”
运行“autoconf”(“autoconf”使用“configure.ac”生成“configure”脚本)
把“Makefile”改为“Makefile.in”(“configure”会用“Makefile.in”来生成“Makefile”)
运行“./configure”和“make”
$ls
$hello.c Makefile
$autoscan
$mv configure.scan configure.ar
$mv Makefile Makefile.in
$autoconf
$./configure
4.让“Hello,world!”可移植
1)用“config.h”使程序可移植
要使程序可移植,我们必须修改“hello.c”,使用大量的“#ifdef”或“#ifndef”等等。但是,更普遍的做法是使用config.h.in,它里面是一些与平台或库相关的常量信息。GNU autotools同样提供了一个工具“autoheader”来帮助我们生成config.h,使用它非常简单,只要在运行“./configure”之前,运行“autoheader”,然后运行
“./configure”,就会生成“config.h”,让我们看一下“config.h”的内容,当然,这儿有些常量定义,但是没有一个是和移植有关的。这是由于我们的程序太简单了,下面,我们将让“config.h”包含一些与移植有关的常量。
2)让“hello.c”变得复杂一些
为了说明如何使用“configu.h”来使程序可移植,我们添加了“gettimeof”函数,“gettimeof”函数获得自1970.1.1(unix纪元)以来的秒数,整个程序如下所示:
首先,确认目录下只有hello.c和Makefile.in这两个文件,其余的文件用rm –fr 命令删除:
然后参照前面的方法来生成“configure”脚本和“Makefile”:
下面看一下“config.h”的部分内容:
由于有了这样一个“config.h”,我们就有了不少可用于检测移植性的宏,譬如可以检测gettimeofday()是否存在(使用Have_GETTIMEOFDAY),或检测是否存在头文件
“sys/time.h”(使用HAVE_SYS_TIME_H)等。
hello.c
#include <stdio.h>
#include <sys/time.h>
int main(void)
{
double sec;
struct timeval tv;
gettimeofday(&tv, NULL);
sec = tv.tv_sec;
sec += tv.tv_usec/1000000.0;
printf ("sec = %e", sec);
return 0;
}
3)让我们的代码变得可移植
现在,我们可以修改我们代码,使它易于移植.当然,你可以重新从“autoscan”开始再走一遍生成“configure”脚本的过程,以便发现新的移植性问题。
现在,你的程序不仅使用了“autoconf”而且是可移植的。
4)总结
在写你的代码的时候,要时刻考虑到移植性。创建“Makefile.in”
运行“autoscan”
把“configure.scan”改为“configure.ac”
运行“autoheader”
运行“autoconf”
“./configure”
查看“config.h”,如果有必要,改写你的源代码,并从第二步重新开始。
编译,“make”
5.使用Automake
1)Automaking
Automaking包含下面三步,但是你应该对第三步很熟悉了:
创建一个文件“Makefile.am”
“Automake”使用“Makefile.am”创建一个新的“Makefile.in”
“Makefile.in”被“configure”用来创建“Makefile”
下面是一个“Makefile.am”的简单的示例:
Makefile.am
bin_PROGRAMS=hello
hello_SOURCES=hello.c
这非常简单。当然,在写“Makefile.am”,还有许多命令可以使用,如果你有兴趣,可以参看GNU的“Automake”手册。
现在,我们Automake这个文件。这需要下面两步:
automake – 执行这个命令肯定会输出很多的错误。我们需要检查并修复它
aclocal – 在处理第一步的输出错误时,我们需要增加一些“Automake”的宏到“configure.ac”里,但是,“Autoconf”肯定不会认出这些新宏。我们需要一个
“aclocal.m4”文件,里面定义了这些新的宏,以便使“Autoconf”认出它们。“alocal”会为我们自动化生成这个文件。
2)修复错误
运行“automake”,会有如下输出:
首先,我们需要修改“configure.ac”,在里面加入AM_INIT_AUTOMAKE:
然后,在修改了“configure.ac”过后,我们需要运行一下aclocal,以生成“aclocal.m4”文件。
最后,在我们运行Automake的时候,它需要下面的文件:
install-sh
missing
INSTALL
NEWS
README
AUTHORS
ChangeLog
COPYING
depcomp
当“automake”使用“-a”选项运行时,它会自动生成install-sh,missing,INSTALL,COPYING和depcomp。其余的需要手工创建:
3)运行automake的结果
运行“automake”后,生成“Makefile.in”,如下所示:
然后,如前所述,运行“autoconfig”生成“configure”脚本,运行“configure”脚本生成“Makefile”。如果,你打开“Makefile”看一下,你会发现它比你自己写的要大了很多,大概有500行,功能丰富了很多,如果有兴趣,并对Makefile的编写比较了解的话,可以看一下,这对写Makefile还是很有好处的。而我们只是添加了不到3句话。从这儿也可以看出GNU autotools的强大。
4)总结
写代码,创建“Makefile.am”
运行“autoscan”
把“configure.scan”改为“configure.ac”
修改“configure.ac”,添加Automake的宏
运行“aclocal”
创建运行“automake”需要的文件
运行“automake”
运行“autoheader”
运行“autoconf”
“./configure”
查看“config.h”,如果有必要,改写你的源代码,并从第二步重新开始。
编译,“make”
1.介绍
大部分时候,你从网上下载了一个开放源代码的软件,在解压后,你一般会敲入以下三个命令来编译和安装你的程序:
1)./configure
2)make
3)make install
其中,configure脚本分析你的系统以找到合适的工具和库,make是真正用来编译构建软件的工具,make install来安装软件。在开放源代码世界,configure脚本获得了广泛的使用,它使从源代码安装软件变得非常容易,本文主要就是介绍如何使用GNU autotools,以便使你能够以上面这种方式来编译和安装你的程序。
2.什么是GNU autotools
GNU autotools主要包括下面三个工具:
Autoconf – 这个工具用来生成configure脚本。就像前面提到的,这个脚本主要用来分析你的系统以找到合适的工具和库。譬如:你的系统的C编译器是“cc”还是“gcc”?
Automake – 这个工具用来生成Makefiles。它需要使用到Autoconf提供的信息。譬如,如果Autoconf检测到你的系统使用“gcc”,那Makefile就使用gcc作为C编译器。反之,如果找到“cc”,那就使用“cc”。
Libtools – 这个工具创建共享库。它是平台无关的。
3.为“Hello,world”添加Autoconf
1) 创建一个“Hello,world!”
写一个简单的“Hello,world!”程序
hello.c:
#include <stdio.h>
int main(void)
{
printf ("Hello World./n");
}
写一个简单的Makefile
Makefile
EXEC:=hello
all: $(EXEC)
.PHONY:
clean
clean:
rm -f hello *.o
2) 添加Autoconf
现在,我们将添加autoconf到这个程序。首先,我们需要创建一个叫做“configure.ac”的文件。这个文件将指导Autoconf如何生成“configure”脚本。因为用手工创建这个文件非常乏味,所以Autoconf提供了一个程序来帮助你创建这个文件。这个程序就是“autoscan”.“autoscan”扫描你的源程序并创建一个相应的“configure.ac”文件。但是注意它并不是直接创建“configure.ac”,相反,它创建了一个叫做“configure.scan”的文件。所以,我们需要把它重命名为“configure.ac”.为什么“autoscan”不直接创建“configure.ac”呢?当然,现在你也许不需要自己来写“configure.ac”,但是,以后你可能会自己写。你当然不希望一不小心把“configure.ac”覆盖掉了。所以“autoscan
”不会直接写到“configure.ac”。
现在,我们可以运行“autoconf”来生成“configure”了.
也许,你现在就想输入“./configure”,但是,别急。“configure”脚本是被用来生成一个新的Makefile。但是“configure”需要一个叫做“Makefile.in”的文件来生成新的Makefile。所以,现在,我们需要一个“Makefile.in”。“Makefile.in”就是一个“Makefile”的模板,它被用来生成一个新的Makefile。所以,现在,我们只是简单的把“Makefile”改为“Makefile.in”。我们将在后面对其进行介绍:
现在,我们已经可以运行“./configure”和“make”.
虽然上面有个error,说找不到config.h.in,但是对于整个脚本的目标—生成Makefile,并没有太大影响。config.h.in,将在下面讲到。
3)总结
写代码、Makefile等
运行“autoscan”(“autoscan”创建“configure.scan”)
把“configure.scan”改为“configure.ac”
运行“autoconf”(“autoconf”使用“configure.ac”生成“configure”脚本)
把“Makefile”改为“Makefile.in”(“configure”会用“Makefile.in”来生成“Makefile”)
运行“./configure”和“make”
$ls
$hello.c Makefile
$autoscan
$mv configure.scan configure.ar
$mv Makefile Makefile.in
$autoconf
$./configure
4.让“Hello,world!”可移植
1)用“config.h”使程序可移植
要使程序可移植,我们必须修改“hello.c”,使用大量的“#ifdef”或“#ifndef”等等。但是,更普遍的做法是使用config.h.in,它里面是一些与平台或库相关的常量信息。GNU autotools同样提供了一个工具“autoheader”来帮助我们生成config.h,使用它非常简单,只要在运行“./configure”之前,运行“autoheader”,然后运行
“./configure”,就会生成“config.h”,让我们看一下“config.h”的内容,当然,这儿有些常量定义,但是没有一个是和移植有关的。这是由于我们的程序太简单了,下面,我们将让“config.h”包含一些与移植有关的常量。
2)让“hello.c”变得复杂一些
为了说明如何使用“configu.h”来使程序可移植,我们添加了“gettimeof”函数,“gettimeof”函数获得自1970.1.1(unix纪元)以来的秒数,整个程序如下所示:
首先,确认目录下只有hello.c和Makefile.in这两个文件,其余的文件用rm –fr 命令删除:
然后参照前面的方法来生成“configure”脚本和“Makefile”:
下面看一下“config.h”的部分内容:
由于有了这样一个“config.h”,我们就有了不少可用于检测移植性的宏,譬如可以检测gettimeofday()是否存在(使用Have_GETTIMEOFDAY),或检测是否存在头文件
“sys/time.h”(使用HAVE_SYS_TIME_H)等。
hello.c
#include <stdio.h>
#include <sys/time.h>
int main(void)
{
double sec;
struct timeval tv;
gettimeofday(&tv, NULL);
sec = tv.tv_sec;
sec += tv.tv_usec/1000000.0;
printf ("sec = %e", sec);
return 0;
}
3)让我们的代码变得可移植
现在,我们可以修改我们代码,使它易于移植.当然,你可以重新从“autoscan”开始再走一遍生成“configure”脚本的过程,以便发现新的移植性问题。
现在,你的程序不仅使用了“autoconf”而且是可移植的。
4)总结
在写你的代码的时候,要时刻考虑到移植性。创建“Makefile.in”
运行“autoscan”
把“configure.scan”改为“configure.ac”
运行“autoheader”
运行“autoconf”
“./configure”
查看“config.h”,如果有必要,改写你的源代码,并从第二步重新开始。
编译,“make”
5.使用Automake
1)Automaking
Automaking包含下面三步,但是你应该对第三步很熟悉了:
创建一个文件“Makefile.am”
“Automake”使用“Makefile.am”创建一个新的“Makefile.in”
“Makefile.in”被“configure”用来创建“Makefile”
下面是一个“Makefile.am”的简单的示例:
Makefile.am
bin_PROGRAMS=hello
hello_SOURCES=hello.c
这非常简单。当然,在写“Makefile.am”,还有许多命令可以使用,如果你有兴趣,可以参看GNU的“Automake”手册。
现在,我们Automake这个文件。这需要下面两步:
automake – 执行这个命令肯定会输出很多的错误。我们需要检查并修复它
aclocal – 在处理第一步的输出错误时,我们需要增加一些“Automake”的宏到“configure.ac”里,但是,“Autoconf”肯定不会认出这些新宏。我们需要一个
“aclocal.m4”文件,里面定义了这些新的宏,以便使“Autoconf”认出它们。“alocal”会为我们自动化生成这个文件。
2)修复错误
运行“automake”,会有如下输出:
首先,我们需要修改“configure.ac”,在里面加入AM_INIT_AUTOMAKE:
然后,在修改了“configure.ac”过后,我们需要运行一下aclocal,以生成“aclocal.m4”文件。
最后,在我们运行Automake的时候,它需要下面的文件:
install-sh
missing
INSTALL
NEWS
README
AUTHORS
ChangeLog
COPYING
depcomp
当“automake”使用“-a”选项运行时,它会自动生成install-sh,missing,INSTALL,COPYING和depcomp。其余的需要手工创建:
3)运行automake的结果
运行“automake”后,生成“Makefile.in”,如下所示:
然后,如前所述,运行“autoconfig”生成“configure”脚本,运行“configure”脚本生成“Makefile”。如果,你打开“Makefile”看一下,你会发现它比你自己写的要大了很多,大概有500行,功能丰富了很多,如果有兴趣,并对Makefile的编写比较了解的话,可以看一下,这对写Makefile还是很有好处的。而我们只是添加了不到3句话。从这儿也可以看出GNU autotools的强大。
4)总结
写代码,创建“Makefile.am”
运行“autoscan”
把“configure.scan”改为“configure.ac”
修改“configure.ac”,添加Automake的宏
运行“aclocal”
创建运行“automake”需要的文件
运行“automake”
运行“autoheader”
运行“autoconf”
“./configure”
查看“config.h”,如果有必要,改写你的源代码,并从第二步重新开始。
编译,“make”