autoconf是一个用于生成可以自动的配置软件源代码包以适应多种UNIX系统的shell脚本的工具。由autoconf生成的配置脚本在运行时与autoconf是无关的,也就是说,配置脚本的用户并不需要拥有autoconf。由autoconf生成的这些脚本通常被命名为configure,它们检查当前系统是否满足软件正常运行所需要的特征,并根据检查得到的信息生成Makefile。对于每个使用了autoconf的软件包,autoconf从一个列举了该软件包需要的或者可以使用的系统特种的列表的模板文件中生成配置脚本。在shell代码识别并响应了一个被列出的系统特征之后,autoconf允许许多个可能使用该特征的软件包共享特征。如果后来因为某些原因需要调整shell代码,只在一个地方进行修改,所有的配置脚本都将被自动重新生成,以使用更新了的代码。为了生成配置脚本,autoconf需要宏处理工具GNU m4。
由autoconf生成的配置脚本通常被称为configure。运行时,configure会创建一些文件。在这些文件中,配置参数被适当的值所替换。由configure创建的文件有:
1、一个或多个Makefile文件,在包的每个子目录中都有一个。2、有时创建一个C语言头文件,它的名字可以被配置,该头文件包含一些宏定义语句。
3、名为config.status的shell脚本,在运行时,它将重新创建上述文件。
4、名为config.cache的shell脚本,它保存了许多测试的运行结果。
5、名为config.log的文件,它包含了由编译程序输出的许多信息,以便在configure出现错误时进行调试。
为了得到由autoconf创建的configure脚本,首先需要编写一个configure.in(该文件包含了对软件包需要或可以使用的系统特征进行测试的autoconf宏的调用)作为autoconf的输入文件。如果autoconf所提供的预定义测试不能满足要求,则需要自行编写特征测试,这时可能还需要编写一个名为aclocal.m4的文件和一个名为acsite.m4de文件。如果在软件包中使用了包含宏定义语句的C语言头文件,可能还需要编写acconfig.h,此时, autoconf会生成一个文件 config.h.in,在软件包发布时需要包含这个文件。第一次看到这里我吓了一大跳,为了得到configure脚本,需要手动编写这么多文件,这不是坑爹么!在大多数情况下,不需要在configure.in文件中手工输入复杂的宏定义,用脚本程序autoscan可以简化为软件包创建 configure.in文件的工作。autoscan又是啥玩意儿呢?autoscan是autoconf软件包提供的Perl脚本程序,它从源程序中抽取与函数调用和头文件有关的信息,并将其输出到configure.scan文件中。这个configure.scan可以作为软件包的configure.in文件的初始版本(不光需要改名,而且文件内容需要进行适当地修改哦!至于怎么改,这里暂时就不说了)。
经过上面的一番折腾,我们有了configure.in文件,下面可以开始生成自动配置脚本configure了。要生configure,只需要不带参数地运行autoconf,autoconf将使用m4宏处理器处理configure.in文件。如果提供了文件参数, autoconf将读入指定的文件而不是默认的configure.in文件,并且把配置脚本输出到文件或设备而不是configure中。
二、automake
我们知道,要使用make,必须先编写一个Makefile文件。它描述了软件包中各个文件之间的关系,提供了更新每个文件的命令。对于一个工程来说,编写Makefile文件也是一个蛮繁琐的工作,如果是一个庞大的工程,手动编写Makefile就有点坑爹了!还好有automake,automake是一个从文件Makefile.am中自动生成Makefile.in文件的工具。 每个Makefile.am文件是一系列make的宏定义又是也会包含make规则。利用automake生成的Makefile.in服从GNU Makefile标准。看到这里,可能菜鸟又要问了,这个Makefile.am文件怎么生成呢,有没有类似的命令自动生成呢。呵呵,这个还真没有,这里的Makefile.am是需我们手动编写滴,至于怎么编写Makefile.am,这里暂时不说。虽然我们需要手动编写Makefile.am,这个automake还是挺好的,大大减轻了我们的工作。这个automake这么厉害,那它是怎么做到的呢?我们一起来看看它的工作流程。automake首先读入Makefile.am文件,然后生成Makefile.in。automake根据Makefile.am中定义的宏和目标产生更多特定代码,例如一个bin_PROGRAMS宏定义将生成一个需要被编译、链接的目标。automake把Makefile.am中的宏定义和目标复制到生成的文件中。开发者可以根据需要把任何代码添加到生成的Makefile.in文件中。需要注意的是,automake不能识别GNU对make的扩展。在Makefile.am中使用这些扩展特性将导致错误或不确定行为。
呵呵,通过上面的介绍,我们对automake和autoconf有了一定的了解。下面我们通过一个C语言例子来走下整个流程。这里的例子很菜鸟,一共有三个文件,test.h、test.c和main.c。其中test.h里面声明了一个test函数,这个test函数的实现是在test.c中,然后在main.c中的main函数里面调用这个test函数。首先我们大概分析下流程,不然菜鸟不好下手啊。我们要手动使用make来编译这个C程序,但是使用make需要有Makefile文件;如果要得到Makefile文件,我们需要有自己编写一个Makefile.am,然后执行automake来生成Makefile.in;有了Makefile.in,我们只要执行configure脚本就能生成Makefile文件;根据我们前面介绍的,要想生成configure脚本,我们需要先执行autoscan生成configure.scan,然后对这个文件进行修改得到configure.in文件,接下来我们可以执行autoconf由这个configure.in文件。呵呵,这下子思路清晰多了,下面开始动手操作。
1、我把上面的三个c程序文件放到test目录下,目前目录中就只有这三个文件。
2、执行autoscan,我们会发现test目录中多了autoscan.log和configure.scan文件。
3、把生成的configure.scan修改成configure.in。首先我们先把名字改过来,然后用Ubuntu自带的gedit编辑器打开这个文件,在修改之前文件内容是这样的
下面我们修改后的文件是这样的
这里第一行是autoscan自动生成的,这个不用管它;第二行代表软件名称和版本号,这个是自己随便写的;第三行是我们加上去的,后面的automake命令需要用到它;第四行是程序源文件的目录,我们这里是当前目录;第五行这个宏
将检查系统的C编译器;第六行代表automake的输出文件名为Makefile。
4、执行aclocal和autoconf,我们发现已经生成了configure脚本。
5、编写Makefile.am
第一行是automake的选项,在执行automake时,它会检查目录下是否存在标准GNU软件包中应具备的各种文件,我们将其设置成foreign时,automake会改用一般软件包的标准来检查;第二行宏bin_PROGRAMS将导致编译和链接的目标被生成,其中test代表链接后生成的可执行文件名;第三行指定源文件,有多个源文件,需要用空格隔开。
6、有了Makefile.am后,我们就可以执行automake来生成Makefile.in文件了
执行automake时可能会报出上面的这个问题,说是找不到一些文件。仔细看我们会发现,这里报出问题的同时也提示了解决方法,根据提示我们再次执行这个命令。执行成功后我们查看目录,会发现Makefile.in文件已经生成了
7、有了Makefile.in和configure脚本就好办了,我们直接执行configure脚本,就可以由Makefile.in生成Makefile文件
这里是执行过程,完了以后我们查看目录会发现我们期待已久的Makefile终于生成了
8、至此就可以编译我们的程序了。
呵呵,执行比较顺利,没有报错。查看目录,已经生成了可执行程序test为了验证结果,我们执行下这个testOK,我们看到了程序的输出信息!!!
好啦,我这里只是粗略地介绍了下autoconf和automake。