分类: LINUX
2013-12-16 20:39:26
作为 Linux 下的程序开发人员,一定都遇到过 Makefile,用 make 命令来编译自己写的程序确实是很方便。
一般情况下,大家都是手工写一个简单 Makefile,如果要想写出一个符合自由软件惯例的 Makefile 就不那么容易了。
在本文中,将介绍如何使用 autoconf 和 automake 两个工具来帮助我们自动地生成符合自由软件惯例的 Makefile,这样就可以象常见的 GNU 程序一样,只要使用“./configure”,“make”,“make instal”就可以把程序安装到 Linux 系统中去了。
这将特别适合想做开放源代码软件的程序开发人员,又或如果你只是自己写些小的 Toy 程序,那么这个文章对你也会有很大的帮助。
一、Makefile介绍
Makefile 是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但不是所有的文件都需要重新编译,Makefile 中记录有文件的信息,在 make 时会决定在链接的时候需要重新编译哪些文件。
Makefile 的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的模块。
Makefile 的基本结构不是很复杂,但当一个程序开发人员开始写 Makefile 时,经常会怀疑自己写的是否符合惯例,而且自己写的 Makefile 经常和自己的开发环境相关联,当系统环境变量或路径发生了变化后,Makefile 可能还要跟着修改。这样就造成了手工书写 Makefile 的诸多问题,automake 恰好能很好地帮助我们解决这些问题。
使用 automake,程序开发人员只需要写一些简单的含有预定义宏的文件,由 autoconf 根据一个宏文件生成configure,由 automake 根据另一个宏文件生成 Makefile.in,再使用 configure 依据 Makefile.in来生成一个符合惯例的 Makefile。
下面我们将详细介绍 Makefile 的 automake 生成方法。
二、使用的环境
本文所提到的程序是基于 Linux 发行版本:Fedora Core release 1,它包含了我们要用到的autoconf,automake。
三、从helloworld入手
我们从大家最常使用的例子程序helloworld开始。
下面的过程如果简单地说来就是:
新建三个文件: helloworld.c configure.in Makefile.am
然后执行:autoscan; aclocal; autoconf; automake --add-missing; ./configure; make; ./helloworld;
就可以看到Makefile被产生出来,而且可以将helloworld.c编译通过。
很简单吧,几条命令就可以做出一个符合惯例的Makefile,感觉如何呀。
现在开始介绍详细的过程:
1、建目录
在你的工作目录下建一个helloworld目录,我们用它来存放helloworld程序及相关文件,如在/home/my/build下:
$ mkdir helloword
$ cd helloworld
2、 helloworld.c
然后用你自己最喜欢的编辑器写一个hellowrold.c文件,如命令:vi helloworld.c。
使用下面的代码作为helloworld.c的内容。
#include
int main(int argc, char** argv)
{
printf("Hello, Linux World! ");
return 0;
}
完成后保存退出。现在在helloworld目录下就应该有一个你自己写的helloworld.c了。
3、生成configure
我们使用 autoscan 命令来帮助我们根据目录下的源代码生成一个 configure.in 的模板文件。
命令:
$ autoscan
$ ls
configure.scan helloworld.c
执行后在 hellowrold 目录下会生成一个文件:configure.scan。
4,生成configure.in
现在将configure.scan改名为configure.in,并且编辑它,按下面的内容修改,去掉无关的语句:
$ mv configure.scan configure.in
5, 执行 aclocal 和 autoconf
然后执行命令 aclocal 和 autoconf,分别会产生 aclocal.m4 及 configure 两个文件:
aclocal 根据 configure.in 文件的内容,自动生成 aclocal.m4 文件。
aclocal 是一个 perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。
autoconf 从 configure.in 这个列举编译软件时所需要各种参数的模板文件中创建 configure。
autoconf 需要 GNU m4 宏处理器来处理 aclocal.m4,生成 configure 脚本。
m4是一个宏处理器。将输入拷贝到输出,同时将宏展开。宏可以是内嵌的,也可以是用户定义的。除了可以展开宏,m4还有一些内建的函数,用来引用文件,执行命令,整数运算,文本操作,循环等。m4既可以作为编译器的前端,也可以单独作为一个宏处理器.
6、新建Makefile.am
新建Makefile.am文件,命令:$ vi Makefile.am
内容如下:
7、运行automake
命令:
8、执行 configure 生成 Makefile
你可以看到,此时Makefile已经产生出来了。
9、使用Makefile编译代码
10, 运行helloworld
$ ./helloworld
这样helloworld就编译出来了,你如果按上面的步骤来做的话,应该也会很容易地编译出正确的helloworld文件。
你还可以试着使用一些其他的 make 命令,如 make clean,make install,make dist,看看它们会给你什么样的效果。感觉如何?自己也能写出这么专业的Makefile,老板一定会对你刮目相看。
四、深入浅出
针对上面提到的各个命令,我们再做些详细的介绍。
1、 autoscan
autoscan 是用来扫描源代码目录生成 configure.scan 文件的。
autoscan 可以用目录名做为参数,但如果你不使用参数的话,那么 autoscan 将认为使用的是当前目录。
autoscan 将扫描你所指定目录中的源文件,并创建 configure.scan文件。
2、 configure.scan
configure.scan 包含了系统配置的基本选项,里面都是一些宏定义。我们需要将它改名为 configure.in
3、 aclocal
aclocal 是一个 perl 脚本程序。
aclocal 根据 configure.in 文件的内容,自动生成 aclocal.m4 文件。
aclocal的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。
4、 autoconf
使用 autoconf,根据 configure.in 和 aclocal.m4 来产生 configure 文件。
configure 是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile,从而可以使你的源代码能在不同的操作系统平台上被编译出来。
configure.in 文件的内容是一些宏,这些宏经过 autoconf 处理后会变成检查系统特性、环境变量、软件必须的参数的shell 脚本。configure.in 文件中的宏的顺序并没有规定,但是你必须在所有宏的最前面和最后面分别加上 AC_INIT 宏和AC_OUTPUT 宏。
在 configure.ini 中:
#号表示注释,这个宏后面的内容将被忽略。
AC_INIT(FILE) 这个宏用来检查源代码所在的路径。
AM_INIT_AUTOMAKE(PACKAGE, VERSION) 这个宏是必须的。
它描述了我们将要生成的软件包的名字及其版本号:PACKAGE是软件包的名字,VERSION是版本号。
当你使用 make dist 命令时,它会给你生成一个类似 helloworld-1.0.tar.gz 的软件发行包,其中就有对应的软件包的名字和版本号。
AC_PROG_CC 这个宏将检查系统所用的C编译器。
AC_OUTPUT(FILE) 这个宏是我们要输出的Makefile的名字。
我们在使用 automake 时,实际上还需要用到其他的一些宏,但我们可以用 aclocal 来帮我们自动产生。
执行 aclocal 后我们会得到 aclocal.m4 文件。
产生了 configure.in 和 aclocal.m4 两个宏文件后,我们就可以使用 autoconf 来产生 configure 文件了。
5、 Makefile.am
Makefile.am 是用来生成 Makefile.in 的,需要你手工书写。
Makefile.am 中定义了一些内容:
AUTOMAKE_OPTIONS 这个是 automake 的选项。
在执行 automake 时,它会检查目录下是否存在标准 GNU 软件包中应具备的各种文件,例如 AUTHORS、ChangeLog、NEWS 等文件。
我们将其设置成 foreign 时,automake 会改用一般软件包的标准来检查。
bin_PROGRAMS 这个是指定我们所要产生的可执行文件的文件名。
如果你要产生多个可执行文件,那么在各个名字间用空格隔开。
helloworld_SOURCES 这个是指定产生“helloworld”时所需要的源代码。
如果它用到了多个源文件,那么请使用空格符号将它们隔开。
比如需要 helloworld.h,helloworld.c 那么请写成 helloworld_SOURCES = helloworld.h helloworld.c。
如果你在 bin_PROGRAMS 定义了多个可执行文件,则对应每个可执行文件都要定义相对的 filename_SOURCES。
6、 automake
我们使用 automake,根据 configure.in 和 Makefile.am 来产生 Makefile.in。
选项 --add-missing 的定义是“add missing standard files to package”,它会让 automake 加入一个标准的软件包所必须的一些文件。
我们用 automake 产生出来的 Makefile.in 文件是符合 GNU Makefile 惯例的,接下来我们只要执行 configure 这个 shell 脚本就可以产生合适的 Makefile 文件了。
7、 Makefile
在符合 GNU Makefiel 惯例的 Makefile 中,包含了一些基本的预先定义的操作:
make 根据Makefile编译源代码,连接,生成目标文件,可执行文件。
make clean 清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。
make install