本文转载自:http://blog.csdn.net/scucj/article/details/6079052

手工写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。在系统中,显示如下:

  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)源代码如下:

  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. }
  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. }
  1. /* project/include/test.h*/
  2. void test_method();

二、autotools 使用步骤

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

  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里面的宏的主要作用是侦测系统。

  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]:

  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,abc@126.com)
  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]

  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中定义的宏。

  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].

  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 文件。

  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 自动添加一些必需的脚本文件。

  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 运行一次,可以辅助生成几个必要的文件。

  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 运行一次。

  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 文件。

  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"的可执行文件,

  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”就能看到运行结果:

  1. [root@localhost project]# ./hello
  2. main entrance.
  3. test method.
  4. [root@localhost project]#

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

  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。

  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,<a href="http://lib.csdn.net/base/go" class='replace_word' title="Go知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Go</a>+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 ”命令来安装编译后的软件包。

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

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

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

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

[1] http://book.chinaitlab.com/linux/777286.html

[2] http://blog.ossxp.com/2010/04/954/

Autotools使用流程【转】的更多相关文章

  1. autotools源文件相同/不同目录下

    关于Autotools 我们前面的章节中已经讲到了Makefile的使用(点击进入查看文章).我们知道在Linux下面如果编译一个比较大型的项目,我们可以通过Makefile的方式来完成. 但是,我们 ...

  2. 【Linux技术】autotools制作makefile过程详解

    Preface Makefile固然可以帮助make完成它的使命,但要承认的是,编写Makefile确实不是一件轻松的事,尤其对于一个较大的项目而言更是如此.那么,有没有一种轻松的手段生成Makefi ...

  3. 【Linux技术】autotools制作makefile过程详解【转】

    转自:http://www.cnblogs.com/lcw/p/3159461.htmlPreface Makefile固然可以帮助make完成它的使命,但要承认的是,编写Makefile确实不是一件 ...

  4. GNU autotools 安装和使用

    1. 下载 http://www.gnu.org/software/software.html 2. 安装 m4-1.4.11.tar.gz autoconf-2.63.tar.gz automake ...

  5. GCC 编译详解

    GNU CC(简称为Gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C.C++和Object C等语言编写的程序.Gcc不仅功能强大,而且可以编译如C.C++.Object C.Jav ...

  6. CMake 简单介绍 图

    http://tech.uc.cn/?p=914     CMake特点 CMake需要用户用CMake规范的语法编写CMake脚本,该语法简单易用,入门极其顺手 原生支持 C/C++/Fortran ...

  7. CMake 简单介绍

    CMake特点 CMake需要用户用CMake规范的语法编写CMake脚本,该语法简单易用,入门极其顺手 原生支持 C/C++/Fortran/Java 的相依性的自动分析功能,免除了程序员对代码依赖 ...

  8. GCC 编译详解[转]

    转自http://www.cnblogs.com/azraelly/archive/2012/07/07/2580839.html GNU CC(简称为Gcc)是GNU项目中符合ANSI C标准的编译 ...

  9. gcc编译问题

    gcc avl.o hash.o list.o rb.o example.o -o 123.exe 多个.o输出 exe -c和-o都是gcc编译器的可选参数.-c表示只编译(compile)源文件但 ...

随机推荐

  1. ios-Objective-C中的各种遍历(迭代)方式(转载)

    iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https:// ...

  2. 洛谷P2634 聪聪可可 [国家集训队] 点分治/dp

    正解:点分治/dp 解题报告: 传送门! 这题有两个做法,都是我不擅长的就都说下好了QAQ 首先这题一看到就会想到点分治? 也确实可以用点分治,那就直接用点分治鸭 每次求出到当前根距离余数为0,1,2 ...

  3. gulp-jshint使用说明

    hint是暗示的意思,jshint是什么意思? 1.使用npm安装 cnpm i --save-dev gulp-jshint jshint ps:gulp-jshint和jshnt要一起下载,安装. ...

  4. javaScript高级教程(一)javaScript 1.6 Array 新增函数

    1.forEach,map,filter三个函数者是相同的调用参数.(callback[, thisArg]) callback is invoked with three arguments: th ...

  5. 给sql server2005打补丁报错:无法安装Windows Installer MSP文件

    给sql server2005打补丁报错:无法安装Windows Installer MSP文件 在我们安装完SQL2005数据库后,需要安装SP4补丁时,会出错:无法安装Windows Instal ...

  6. 类似CFS程式发布注意事项

    1.CFS 此AP 程式的验证方式为Forms 验证.需要在IIS 中做如下设置(Forms 身份验证,配套的Web.config 中要有对应节点代码,后台代码中要有获取方式) 2.Forms 身份验 ...

  7. rplidar跑cartographer

    一.Cartographer编译 cartographer依赖的大型第三方库很少,编译时基本没有依赖项问题,基本按照官方文档的步骤来,略作修改.使用的环境是Ubuntu16.04+ROS Kineti ...

  8. [vue]vue-cli下载原理

    正常vue-cli这样操作就ok了 vue-cli github $ npm install -g vue-cli $ vue init webpack my-project $ cd my-proj ...

  9. [py]requests+json模块处理api数据,flask前台展示

    需要处理接口json数据,过滤字段,处理字段等. 一大波json数据来了 参考: https://stedolan.github.io/jq/tutorial/ https://api.github. ...

  10. Kettle定时抽取两个库中的两个表到目标库SYS_OPLOG表

     A库a表(红色为抽取字段): 关联用户表: B库b表(红色为抽取字段): 关联用户表  C目标库SYS_OPLOG表(c表) 利用kettle抽取A库a表(具体名称见上图),B库b表的上面红色框起来 ...