GNU Autotools的使用方法

       手工写Makefile是一件很有趣的事情,对于比较大型的项目,如果有工具可以代劳,自然是一件好事。在Linux系统开发环境中,GNU Autotools 无疑就充当了这个重要角色。(在Windows系统的开发环境中,IDE工具,诸如Visual Studio,来管理项目也很方便。)

      本文以一个简单项目为例子,来讲述GNU Autotools的一列工具及其命令的用法。

autotools是系列工具, 它主要由autoconf、automake、perl语言环境和m4等组成;所包含的命令有五个:
    (1)aclocal
    (2)autoscan
    (3)autoconf
    (4)autoheader
    (5)automake

 

一、准备源代码

(1)目录project包含一个main.c的文件和两个子目录lib与include;lib目录中包含一个test.c,include目录中包含一个test.h。在系统中,显示如下:

[c-sharp] view plain copy
  1. [root@localhost project]# ls  
  2. include  lib  main.c  
  3. [root@localhost project]#  
  4. [root@localhost project]# ls include/  
  5. test.h  
  6. [root@localhost project]# ls lib/  
  7. test.c  
  8. [root@localhost project]#  

 

(2)源代码如下:

 

[cpp] view plain copy
  1. /* project/main.c */  
  2. #include <stdio.h>  
  3. #include "include/test.h"  
  4. int main()  
  5. {  
  6.     printf("main entrance./n");  
  7.     test_method();  
  8.     return 0;  
  9. }  

 

[c-sharp] view plain copy
  1. /* project/lib/test.c */  
  2. #include <stdio.h>  
  3. #include "../include/test.h"  
  4. void test_method()  
  5. {  
  6.     printf("test method./n");  
  7. }  
[cpp] view plain copy
  1. /* project/include/test.h*/  
  2. void test_method();  

 

二、autotools 使用步骤

     2.1 使用autoscan命令,它将扫描工作目录,生成 configure.scan 文件。    

[c-sharp] view plain copy
  1. [root@localhost project]# autoscan  
  2. autom4te: configure.ac: no such file or directory  
  3. autoscan: /usr/bin/autom4te failed with exit status: 1  
  4. [root@localhost project]# ls  
  5. autoscan.log  configure.scan  include  lib  main.c  
  6. [root@localhost project]#  

      2.2 将configure.scan 文件重命名为configure.ac,并做适当的修改。在 configure.ac 中,# 号开始的行是注释,其他都是m4 宏命令;configure.ac里面的宏的主要作用是侦测系统。

 

[c-sharp] view plain copy
  1. [root@localhost project]mv configure.scan configure.ac  
  2. [root@localhost project]# ls  
  3. autoscan.log  configure.ac include  lib  main.c  
  4. [root@localhost project]#  
  5. [root@localhost project]# cat configure.ac  
  6. #                                               -*- Autoconf -*-  
  7. # Process this file with autoconf to produce a configure script.  
  8. AC_PREREQ(2.59)  
  9. AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)  
  10. AC_CONFIG_SRCDIR([main.c])  
  11. AC_CONFIG_HEADER([config.h])  
  12. # Checks for programs.  
  13. AC_PROG_CC  
  14. # Checks for libraries.  
  15. # Checks for header files.  
  16. # Checks for typedefs, structures, and compiler characteristics.  
  17. # Checks for library functions.  
  18. AC_OUTPUT  
  19. [root@localhost project]#  

 

     2.3 对 configure.ac 文件做适当的修改,修改显示如下[1]:

[c-sharp] view plain copy
  1. [root@localhost project]# cat configure.ac  
  2. #                                               -*- Autoconf -*-  
  3. # Process this file with autoconf to produce a configure script.  
  4. AC_PREREQ(2.59)  
  5. #AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)  
  6. AC_INIT(hello,1.0,[email protected])  
  7. AM_INIT_AUTOMAKE(hello,1.0)  
  8. AC_CONFIG_SRCDIR([main.c])  
  9. AC_CONFIG_HEADER([config.h])  
  10. # Checks for programs.  
  11. AC_PROG_CC  
  12. # Checks for libraries.  
  13. # Checks for header files.  
  14. # Checks for typedefs, structures, and compiler characteristics.  
  15. # Checks for library functions.  
  16. AC_CONFIG_FILES([Makefile])  
  17. AC_OUTPUT  

