转载至: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。在系统中,显示如下:


[c-sharp]
 view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  1. /* project/include/test.h*/
  2. void test_method();

二、autotools 使用步骤

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

[c-sharp] view plaincopy
  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 plaincopy
  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 plaincopy
  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]

[c-sharp] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  1. [root@localhost project]# ./hello
  2. main entrance.
  3. test method.
  4. [root@localhost project]#

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

[c-sharp] view plaincopy
  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 plaincopy
  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 plaincopy
  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来描述上述两个问题。

Makefile文件生成 GNU Autotools的使用方法相关推荐

  1. Makefile文件生成

    Makefile文件生成 (2008-04-28 19:19:01) 转载▼ 标签: linux 分类:DoxygenMakefile 所必须的软件:autoconf(generate configu ...

  2. linux makefile文件怎么生成,Makefile文件生成

    所必须的软件:autoconf (generate configuration script [configuration]) automake( aclocal:automatically gene ...

  3. 多文件目录下makefile文件递归执行编译所有c文件 很不错

    下面是网上找到的,思路很不错,当然也无法满足所有的需求,我执行又修改了一套.解决了下面的方法存在的问题:每次编译都是全编译的问题,解决思路是.o文件需要跟编译的makefile文件同目录. 首先说说本 ...

  4. Macbook 终端Terminal下如何查看文件生成日期和修改日期

    有时候在用vim命令修改配置文件时,不确定是否被修改,为了与旧版本比较,最好查一下文件生成和修改日期,方法如下: $ GetFileInfo my_file.py file: "/Users ...

  5. Makefile文件自动生成,ubuntu系统autotools使用

    多目录项目用automake和autoconf自动生成Makefile方法 在Linux系统下编写代码,基本上都会遇到Makefile的使用,虽说它对于工程管理有很方便的作用,但对初学者来说要编写出自 ...

  6. Ubuntu ./configure 半途终止 导致没有生成makefile文件 解决方法

    在安装thrift的时候,解压包进入目录,执行命令: ./configure 之后,发现某些包没有安装,导致configure到一半的时候退出,接着make发现没有makefile文件.估计是我系统安 ...

  7. 例解 autoconf 和 automake 生成 Makefile 文件[转+个人修改]

    引子 无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令.不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或 make install.利用make工具,我们可 ...

  8. Ubuntu下使用cmake结合CmakeLists.txt生成makefile文件并进行编译

    转自1:https://www.cnblogs.com/cv-pr/p/6206921.html 转自2:https://blog.csdn.net/qqwangfan/article/details ...

  9. php导出doc文件_PHP生成Word文档的方法

    PHP生成Word文档的方法 首先,请确保在你的Windows系统中已经安装并配置好了一个典型的WAMP环境.由于Interop纯粹是一个Windows的特性,我们将在Windows平台下搭建Apac ...

  10. vue html引入资源dev下404,webpack vue 项目打包生成的文件,资源文件报404问题的修复方法(总结篇)...

    最近在使用webpack + vue做个人娱乐项目时,发现npm run build后,css js img静态资源文件均找不到路径,报404错误...网上查找了一堆解决办法,总结如下 一.首先修改c ...

最新文章

  1. 【嵌入式】Libmodbus下载和编译详解
  2. 收集下关系数据库处理亿万级别的数据
  3. django1.4.9 OMserverweb站点管理
  4. MyEclipse中SVN的使用方法
  5. 【ios】开发者笔记-编写第一个app
  6. 三条中线分的六个三角形_初中数学——与三角形有关的线段
  7. 黑马程序员传智播客python 协程greenlet gevent学习笔记
  8. DirectX修复工具V4.1公测!
  9. pip install清华镜像源
  10. matlab中调用simulink,MATLAB中的simulink是做什么的?说的通俗简单点 如何在matlab中打开simulink...
  11. readlink /var/lib/docker/overlay2: invalid argument的解决方案
  12. python多任务,线程详解
  13. “一品四境”学JAVA——书籍推荐/路径规划
  14. “华为云,有技术”,并不只是一句口号而已
  15. 老猪带你玩转自定义控件三——sai大神带我实现ios 8 时间滚轮控件
  16. mysql从数据库误删.idb / .frm 文件,恢复数据方法
  17. 统计学习(一):最大似然估计
  18. MYSQL中日期加减(前一天、后一天等)以及格式化的函数
  19. 宝塔面板重启mysql命令_宝塔linux面板命令大全
  20. 记 · leo · code 2019

热门文章

  1. 计算机网络超详细笔记(一):计网概述
  2. 牛顿插值 | MATLAB源码
  3. 405.十六进制数 (力扣leetcode) 博主可答疑该问题
  4. 使用py 和flask 实现的服务器系统目录浏览,日志文件实时显示到网页的功能
  5. java 编程英语单词,语句
  6. webGIS的粗浅认识(一)
  7. 画图解释 SQL join 语句
  8. 解决easy ui 1.4datebox控件不能清空的问题
  9. USACO 3.3 Riding the Fences(欧拉路输出路径)
  10. centos标准分区调整大小_磁盘怎么调整分区大小 磁盘调整分区大小教程【详细步骤】...