autoconf手册(八)
2024-07-21 02:35:58
供稿:网友
我如何解开死结?
假如Autoconf需要GNU m4并且GNU m4还有一个Autoconf configure脚本,
我如何解开这个死结?它似乎是一个类似于鸡和蛋的问题!
这实际上是一种误解。虽然GNU m4带有一个由Autoconf生成的configure脚本,但在运行脚本及安装GNU m4的时候并不需要安装Autoconf。只有在你需要修改m4的configure 脚本的时候,这只是少数几个人(主要是它的维护者)必须去作的事,才需要Autoconf。
为什么不使用Imake?
为什么不用Imake来代替configure脚本?
有些人已经提出了这个问题,所以在改编之后,我把给他们的解释写在这里。
下面是对Richard Pixley的问题的回答:
由Autoconf生成的脚本经常地在它以前从未设置过的机器上工作。这就是说,它善于推断新系统的配置。而Imake不能做到。
Imake使用含有主机特定数据的通用数据库。对X11来说,这种方法具有意义是因为发布版本是由一个控制整个数据库的总管机关治理的一组工具组成的。
GNU工具并不按这种方式发行。每个GNU工具都有一个维护者;这些维护者散布在世界各地。使用统一的数据库将使维护变成噩梦。 Autoconf可能成为这类数据库,但实际上它没有。不是列举主机的依靠性,它列举的是程序的需求。
假如你把GNU套件看作一组本地工具,那么问题就很相似了。但GNU开发工具可以作为交叉工具(cross tools)而在几乎所有主机+目标机的组合中进行配置。所有的这些配置都可以同时(concurrency)安装。它们甚至可以被配置成可以在不同主机上共享与主机独立的信息的形式。Imake不能处理这些问题。
Imake模板是标准的一种形式。GNU编码标准在没有强加相同的限制的情况下,解决了相同的问题。
下面是一些由Per Bothner撰写的进一步的解释:
Imake的一个优点是它易于通过使用cpp的`#include'和宏机制生成大的Makefile。然而,cpp是不可编程的:它含有有限的条件工具,而不含有循环。而且cpp不能检查它的环境。
所有这些问题可以通过使用sh而不是cpp来解决。shell是完全可编程的、含有宏替换、可以执行(或者编制)其它的shell脚本,并且可以检查它的环境。
Paul Eggert更具体地阐述:
使用Autoconf,安装者不必假定Imake自身已经被安装并且正常地工作了。这对于习惯使用Imake的人们来说,看起来不是突出的优点。但在许多主机上,并没有安装Imake或者缺省的安装不能很好地工作,为此,要求安装Imake就阻碍了在这些主机上使用由Imake配置的软件包。例如,Imake模板和配置文件可能不能适当地安装在一个主机上,或者Imake创建过程可能会错误地假定所有的源代码文件都在一个大目录树中,或者Imake配置可能使用某个编译器而包或者安装器需要使用另一个编译器,或者包需要的Imake的版本号与系统支持的版本号不匹配。这些问题在Autoconf中很少出现,这是因为包附带属于它自己的独立配置处理器。
还有,Imake通常会在make和安装者的C预处理器之间碰到难以预期的影响。这里的基本问题是,C预处理器是为处理C程序而不是`Makefile'而设计的。这对Autoconf来说问题小得多,它使用通用目的预处理器m4,并且包的作者(而不是安装者)以标准的方式进行预处理。
最后,Mark Eichin解释道:
Imake还不是完全可扩展的。为了把新特征添加到Imake中,你需要提供你自己的项目模板,并且复制已经存在的特征的主要部分。这意味着对于复杂的项目来说,使用由买主提供的(vendor-PRovided)Imake模板不能提供任何平衡作用--这是因为它们不包括你自己的项目的任何东西(除非它是一个X11程序)。
但是,另一方面:
一个Imake胜过configure的优点是: `Imakefile'总是趋向于比`Makefile.in'简短(同样地,冗余较少)。但是,这儿有一个修正的方法--至少对于Kerberos V5树来说,我们已经在整个树中进行了修改以调用通用的 `post.in'和`pre.in' `Makefile'片断。这意味着大部分通用的东西,即使它们通常是在configure中设置的,也不必复制。
从版本1中升级
Autoconf第2版基本上与第1版是向后兼容的。但是,它给出了作某些事的更好方法,并且不再支持版本1中一些丑陋的东西。因此,根据你的`configure.in'文件的复杂性,你可能必须作一些手工的工作以升级到版本2。本章指出了一些在升级的时候需要注重的问题。还有,可能你的configure脚本可以从版本2中的新特征中获得一些好处;在Autoconf发布包中的`NEWS'文件概括了改变的部分。
首先,确认你安装了1.1版或者更高版本的GNU m4,最好是1.3版或者更高版本。在1.1版之前的版本含有bug 以至于它不能与Autoconf版本2一同工作。版本1.3及其后的版本比早期的版本更快一些,这是因为1.3版的GNU m4 对转换(diversions)进行了更有效的实现并且能够在可以快速读回的文件中冻结(freeze)它的内部状态。
改变了的文件名
假如你随Autoconf一起安装了`aclocal.m4'(相对于特定软件包的源代码目录中的`aclocal.m4'),你必须把它重命名为`acsite.m4'。参见用autoconf创建configure。
假如你与你的软件包一同发布`install.sh',就把它重命名为`install-sh'以便make的内置规则不会无意地从该文件创建一个称为`install'的文件。
AC_PROG_INSTALL将寻找这两个名字的脚本,但最好使用新名字。
假如你使用`config.h.top'或者`config.h.bot',你仍然可以使用它们,但假如你把它们混合到 `acconfig.h'之中,将减少你的麻烦。参见用autoheader创建`config.h.in'。
改变了的Makefile
在你的`Makefile.in'文件中添加`@CFLAGS@'、`@CPPFLAGS@'和`@LDFLAGS@',以便它们可以在configure运行的时候利用环境中的这些变量的值。这样做不是必须的,但对用户来说比较方便。
对于AC_OUTPUT的每个非`Makefile'的输入文件,你还应该添加一条含有 `@configure_input@'的注释,以便输出文件将会包含一条注释以说明它们是由configure生成的。自动地为每种人们在AC_OUTPUT中输出的文件选择正确的注释语法需要做太多的工作。
把`config.log'和`config.cache'添加到你要在distclean目标中删除的文件的列表中。
假如你的`Makefile.in'如下:
prefix = /usr/local
exec_prefix = ${prefix}
你必须把它修改成:
prefix = @prefix@
exec_prefix = @exec_prefix@
不使用`@'字符的老式的对这些变量的替换行为已经被删除了。
改变了的宏
在Autoconf第2版中,重新命名了许多宏。你仍然可以使用旧名字,但新名字更清楚,并且易于找到相关文档。关于为旧宏名提供新宏名的列表,参见陈旧的宏名。用autoupdate程序转换你的`configure.in'以使用新的宏名。参见用autoupdate更新configure。
有些宏已经被能够更好地完成工作的类似宏所代替,但在调用上并不兼容。假如你在运行autoconf时受到了关于调用过时宏的警告,你可以安全地忽略它们,但假如你按照打印的建议替换过时的宏,你的configure脚本通常可以工作的更好。非凡地,报告测试结果的机制已经改变了。假如你使用了echo或者AC_VERBOSE(可能是通过AC_COMPILE_CHECK),假如你改用AC_MSG_CHECKING和AC_MSG_RESULT,你的configure脚本的输出将更加美观。参见打印消息。这些宏能够更好地与缓存变量协同工作。参见缓存结果。
用autoupdate更新configure
程序autoupdate把使用Autoconf旧宏名的`configure.in'文件更新为使用当前宏名的文件。在Autoconf第2版中,大部分宏被重命名以使用一个更统一、更具有描述性的命名机制。关于对新的命名机制的描述,参见宏名。虽然旧宏名仍然可以工作(关于旧宏名和对应的新宏名的列表,参见陈旧的宏名),假如你更新它们以使用新的宏名,你可以使你的 `configure.in'文件更加可读并且易于使用当前的Autoconf文档。
假如没有给出参数,autoupdate就更新`configure.in',并且通过添加后缀`~' (或者在设置了环境变量SIMPLE_BACKUP_SUFFIX的时候,使用该环境变量的值)以备份原始版本。假如你带参数调用autoupdate,它就读入那个文件而不是读入`configure.in',并且把更新的文件输出到标准输出。
autoupdate接受下列选项:
--help
-h
打印命令行选项的概述并且退出。
--macrodir=dir
-m dir
在目录dir中,而不是在缺省安装目录中寻找Autoconf宏文件。你还可以把环境变量AC_MACRODIR设置成一个目录;本选项覆盖该环境变量。
--version
打印autoupdate的版本号并且退出。
改变了的结果
假如你通过检验shell变量DEFS来检验以前测试的结果,你需要把这些检验替换为对那些测试的缓存变量的检查。在configure运行的时候,DEFS不再存在;它仅仅在生成输出文件的时候才被创建。这种与第1版的不同是因为正确地对变量实行引用(quoting)实在太麻烦而且在每次调用AC_DEFINE都要实行引用是低效的。参见缓存变量名。
例如,下面是为Autoconf第1版编写的`configure.in'的片断:
AC_HAVE_FUNCS(syslog)
case "$DEFS" in
*-DHAVE_SYSLOG*) ;;
*) # syslog is not in the default libraries.See if it's in some other.
saved_LIBS="$LIBS"
for lib in bsd socket inet; do
AC_CHECKING(for syslog in -l$lib)
LIBS="$saved_LIBS -l$lib"
AC_HAVE_FUNCS(syslog)
case "$DEFS" in
*-DHAVE_SYSLOG*) brea