GNU make是一个命令工具,它解释Makefile 中的指令。Makefile文件描述了整个工程所有文件的编译顺序、编译规则,Makefile有自己的书写格式、关键字、函数。Linux系统编程人员可以利用autoconf和automake自动生成一个符合惯例的Makefile。
下面就是示例说明Makefile文件自动生成过程,源文件如下:
/* common.h */ #ifndef COMMON_H #define COMMON_H int add(int, int); int sub(int, int); int mul(int, int); int div(int, int); #endif /* add.c */ #include "common.h" int add(int i, int j) { return i + j; } /* sub.c */ #include "common.h" int sub(int i, int j) { return i - j; } /* mul.c */ #include "common.h" int mul(int i, int j) { return i * j; } /* div.c */ #include "common.h" int div(int i, int j) { return i / j; } /* main.c */ #include <stdio.h> #include "common.h" int main(void) { int i = 200, j = 10; int a, s, m, d; a = add(i, j); s = sub(i, j); m = mul(i, j); d = div(i, j); printf("%d + %d = %d\n", i, j, a); printf("%d - %d = %d\n", i, j, s); printf("%d * %d = %d\n", i, j, m); printf("%d / %d = %d\n", i, j, d); return 0; }
一、autoscan命令
autoscan: 扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是configure.ac的一个雏形。
[ycxie@fedora netdev]$ ll total 24 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 add.c -rwxrwxr-x. 1 ycxie ycxie 119 May 2 15:56 common.h -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 div.c -rwxrwxr-x. 1 ycxie ycxie 320 May 2 15:56 main.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 mul.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 sub.c [ycxie@fedora netdev]$ autoscan [ycxie@fedora netdev]$ ll total 28 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 add.c -rw-rw-r--. 1 ycxie ycxie 0 May 2 16:11 autoscan.log -rwxrwxr-x. 1 ycxie ycxie 119 May 2 15:56 common.h -rw-rw-r--. 1 ycxie ycxie 465 May 2 16:11 configure.scan -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 div.c -rwxrwxr-x. 1 ycxie ycxie 320 May 2 15:56 main.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 mul.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 sub.c
二、将configure.scan文件名改为configure.ac,并修改内容
AC_PREREQ:宏声明本文件要求的autoconf版本,本例使用的版本为2.69。
AC_INIT:宏用来定义软件的名称和版本等信息,”FULL-PACKAGE-NAME”为软件包名称,”VERSION”为软件版本号,”BUG-REPORT-ADDRESS”为BUG报告地址(一般为软件作者邮件地址)。
AC_CONFIG_SRCDIR:宏用来侦测所指定的源码文件是否存在,来确定源码目录的有效性。
AC_CONFIG_HEADER:宏用于生成config.h文件,以便autoheader使用。
AC_PROG_CC:用来指定编译器,如果不指定,选用默认gcc。
AC_OUTPUT:用来设定configure所要产生的文件,如果是Makefile,configure会把它检查出来的结果带入Makefile.in文件产生合适的Makefile。使用Automake时,还需要一些其他的参数,这些额外的宏用aclocal工具产生。
[ycxie@fedora netdev]$ mv configure.scan configure.ac [ycxie@fedora netdev]$ vim configure.ac [ycxie@fedora netdev]$ cat configure.ac # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([netdev], [1.0], [admin@xieyincai.com]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADERS([config.h]) # 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])
三、aclocal命令
aclocal:根据已经安装的宏,用户定义宏和acinclude.m4文件中的宏将configure.ac文件所需要的宏集中定义到文件 aclocal.m4中。aclocal是一个perl脚本程序,它的定义是:“aclocal – create aclocal.m4 by scanning configure.ac”
[ycxie@fedora netdev]$ aclocal [ycxie@fedora netdev]$ ll total 76 -rw-rw-r--. 1 ycxie ycxie 41888 May 2 16:25 aclocal.m4 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 add.c drwxr-xr-x. 2 ycxie ycxie 4096 May 2 16:25 autom4te.cache -rw-rw-r--. 1 ycxie ycxie 0 May 2 16:11 autoscan.log -rwxrwxr-x. 1 ycxie ycxie 119 May 2 15:56 common.h -rw-rw-r--. 1 ycxie ycxie 481 May 2 16:25 configure.ac -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 div.c -rwxrwxr-x. 1 ycxie ycxie 320 May 2 15:56 main.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 mul.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 sub.c
四、autoconf命令
autoconf:将configure.ac中的宏展开,生成configure脚本。这个过程可能要用到aclocal.m4中定义的宏。
[ycxie@fedora netdev]$ autoconf [ycxie@fedora netdev]$ ll total 220 -rw-rw-r--. 1 ycxie ycxie 41888 May 2 16:25 aclocal.m4 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 add.c drwxr-xr-x. 2 ycxie ycxie 4096 May 2 16:27 autom4te.cache -rw-rw-r--. 1 ycxie ycxie 0 May 2 16:11 autoscan.log -rwxrwxr-x. 1 ycxie ycxie 119 May 2 15:56 common.h -rwxrwxr-x. 1 ycxie ycxie 145764 May 2 16:27 configure -rw-rw-r--. 1 ycxie ycxie 481 May 2 16:25 configure.ac -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 div.c -rwxrwxr-x. 1 ycxie ycxie 320 May 2 15:56 main.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 mul.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 sub.c
五、autoheader命令
autoheader生成了configure.h.in如果在configure.ac中定义了AC_CONFIG_HEADER,那么此文件就需要。
[ycxie@fedora netdev]$ autoheader [ycxie@fedora netdev]$ ll total 224 -rw-rw-r--. 1 ycxie ycxie 41888 May 2 16:25 aclocal.m4 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 add.c drwxr-xr-x. 2 ycxie ycxie 4096 May 2 16:27 autom4te.cache -rw-rw-r--. 1 ycxie ycxie 0 May 2 16:11 autoscan.log -rwxrwxr-x. 1 ycxie ycxie 119 May 2 15:56 common.h -rw-rw-r--. 1 ycxie ycxie 625 May 2 16:29 config.h.in -rwxrwxr-x. 1 ycxie ycxie 145764 May 2 16:27 configure -rw-rw-r--. 1 ycxie ycxie 481 May 2 16:25 configure.ac -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 div.c -rwxrwxr-x. 1 ycxie ycxie 320 May 2 15:56 main.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 mul.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 sub.c
六、创建Makefile.am文件
AUTOMAKE_OPTIONS:为设置Automake的选项。由于GNU对自己发布的软件有严格的规范,比如必须附带许可证声明文件COPYING等,否则Automake执行时会报错。Automake提供了3种软件等级:foreign、gnu和gnits,供用户选择,默认等级为gnu。本例使需用foreign等级,它只检测必须的文件。
bin_PROGRAMS:定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空格隔开。
netdev_SOURCES:定义“netdev”这个执行程序所需要的原始文件。如果“netdev”这个程序是由多个原始文件所产生的,则必须把它所用到的所有原始文件都列出来,并用空格隔开。
[ycxie@fedora netdev]$ vim Makefile.am [ycxie@fedora netdev]$ cat Makefile.am AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = netdev netdev_SOURCES = main.c add.c sub.c mul.c div.c common.h
七、automake命令
automake:将Makefile.am中定义的结构建立Makefile.in,然后configure脚本将生成的Makefile.in文件转换为Makefile。如果在configure.ac中定义了一些特殊的宏,比如AC_PROG_LIBTOOL,它会调用libtoolize,否则它会自己产生config.guess和config.sub。此步主要是为了生成Makefile.in,加上–add-missing参数后,会补全缺少的脚本。
[ycxie@fedora netdev]$ automake --add-missing configure.ac:11: installing './compile' configure.ac:6: installing './install-sh' configure.ac:6: installing './missing' Makefile.am: installing './depcomp' [ycxie@fedora netdev]$ ll total 256 -rw-rw-r--. 1 ycxie ycxie 41888 May 2 16:25 aclocal.m4 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 add.c drwxr-xr-x. 2 ycxie ycxie 4096 May 2 16:36 autom4te.cache -rw-rw-r--. 1 ycxie ycxie 0 May 2 16:11 autoscan.log -rwxrwxr-x. 1 ycxie ycxie 119 May 2 15:56 common.h lrwxrwxrwx. 1 ycxie ycxie 32 May 2 16:36 compile -> /usr/share/automake-1.16/compile -rw-rw-r--. 1 ycxie ycxie 625 May 2 16:29 config.h.in -rwxrwxr-x. 1 ycxie ycxie 145764 May 2 16:27 configure -rw-rw-r--. 1 ycxie ycxie 481 May 2 16:25 configure.ac lrwxrwxrwx. 1 ycxie ycxie 32 May 2 16:36 depcomp -> /usr/share/automake-1.16/depcomp -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 div.c lrwxrwxrwx. 1 ycxie ycxie 35 May 2 16:36 install-sh -> /usr/share/automake-1.16/install-sh -rwxrwxr-x. 1 ycxie ycxie 320 May 2 15:56 main.c -rw-rw-r--. 1 ycxie ycxie 107 May 2 16:35 Makefile.am -rw-rw-r--. 1 ycxie ycxie 24902 May 2 16:36 Makefile.in lrwxrwxrwx. 1 ycxie ycxie 32 May 2 16:36 missing -> /usr/share/automake-1.16/missing -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 mul.c -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 sub.c
八、执行configure生成Makefile
[ycxie@fedora netdev]$ ./configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no 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 ISO C89... none needed checking whether gcc understands -c and -o together... yes checking whether make supports the include directive... yes (GNU style) checking dependency style of gcc... gcc3 checking that generated files are newer than configure... done configure: creating ./config.status config.status: creating Makefile config.status: creating config.h config.status: executing depfiles commands [ycxie@fedora netdev]$ ll total 332 -rw-rw-r--. 1 ycxie ycxie 41888 May 2 16:25 aclocal.m4 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 add.c drwxr-xr-x. 2 ycxie ycxie 4096 May 2 16:36 autom4te.cache -rw-rw-r--. 1 ycxie ycxie 0 May 2 16:11 autoscan.log -rwxrwxr-x. 1 ycxie ycxie 119 May 2 15:56 common.h lrwxrwxrwx. 1 ycxie ycxie 32 May 2 16:36 compile -> /usr/share/automake-1.16/compile -rw-rw-r--. 1 ycxie ycxie 769 May 2 16:39 config.h -rw-rw-r--. 1 ycxie ycxie 625 May 2 16:29 config.h.in -rw-rw-r--. 1 ycxie ycxie 9170 May 2 16:39 config.log -rwxrwxr-x. 1 ycxie ycxie 32463 May 2 16:39 config.status -rwxrwxr-x. 1 ycxie ycxie 145764 May 2 16:27 configure -rw-rw-r--. 1 ycxie ycxie 481 May 2 16:25 configure.ac lrwxrwxrwx. 1 ycxie ycxie 32 May 2 16:36 depcomp -> /usr/share/automake-1.16/depcomp -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 div.c lrwxrwxrwx. 1 ycxie ycxie 35 May 2 16:36 install-sh -> /usr/share/automake-1.16/install-sh -rwxrwxr-x. 1 ycxie ycxie 320 May 2 15:56 main.c -rw-rw-r--. 1 ycxie ycxie 24502 May 2 16:39 Makefile -rw-rw-r--. 1 ycxie ycxie 107 May 2 16:35 Makefile.am -rw-rw-r--. 1 ycxie ycxie 24902 May 2 16:36 Makefile.in lrwxrwxrwx. 1 ycxie ycxie 32 May 2 16:36 missing -> /usr/share/automake-1.16/missing -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 mul.c -rw-rw-r--. 1 ycxie ycxie 23 May 2 16:39 stamp-h1 -rwxrwxr-x. 1 ycxie ycxie 62 May 2 15:56 sub.c
上面八步已经自动生成Makefile文件,至此大功告成。下面我们就来测试一下:
[ycxie@fedora netdev]$ make make all-am make[1]: Entering directory '/home/ycxie/Workspace/netdev' gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c mv -f .deps/main.Tpo .deps/main.Po gcc -DHAVE_CONFIG_H -I. -g -O2 -MT add.o -MD -MP -MF .deps/add.Tpo -c -o add.o add.c mv -f .deps/add.Tpo .deps/add.Po gcc -DHAVE_CONFIG_H -I. -g -O2 -MT sub.o -MD -MP -MF .deps/sub.Tpo -c -o sub.o sub.c mv -f .deps/sub.Tpo .deps/sub.Po gcc -DHAVE_CONFIG_H -I. -g -O2 -MT mul.o -MD -MP -MF .deps/mul.Tpo -c -o mul.o mul.c mv -f .deps/mul.Tpo .deps/mul.Po gcc -DHAVE_CONFIG_H -I. -g -O2 -MT div.o -MD -MP -MF .deps/div.Tpo -c -o div.o div.c mv -f .deps/div.Tpo .deps/div.Po gcc -g -O2 -o netdev main.o add.o sub.o mul.o div.o make[1]: Leaving directory '/home/ycxie/Workspace/netdev' [ycxie@fedora netdev]$ ./netdev 200 + 10 = 210 200 - 10 = 190 200 * 10 = 2000 200 / 10 = 20
经典,太详细了。自动生成Makefile文件成功,目测有效,感谢!