Makefile.am -- a user input file to automake
configure.in -- a user input file to autoconf
autoconf generates configure from configure.in
automake gererates Makefile.in from Makefile.am
configure generates Makefile from Makefile.in
最近在研究开源的东西,发现有很多makefile.am,makefile.in,makefile文件,它们之间究竟是什么关系呢?能可以用什么工具生成吗?
〉GNU Automake
〉GNU Autoconf
〉GNU m4
〉perl
〉GNU Libtool
因此您的操作系统必须安装以上软件,否则就不能够自动生成Makefile文件或者在生成的过程中出现各种各样的问题。用 autoconf/automake/autoheader工具来处理各种移植性的问题,用这些工具完成系统配置信息的收集,制作Makefile文件。然后在打算编译源码时只需要通过 "./configure; make"这样简单的命令就可以得到干净利落的编译。
制作Makefile文件需要以下几步:
1〉建立编译目录和源代码目录及源代码文件(即要编译的源文件)
[root@localhost leaf]#mkdir testmk
[root@localhost leaf]#cd testmk
[root@localhost testmk]#vi hello.c
编辑hello.c文件如下内容:
/*filename:hello.c*/
#include <stdio.h>
int main(int argc,char **argv)
{
printf("%s/n","Hello, World!")
return 0;
}
2〉利用autoscan工具产生一个configure.in文件的模板文件configure.scan文件:
[root@localhost testmk]#autoscan
[root@localhost testmk]#ls
configure.scan hello.c
3〉把configure.scan文件更名为configure.in文件,并编译其内容如下:
[root@localhost testmk]#mv configure.scan configure.in
[root@localhost testmk]#vi configure.in
dnl Process this file with autoconf to produce a configure script.
AC_INIT(hello.c)
dnl Add the file by leaf
AM_INIT_AUTOMAKE(hello,1.0)
dnl Checks for programs.
AC_PROG_CC
dnl Checks for libraries.
dnl Checks for header files.
dnl Checks for typedefs, structures, and compiler characteristics.
dnl Checks for library functions.
AC_OUTPUT(Makefile)
4〉执行aclocal,会产生aclocal.m4文件
[root@localhost testmk]#aclocal
[root@localhost testmk]#ls
aclocal.m4 configure.in hello.c
5〉执行autoconf,会产生confiure文件
[root@localhost testmk]#autoconf
[root@localhost testmk]#ls
aclocal.m4 [autom4te.cache] configure configure.in hello.c
6〉创建文件Makefile.am并编辑其内容如下:
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=hello
hello_SOURCES=hello.c
其中,hello为编译后产生的可执行文件名称,而第三行等号后面为源文件列表
7〉执行automake程序,automake程序会根据Makefile.am产生一些文件,其中最重要的是Makefile.in文件:
[root@localhost testmk]#automake --add-missing
configure.in: installing `./install-sh'
configure.in: installing `./mkinstalldirs'
configure.in: installing `./missing'
Makefile.am: installing `./depcomp'
[root@localhost testmk]#ls
aclocal.m4 [autom4te.cache] configure configure.in depcomp
hello.c install-sh Makefile.am Makefile.in missing
mkinstalldirs
8〉执行configure脚本,生成我们需要的Makefile文件。
[root@localhost testmk]#./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
9〉最后只执行make就大功告成了:
[root@localhost testmk]#make
source='hello.c' object='hello.o' libtool=no /
depfile='.deps/hello.Po' tmpdepfile='.deps/hello.TPo' /
depmode=gcc3 /bin/sh ./depcomp /
gcc -DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION="" -DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DPACKAGE="hello" -DVERSION="1.0" -I. -I. -g -O2 -c `test -f 'hello.c' || echo './'`hello.c
gcc -g -O2 -o hello hello.o
备注:
1.以上内容均在RedHat Linux 9.0环境下测试通过。
2.参考书目《Linux 程序设计权威指南》于明俭、陈向阳、方汉编著
3.其它国内外网站资料
4.RedHat 9.0下带的程序文件及版本
autoconf-2.57-3.noarch.rpm
automake-1.6.3-5.noarch.rpm
gcc-3.2.2-5.i386.rpm
=================================================================================================================================
〉GNU Automake
〉GNU Autoconf
〉GNU m4
〉perl
〉GNU Libtool
因此您的操作系统必须安装以上软件,否则就不能够自动生成Makefile文件或者在生成的过程中出现各种各样的问题。用 autoconf/automake/autoheader工具来处理各种移植性的问题,用这些工具完成系统配置信息的收集,制作Makefile文件。然后在打算编译源码时只需要通过 "./configure; make"这样简单的命令就可以得到干净利落的编译。
1.autoscan (autoconf): 扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是configure.ac的一个雏形。
your source files --> [autoscan*] --> [configure.scan] --> configure.ac
2.aclocal (automake):根据已经安装的宏,用户定义宏和acinclude.m4文件中的宏将configure.ac文件所需要的宏集中定义到文件 aclocal.m4中。aclocal是一个perl 脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”
user input files optional input process output files ================ ============== ======= ============ acinclude.m4 - - - - -. V .-------, configure.ac ------------------------>|aclocal| {user macro files} ->| |------> aclocal.m4 `-------' 3.autoheader(autoconf): 根据configure.ac中的某些宏,比如cpp宏定义,运行m4,声称config.h.in user input files optional input process output files ================ ============== ======= ============ aclocal.m4 - - - - - - - . | V .----------, configure.ac ----------------------->|autoheader|----> autoconfig.h.in `----------'
4.automake: automake将Makefile.am中定义的结构建立Makefile.in,然后configure脚本将生成的Makefile.in文件转换 为Makefile。如果在configure.ac中定义了一些特殊的宏,比如AC_PROG_LIBTOOL,它会调用libtoolize,否则它 会自己产生config.guess和config.sub
user input files optional input processes output files ================ ============== ========= ============ .--------, | | - - -> COPYING | | - - -> INSTALL | |------> install-sh | |------> missing |automake|------> mkinstalldirs configure.ac ----------------------->| | Makefile.am ----------------------->| |------> Makefile.in | |------> stamp-h.in .---+ | - - -> config.guess | | | - - -> config.sub | `------+-' | | - - - -> config.guess |libtoolize| - - - -> config.sub | |--------> ltmain.sh | |--------> ltconfig `----------'
5.autoconf:将configure.ac中的宏展开,生成configure脚本。这个过程可能要用到aclocal.m4中定义的宏。
user input files optional input processes output files ================ ============== ========= ============ aclocal.m4 ,autoconfig.h.in - - - - - - -. V .--------, configure.ac ----------------------->|autoconf|------> configure
6. ./configure的过程
.-------------> [config.cache] configure* --------------------------+-------------> config.log | [config.h.in] -. v .--> [autoconfig.h] +-------> config.status* -+ Makefile.in ---' `--> Makefile
7. make过程
[autoconfig.h] -. +--> make* ---> 程序 Makefile ---'
.---------, config.site - - ->| | config.cache - - ->|configure| - - -> config.cache | +-, `-+-------' | | |----> config.status config.h.in ------->|config- |----> config.h Makefile.in ------->| .status|----> Makefile | |----> stamp-h | +--, .-+ | | | `------+--' | ltmain.sh ------->|ltconfig|-------> libtool | | | `-+------' | |config.guess| | config.sub | `------------'
.--------, Makefile ------>| | config.h ------>| make | {project sources} ---------------->| |--------> {project targets} .-+ +--, | `--------' | | libtool | | missing | | install-sh | |mkinstalldirs| `-------------'
实例:
在/hello/目录下创建一个hello.c文件,并编译运行它:
#cd /hello/
(1) 编写源文件hello.c:
#include<stdio.h>
int main(int argc, char** argv)
{
printf("Hello, GNU!n");
return 0;
}
[litao@vm0000131 hello]$ ll
total 4
-rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c
一、autoscan
[litao@vm0000131 hello]$ autoscan
autom4te: configure.ac: no such file or directory
autoscan: /usr/bin/autom4te failed with exit status: 1
[litao@vm0000131 hello]$ ll
total 8
-rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
-rw-rw-r-- 1 litao litao 457 Aug 12 12:03 configure.scan
-rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c
已经生成了configure.scan,autoscan.log文件
将configure.scan 修改为 configure.in,最后修改的内容如下:
[litao@vm0000131 hello]$ mv configure.scan configure.in
[litao@vm0000131 hello]$ vim configure.in
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([hello.c])
#AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE(hello, 1.0)
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT(Makefile)
二、acloacl
[litao@vm0000131 hello]$ aclocal
生成 aclocal.m4 和 autom4te.cache (生成aclocal.m4的过程中涉及到configure.in)
[litao@vm0000131 hello]$ ll
total 44
-rw-rw-r-- 1 litao litao 31120 Aug 12 12:08 aclocal.m4
drwxr-xr-x 2 litao litao 4096 Aug 12 12:08 autom4te.cache
-rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
-rw-rw-r-- 1 litao litao 496 Aug 12 12:08 configure.in
-rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c
三、antoconf
[litao@vm0000131 hello]$ autoconf
生成 configure (根据 configure.in, 和 aclocal.m4)
[litao@vm0000131 hello]$ ll
total 168
-rw-rw-r-- 1 litao litao 31120 Aug 12 12:08 aclocal.m4
drwxr-xr-x 2 litao litao 4096 Aug 12 12:11 autom4te.cache
-rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
-rwxrwxr-x 1 litao litao 122297 Aug 12 12:11 configure
-rw-rw-r-- 1 litao litao 496 Aug 12 12:08 configure.in
-rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c
四、编写Makefile.am:
AUTOMAKE_OPTIONS= foreign
bin_PROGRAMS= hello
hello_SOURCES= hello.c
五、automake
生成 Makefile.in, depcomp, install-sh, 和 missing (根据 Makefile.am, 和 aclocal.m4)
[litao@vm0000131 hello]$ automake
configure.in: required file `./install-sh' not found
configure.in: required file `./missing' not found
Makefile.am: required file `./depcomp' not found
[litao@vm0000131 hello]$ automake --add-missing
configure.in: installing `./install-sh'
configure.in: installing `./missing'
Makefile.am: installing `./depcomp'
[litao@vm0000131 hello]$ ll
total 192
-rw-rw-r-- 1 litao litao 31120 Aug 12 12:08 aclocal.m4
drwxr-xr-x 2 litao litao 4096 Aug 12 12:14 autom4te.cache
-rw-rw-r-- 1 litao litao 0 Aug 12 12:03 autoscan.log
-rwxrwxr-x 1 litao litao 122297 Aug 12 12:11 configure
-rw-rw-r-- 1 litao litao 496 Aug 12 12:08 configure.in
lrwxrwxrwx 1 litao litao 31 Aug 12 12:16 depcomp -> /usr/share/automake-1.9/depcomp
-rw-rw-r-- 1 litao litao 68 Aug 12 12:02 hello.c
lrwxrwxrwx 1 litao litao 34 Aug 12 12:16 install-sh -> /usr/share/automake-1.9/install-sh
-rw-rw-r-- 1 litao litao 69 Aug 12 12:15 Makefile.am
-rw-rw-r-- 1 litao litao 16561 Aug 12 12:16 Makefile.in
lrwxrwxrwx 1 litao litao 31 Aug 12 12:16 missing -> /usr/share/automake-1.9/missing
六、configure
生成 Makefile, config.log, 和 config.status
生成makefile整个过程
configure.in :
configure.in文件内容是一系列GNU m4 的宏,这些宏经autoconf处理后会变成检查系统特性的shell scripts。 configure.in 内宏的顺序并没有特别的规定,但是每一个configure.in 文件必須在所有宏前加入 AC_INIT 宏,然后在所有宏的最后加上 AC_OUTPUT宏。可先用 autoscan 扫描原始文件以产生一个 configure.scan 文件,再对 configure.scan 做些修改成 configure.in 文件。在范例中所用到的宏如下:
dnl
这个宏后面的字不会被处理,可以视为注释
AC_INIT(FILE)
该宏用来检查源代码所在路径,autoscan 会自动产生,一般无须修改它。
AM_INIT_AUTOMAKE(PACKAGE,VERSION)
这个是使用 Automake 所必备的宏,PACKAGE 是所要产生软件套件的名称,VERSION 是版本编号。
AC_PROG_CC
检查系统可用的C编译器,若源代码是用C写的就需要这个宏。
AC_OUTPUT(FILE)
设置 configure 所要产生的文件,若是Makefile ,configure 便会把它检查出来的结果带入 Makefile.in 文件后产生合适的 Makefile。
实际上,这里使用 Automake 时,还需要一些其他的宏,这些额外的宏我们用 aclocal来帮助产生。執行 aclocal会产生aclocal.m4 文件,如果无特别的用途,可以不需要修改它,用 aclocal 所产生的宏会告诉 Automake如何动作。
有了 configure.in 及 aclocal.m4两个文件以后,便可以执行 autoconf来产生 configure 文件了。
Makefile.am
Automake 会根据 configure.in 中的宏把Makefile.am 转成 Makefile.in 文件。 Makefile.am 文件定义所要产生的目标:
AUTOMAKE_OPTIONS
设置 automake 的选项。
Automake 主要是帮助开发 GNU 软件的人员来维护软件,所以在执行 automake 时,会检查目录下是否存在标准 GNU 软件中应具备的文件,例如 'NEWS'、'AUTHOR'、'ChangeLog' 等文件。设置 foreign 时,automake 会改用一般软件的标准来检查。
bin_PROGRAMS
定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空白符隔开。
hello_SOURCES
定义 'hello' 这个执行程序所需要的原始文件。如果 'hello'这个程序是由多个原始文件所产生,必須把它所用到的所有原始文件都列出来,以空白符隔开。假设 'hello' 还需要 'hello.c'、'main.c'、'hello.h' 三个文件的话,则定义
hello_SOURCES= hello.c main.c hello.h
如果定义多个执行文件,则对每个执行程序都要定义相对的filename_SOURCES。
编辑好 Makefile.am 文件,就可以用 automake --add-missing来产生 Makefile.in。加上 --add-missing 选项来告诉 automake顺便假如包装一个软件所必须的文件。Automake产生生出來的 Makefile.in 文件是完全符合 GNU Makefile 的惯例,只要执行 configure这个shell script 便可以产生合适的 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 文件的。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 --add-missing 来产生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
将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin 目录。
make dist
产生发布软件包文件(即distribution package )。这个命令将会将可执行文件及相关文件打包成一个tar.gz 压缩的文件用来作为发布软件的软件包。
它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz” 的文件。PACKAGE 和VERSION ,是我们在configure.in 中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION) 。
make distcheck
生成发布软件包并对其进行测试检查,以确定发布包的正确性。这个操作将自动把压缩包文件解开,然后执行configure 命令,并且执行make ,来确认编译不出现错误,最后提示你软件包已经准备好,可以发布了。
===============================================
helloworld-1.0.tar.gz is ready for distribution
===============================================
make distclean
类似make clean ,但同时也将configure 生成的文件全部删除掉,包括Makefile 。