说明:

(1)以“#”号开始的行均为注释行。
(2)AC_PREREQ 宏声明本文要求的 autoconf 版本, 如本例中的版本 2.59。

(3)AC_INIT 宏用来定义软件的名称、版本等信息、作者的E-mail等。
(4)AM_INIT_AUTOMAKE是通过手动添加的, 它是automake所必备的宏, FULL-PACKAGE-NAME是软件名称,VERSION是软件版本号。
(5)AC_CONFIG_SCRDIR 宏用来侦测所指定的源码文件是否存在, 来确定源码目录的有效性.。此处为当前目录下main.c。

(6)AC_CONFIG_HEADER 宏用于生成config.h文件,以便 autoheader 命令使用。
(7)AC_PROG_CC用来指定编译器,如果不指定,默认gcc。
(8)AC_OUTPUT 用来设定 configure 所要产生的文件,如果是makefile,configure 会把它检查出来的结果带入makefile.in文件产生合适的makefile。使用 Automake 时,还需要一些其他的参数,这些额外的宏用aclocal工具产生。
(9)AC_CONFIG_FILES宏用于生成相应的Makefile文件。

 

2.4  使用 aclocal 命令,扫描 configure.ac 文件生成 aclocal.m4文件, 该文件主要处理本地的宏定义,它根据已经安装的宏、用户定义宏和 acinclude.m4 文件中的宏将 configure.ac 文件需要的宏集中定义到文件 aclocal.m4 中。[2]

 

[c-sharp] view plain copy
  1. [root@localhost project]# aclocal  
  2. [root@localhost project]# ls  
  3. aclocal.m4  autom4te.cache  autoscan.log  configure.in  include  lib  main.c  
  4. [root@localhost project]#  


2.5 使用 autoconf 命令生成 configure 文件。这个命令将 configure.ac 文件中的宏展开,生成 configure 脚本。这个过程可能要用到aclocal.m4中定义的宏。

[c-sharp] view plain copy
  1. [root@localhost project]# autoconf  
  2. [root@localhost project]# ls  
  3. aclocal.m4  autom4te.cache  autoscan.log  configure  configure.in  include  lib  main.c  

2.6 使用 autoheader 命令生成 config.h.in 文件。该命令通常会从 "acconfig.h” 文件中复制用户附加的符号定义。该例子中没有附加的符号定义, 所以不需要创建 "acconfig.h” 文件[2].

[cpp] view plain copy
  1. [root@localhost project]# autoheader  
  2. [root@localhost project]# ls  
  3. aclocal.m4  autom4te.cache  autoscan.log  config.h.in  configure  configure.in  include  lib  main.c  
  4. [root@localhost project]#  

2.7 手工创建Makefile.am文件。Automake工具会根据 configure.in 中的参量把 Makefile.am 转换成 Makefile.in 文件。

[cpp] view plain copy
  1. [root@localhost project]# cat Makefile.am  
  2. UTOMAKE_OPTIONS = foreign  
  3. bin_PROGRAMS = hello  
  4. hello_SOURCES = main.c include/test.h lib/test.c  

说明:

(1)其中的AUTOMAKE_OPTIONS为设置automake的选项. 由于GNU对自己发布的软件有严格的规范, 比如必须附带许可证声明文件COPYING等,否则automake执行时会报错. automake提供了3中软件等级:foreign, gnu和gnits, 供用户选择。默认级别是gnu. 在本例中, 使用了foreign等级, 它只检测必须的文件。

