来自:http://tigersoldier.is-programmer.com/show/1904.html
autoconf和automake是啥?这要从类Unix系统的程序编译说起。
一般一个真正的工程肯定不只一个文件,而多个文件的编译是件很麻烦的事情(最简单的就是用gcc或者g 后面接着多个文件),再加上要推出跨平台的(一般只是跨不同的类Unix平台),还有啥包依赖啊什么的,很麻烦嗯。于是就有了一个工具叫make,它接收一个名为Makefile的文件作为参数,自动地进行编译,还可以在Makefile里设置接受不同的选项,然后人们就可以make install、make all什么的了。
然而confiure脚本和Makefile.in还是很难写,至少我不会写,而且看得也眼花。于是GNU推出了autoconf和automake,用于生成configure脚本和Makefile.in文件。其中autoconf是用来生成configure的,automake是用来生成Makefile.in的。
貌似说了很多废话。东西是拿来用的,不是拿来吹的,所以就拿来用吧。
首先看看autoconf怎么用。autoconf接受一个configure.ac的文件,根据里面的内容来生成configure脚本。怎么还有文件?嗯,总是要有输入的嘛,反正简单得多就是了(大型软件的configure.ac可能也挺复杂,不过总比自己写configure要来得轻松得多)。
现在一步一步来看看最简单的configure.ac里有些什么,首先是两句初始化命令:
AC_INIT(src/main.cpp)
AM_INIT_AUTOMAKE(main, 0.1)
这两句是所有configure.ac里都必须有的,AC_INIT的参数是你main函数所在的文件(包括路径),AM_INIT_AUTOMAKE指定了程序的名称和版本号。名称可以随意起,只要符合标识符规则就行。注意第二行的开头是AM而不是AC。
接下来定义程序语言,C语言用AC_PROG_CC,C 用AC_PROG_CXX,其他语言请自行搜索。
然后可以加一些其他选项了,我见过的是AC_PROG_INSTALL、PKG_CHECK_MODULES和AC_SUBST,目前对它们还没什么了解,先放一边.
如果要用到库(也就是有个目录的代码本身不是文件,是给其他目录include用的),就还要加上这么一句:
AC_PROG_RANLIB
最后指定要输出的Makefile文件,注意是每个有代码(或者有Makefile.am)的地方都要输出,不同的文件之间用空格隔开。大概类似这个样子:
AC_OUTPUT(Makefile src/Makefile)
这就是一个最简单的configure.ac文件了
再看看Makefile.am。
在你的代码所存放的地方要定义bin_PROGRAMS,如
bin_PROGRAMS = main
这个定义的就是编译好的可执行程序名。
然后就要定义程序文件,类似这个格式:
main_SOURCES = main.cpp a.h a.cpp
_SOURCES 前面的要与bin_PROGRAMS所定义的相一致,如果写的是bin_PROGRAMS = asdf,那么相应地要改为asdf_SOURCES。之后要包含该Makefile.am文件所在目录中所有的程序文件(当然,没用到的可以不包含),用空格隔开。不在这个目录下的(哪怕是在这个目录的子目录下)都不要包含进去.那么子目录下的文件怎么办?我们可以用SUBDIRS指定子目录,如:
SUBDIRS = sub abc
相邻的子目录用空格分开。SUBDIRS里指定的每个子目录中都必须要有Makefile.am(相应地在configure.ac里也要加入到AC_OUTPUT中)。要注意一点是bin_PROGRAMS定义的是一个可执行文件,也就是说之后的XXX_PROGRAMS中定义的文件必须有一个是有main函数的。要是我们的子目录中的代码不是一个独立的程序,只是拿来给其他目录的程序include的怎么办?要用noinst_LIBRARIES来将它定义为库,如
noinst_LIBRARIES = lib.a
之后和定义了bin_PROGRAMS一样定义XXX_SOURCES,例如根据上面noinst_LIBRARIES所定义的,我们可以这样来定义:
lib_a_SOURCES = a.cpp a.h
注意“.”要改成“_”,也誻lib.a在作为XXX_SOURCES的头部时变成了lib_a
最后哪里引用了这些代码,要加入相应地语句。比方说,这个目录名字为sub,在它的上层目录要引用到这些代码,那么要在它的上层目录中的Makefile.am中加入这么一句:
LDADD = sub/lib.a
来指定调用了这个目录的代码(其实我们是把sub目录下的代码编译成了一个库,库文件为lib.a,LDADD就是指定要调用哪个库)。最后,别忘了使用库时,要给configure.ac中加入AC_PROG_RANLIB. 由于Makefile.am有多个,刚才的介绍可能有点乱,下面来总结一下Makefile.am是怎么放的:
于是这两个文件大致介绍完了,当然,只是介绍了要编译一个简单程序的最基本、最通用的部分,没介绍的东西(也就是我现在还不懂的东西)多着呢。