本文转载自: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. How Many Answers Are Wrong----hdu3038(并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038 题意:数组第 a 个元素到第 b 个元素之间的和为sum: 求有几句话是假的,如果与前面的话有冲 ...

  2. Python开发【笔记】:加锁的最佳方案

    避开死锁 代码程序中,尽量要避免死锁的产生,下面分析常见的线程锁使用方式 :注:只有同一把锁才会产生互斥 1.常见的死锁方式(加锁时程序报错,锁未释放): import time import thr ...

  3. oracle动态视图(一)stat

    1v$mystat,v$sesstat,v$sysstat是用来分别统计用户级,会话级,系统级信息的. SID                                 NUMBER STATI ...

  4. oracle(一)复习起航

    住了三年的宿舍,前几天不得不搬走.也断了好几天网,所以顺手拿了本以前买的<oracle编程艺术>,感觉翻译的书就是有些地方读起来不通顺,好吃力. 还好以前有点oracle经验,不然真看不懂 ...

  5. 梯度下降算法(Gradient Descent)

    近期在搞论文,须要用梯度下降算法求解,所以又一次整理分享在这里. 主要包含梯度介绍.公式求导.学习速率选择.代码实现. 梯度下降的性质: 1.求得的解和选取的初始点有关 2.能够保证找到局部最优解,由 ...

  6. 通过Tacker将NFV引入OpenStack

    14年的这个时候,我们还在OpenStack社区中为NFV是否属于OpenStack而争论不休.如今这一争议已经被解决了.OpenStack已经成为NFV讨论中的重要部分,正如下面的ETSI MANO ...

  7. Selenium+Java元素定位之二

    //通过完全匹配链接来定位 driver.findElement(By.linkText("新闻")).click(); //通过部分匹配链接来定位 driver.findElem ...

  8. python3专业版安装及破解

    1.网址 https://www.jetbrains.com/pycharm/download/#section=windows,打开页面,点击下载专业版 2.这是下载好的文件,双击运行即可. //详 ...

  9. IDA 7.0在Mojava更新后打不开的问题

    Mac升级到mojava后,ida 7.0打不开了. 上述是两种典型的窗口,不过不论是出现什么样的弹窗,如果是在升级之后出现的,都要试一下下面的解决办法.因为IDA7.0版本流出的比较多,虽然这个已经 ...

  10. IP设置-内置服务器-外置服务器

    HBulider 中 运行 -> 设置web服务器 -> 内置服务器将 127.0.0.1 换为局域网的ip,可以在局域网内所有电脑,手机上浏览页面.但是只能浏览html,php asp等 ...