(2)bin_PROGRAMS定义要产生的执行文件名. 如果要产生多个执行文件, 每个文件名用空格隔开。
(3)hello_SOURCES 定义”hello”这个可执行程序所需的原始文件。如果”hello”这个程序是由多个源文件所产生的, 则必须把它所用到的所有源文件都列出来,并用空格隔开。如果要定义多个可执行程序,那么需要对每个可执行程序建立对应的file_SOURCES。

 

2.8 使用 Automake  命令生成 Makefile.in 文件。使用选项 "--add-missing" 可以让 Automake 自动添加一些必需的脚本文件。

 

[cpp] view plain copy
  1. [root@localhost project]# automake --add-missing  
  2. configure.ac: installing `./install-sh'  
  3. configure.ac: installing `./missing'  
  4. Makefile.am: installing `./INSTALL'  
  5. Makefile.am: required file `./NEWS' not found  
  6. Makefile.am: required file `./README' not found  
  7. Makefile.am: required file `./AUTHORS' not found  
  8. Makefile.am: required file `./ChangeLog' not found  
  9. Makefile.am: installing `./COPYING'  
  10. Makefile.am: installing `./depcomp'  
  11. [root@localhost project]#  

 2.8.1 再次使用 automake ——add-missing 运行一次,可以辅助生成几个必要的文件。

 

[cpp] view plain copy
  1. [root@localhost project]# automake --add-missing  
  2. Makefile.am: required file `./NEWS' not found  
  3. Makefile.am: required file `./README' not found  
  4. Makefile.am: required file `./AUTHORS' not found  
  5. Makefile.am: required file `./ChangeLog' not found  
  6. [root@localhost project]# ls  
  7. aclocal.m4  autom4te.cache  autoscan.log  config.h.in  config.h.in~  configure  configure.ac  COPYING  depcomp  include  INSTALL  install-sh  lib  main.c  Makefile.am  missing  
  8. [root@localhost project]#  

2.8.2 在当前目录创建上面未发现的四个文件,并再次使用 automake ——add-missing 运行一次。

[c-sharp] view plain copy
  1. [root@localhost project]# touch NEWS  
  2. [root@localhost project]# touch README  
  3. [root@localhost project]# touch AUTHORS  
  4. [root@localhost project]# touch ChangeLog  
  5. [root@localhost project]#  
  6. [root@localhost project]# automake --add-missing  
  7. [root@localhost project]# ls  
  8. aclocal.m4  autom4te.cache  ChangeLog    config.h.in~  config.status  configure.ac  depcomp  INSTALL     lib     Makefile.am  missing  README  
  9. AUTHORS     autoscan.log    config.h.in  config.log    configure      COPYING       include  install-sh  main.c  Makefile.in  NEWS  
  10. [root@localhost project]#  

2.9 使用 configure 命令, 把 Makefile.in 变成最终的 Makefile 文件。

 

[c-sharp] view plain copy
  1. [root@localhost project]# ./configure  
  2. checking for a BSD-compatible install... /usr/bin/install -c  
  3. checking whether build environment is sane... yes  
  4. checking for gawk... gawk  
  5. checking whether make sets $(MAKE)... yes  
  6. checking for gcc... gcc  
  7. checking for C compiler default output file name... a.out  
  8. checking whether the C compiler works... yes  
  9. checking whether we are cross compiling... no  
  10. checking for suffix of executables...  
  11. checking for suffix of object files... o  
  12. checking whether we are using the GNU C compiler... yes  
  13. checking whether gcc accepts -g... yes  
  14. checking for gcc option to accept ANSI C... none needed  
  15. checking for style of include used by make... GNU  
  16. checking dependency style of gcc... gcc3  
  17. configure: creating ./config.status  
  18. config.status: creating Makefile  
  19. config.status: creating config.h  
  20. config.status: config.h is unchanged  
  21. config.status: executing depfiles commands  
  22. [root@localhost project]# ls  
  23. aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello    INSTALL     lib     main.o    Makefile.am  missing  README    test.o  
  24. AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  include  install-sh  main.c  Makefile  Makefile.in  NEWS     stamp-h1  
  25. [root@localhost project]#  

 

    Makefile文件已经生成成功。

 

三、Makefile的用法

3.1  make 命令,用来编译代码, 默认执行”make all”命令,可以看到生成了"hello"的可执行文件,

[c-sharp] view plain copy
  1. [root@localhost project]# make  
  2. make  all-am  
  3. make[1]: Entering directory `/home/chenjie/project'  
  4. gcc  -g -O2   -o hello  main.o test.o  
  5. make[1]: Leaving directory `/home/chenjie/project'  
  6. [root@localhost project]#  
  7. [root@localhost project]# ls  
  8. aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello    INSTALL     lib     main.o    Makefile.am  missing  README    test.o  
  9. AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  include  install-sh  main.c  Makefile  Makefile.in  NEWS     stamp-h1  
  10. [root@localhost project]#  

 

3.2 make clean 命令清除编译时的obj文件,它与 make 命令是对应关系,一个是编译,一个清除编译的文件

 

3.3 运行”./hello”就能看到运行结果:

 

[c-sharp] view plain copy
  1. [root@localhost project]# ./hello  
  2. main entrance.  
  3. test method.  
  4. [root@localhost project]#  

3.4 make install 命令把目标文件安装到系统中。这一,直接输入hello, 就可以看到程序的运行结果。

[c-sharp] view plain copy
  1. [root@localhost project]# make install  
  2. make[1]: Entering directory `/home/chenjie/project'  
  3. test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"  
  4.   /usr/bin/install -c 'hello' '/usr/local/bin/hello'  
  5. make[1]: Nothing to be done for `install-data-am'.  
  6. make[1]: Leaving directory `/home/chenjie/project'  
  7. [root@localhost project]#  
  8. [root@localhost project]# hello  
  9. main entrance.  
  10. test method.  
  11. [root@localhost project]#  

 

3.5 make uninstall 命令把目标文件从系统中卸载。

3.6 make dist 命令将程序和相关的文档打包为一个压缩文档以供发布,在本例子中,生成的打包文件名为:hello-1.0.tar.gz。

 

[c-sharp] view plain copy
  1. [root@localhost project]# make dist  
  2. { test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; }  
  3. mkdir hello-1.0  
  4. find hello-1.0 -type d ! -perm -755 -exec chmod a+rwx,go+rx {} /; -o /  
  5.           ! -type d ! -perm -444 -links 1 -exec chmod a+r {} /; -o /  
  6.           ! -type d ! -perm -400 -exec chmod a+r {} /; -o /  
  7.           ! -type d ! -perm -444 -exec /bin/sh /home/chenjie/project/install-sh -c -m a+r {} {} /; /  
  8.         || chmod -R a+r hello-1.0  
  9. tardir=hello-1.0 && /bin/sh /home/chenjie/project/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz  
  10. { test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; }  
  11. [root@localhost project]# ls  
  12. aclocal.m4  autom4te.cache  ChangeLog  config.h.in   config.log     configure     COPYING  hello             include  install-sh  main.c  Makefile     Makefile.in  NEWS    stamp-h1  
  13. AUTHORS     autoscan.log    config.h   config.h.in~  config.status  configure.ac  depcomp  hello-1.0.tar.gz  INSTALL  lib         main.o  Makefile.am  missing      README  test.o  
  14. [root@localhost project]#  


四 如何使用已发布的压缩文档

4.1 下载到“hello-1.0.tar.gz”压缩文档

4.2 使用“ tar -zxvf hello-1.0.tar.gz ”命令解压

4.3 使用 “./configure” 命令,主要的作用是对即将安装的软件进行配置,检查当前的环境是否满足要安装软件的依赖关系。

4.4 使用“ make ” 命令编译源代码文件生成软件包。

4.5 使用 “ make install ”命令来安装编译后的软件包。

[c-sharp] view plain copy
  1. [root@localhost chenjie]# ls  
  2. hello-1.0.tar.gz  
  3. [root@localhost chenjie]# tar -zxvf hello-1.0.tar.gz  
  4. [root@localhost chenjie]# ls  
  5. hello-1.0  hello-1.0.tar.gz  
  6. [root@localhost chenjie]# cd hello-1.0  
  7. [root@localhost hello-1.0]# ls  
  8. aclocal.m4  AUTHORS  ChangeLog  config.h.in  configure  configure.ac  COPYING  depcomp  include  INSTALL  install-sh  lib  main.c  Makefile.am  Makefile.in  missing  NEWS  README  
  9. [root@localhost hello-1.0]#  
  10. [root@localhost hello-1.0]#  
  11. [root@localhost hello-1.0]# ./configure  
  12. checking for a BSD-compatible install... /usr/bin/install -c  
  13. checking whether build environment is sane... yes  
  14. checking for gawk... gawk  
  15. checking whether make sets $(MAKE)... yes  
  16. checking for gcc... gcc  
  17. checking for C compiler default output file name... a.out  
  18. checking whether the C compiler works... yes  
  19. checking whether we are cross compiling... no  
  20. checking for suffix of executables...  
  21. checking for suffix of object files... o  
  22. checking whether we are using the GNU C compiler... yes  
  23. checking whether gcc accepts -g... yes  
  24. checking for gcc option to accept ANSI C... none needed  
  25. checking for style of include used by make... GNU  
  26. checking dependency style of gcc... gcc3  
  27. configure: creating ./config.status  
  28. config.status: creating Makefile  
  29. config.status: creating config.h  
  30. config.status: executing depfiles commands  
  31. [root@localhost hello-1.0]#  
  32. [root@localhost hello-1.0]# make  
  33. make  all-am  
  34. make[1]: Entering directory `/home/chenjie/hello-1.0'  
  35. if gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -MT main.o -MD -MP -MF ".deps/main.Tpo" -c -o main.o main.c; /  
  36.         then mv -f ".deps/main.Tpo" ".deps/main.Po"else rm -f ".deps/main.Tpo"; exit 1; fi  
  37. if gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -MT test.o -MD -MP -MF ".deps/test.Tpo" -c -o test.o `test -f 'lib/test.c' || echo './'`lib/test.c; /  
  38.         then mv -f ".deps/test.Tpo" ".deps/test.Po"else rm -f ".deps/test.Tpo"; exit 1; fi  
  39. gcc  -g -O2   -o hello  main.o test.o  
  40. make[1]: Leaving directory `/home/chenjie/hello-1.0'  
  41. [root@localhost hello-1.0]#  
  42. [root@localhost hello-1.0]# make install  
  43. make[1]: Entering directory `/home/chenjie/hello-1.0'  
  44. test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"  
  45.   /usr/bin/install -c 'hello' '/usr/local/bin/hello'  
  46. make[1]: Nothing to be done for `install-data-am'.  
  47. make[1]: Leaving directory `/home/chenjie/hello-1.0'  
  48. [root@localhost hello-1.0]#  
  49. [root@localhost hello-1.0]# hello  
  50. main entrance.  
  51. test method.  
 

五、命令使用的整个流程图

    图我就不画了,转载两个图[2][3],对比着看,或许更明白一些。

 

GNU Autotools的使用方法_第1张图片

GNU Autotools的使用方法_第2张图片

 


六、总结

    本文描述了如果使用GNU Autotools的来管理源代码,发布源代码包,以及获得源代码包后如何编译、安装。由于这个例子过于简单,GNU Autotools的用法还未完全描述清楚,主要体现在以下几点:

    (1)在创建 Makefile.am 文件中,描述的很简单。在实际的项目中,文件关系很复杂,而且还有引用其他动态库、第三方动态库等关系。

    (2)虽然 makefile 是自动生成的,但是了解它的规则是非常重要的。makefile 涉及到的规则本文并未加以描述。

    有空的时候再写一篇blog来描述上述两个问题

你可能感兴趣的:(GNU Autotools的使用方法)