自学编写Makefile之1 —— GNU Autotools工具介绍

来源:互联网 发布:知乎仲夏夜之梦 编辑:程序博客网 时间:2024/05/17 08:03

        作为一名C/C++程序猿,初学C/C++时开发环境绝大多数都在Windows下,开发IDE主要集中于VC++ 6.0, Visual Studio (2008, 2010,...),在这种情况下,通常我们不需要自己考虑编译的问题,因为开发工具已经帮我们做掉。但是,随着开发项目的需求变化,越来越多的C/C++程序猿都需要转移到UNIX/Linux环境下进行开发,此时程序的编译依赖于GNU编译器(GCC,G++等)。如果只是简单的小程序,可以直接使用gcc/g++命令直接编译得到可执行文件。但是,随着代码文件的增加,手写gcc/g++命令就显得很繁琐,易用性也很差。解决方法就是手动写Makefile,每当添加新的代码文件或者修改某段代码时,只需要简单修改一下Makefile就可以编译,这样就省去那些繁琐的命令行。

        手工写Makefile是一件很有趣的事情,但是,对于大型项目,手写Makefile也是一件相当费力的工作,如果有工具可以替代,自然可以省去很多工作。在Linux系统开发环境中,GNU Autotools无疑充当了这一重要角色。

一、GNU Autotools介绍

        GNU Autotools是发布管理GNU软件包的一套非常著名的工具集合。通常,我们在Linux下面下载的大多数源代码形式发布的软件包,都是采用这套工具生成的。举例简单说明一下这个工具集合的用途。大部分时候,你从网上下载了一个开放软代码的软件,解压后,一般会敲入以下三个命令来编译和安装程序:

  1. ./configure
  2. make
  3. make install

        其中,configure脚本分析你的系统以找到合适的工具和库,make才是真正用来编译构建软件的工具,make install用来安装软件。在开放源代码世界里,configure脚本获得了广泛的使用,它使从源代码安装软件变得非常容易。

        GNU Autotools是一个系列工具,主要由autoconf、automake、libtools、perl语言环境和m4等组成,主要包括下面三个工具:

  • autoconf - 用来生成configure脚本。这个脚本主要用于分析你的系统以找到合适的工具和库。譬如,你的系统的C编译器是"cc"还是"gcc";
  • automake - 用来生成Makefile。它需要使用到Autoconf提供的信息。譬如,如果Autoconf检测到你的系统使用"gcc",那么Makefile就使用gcc作为C编译器;反之,如果找到"cc",那就使用"cc";
  • libtools - 这个工具创建共享库,它是平台无关的(目前使用的不多,这里暂时不做详细介绍,会在后续的博客中介绍);

        还有一些其他工具,包括autoscan、aclocal、autoheader等,这些工具在生成Makefile过程都起到重要作用。

        那么,autoconf和automake究竟是做啥?首先要从UNIX系统的程序编译说起。一般一个真正的工程肯定不只一个文件(不只一个目录),而多个文件(多个目录)的编译时间很繁琐的事情(最简单的方法就是gcc或g++后面接着多个文件),再加上要推出跨平台的(一般是指跨不同类型的UNIX平台),还要检查依赖包等等。于是就有了一个make工具,它接收一个名为Makefile的文件作为参数,自动地进行编译,还可以在Makefile里设置接受不同的选项,然后就可以make install、make all .....

       然后,不同系统的编译需要不同的编译参数,但是开源软件不可能带多个Makefile,而且又难写。于是又有了configure脚本,它会自动检测系统,并接收一个Makefile.in文件,根据它来生成Makefile。

       可是,configure脚本和Makefile.in还是很难写,至少我不会写,也看不懂。于是GNU推出了autoconf和automake等工具,用于生成configure脚本和Makefile.in文件。其中,autoconf用来生成configure脚本,automake用来生成Makefile.in。

二、GNU Autotools简单使用

        GNU Autotools主要用于自动生成较大项目的Makefile,避免繁琐的命令行操作,也便于系统的更新和修改,加快项目开发进度。如何正确使用autotools,对于一个新手来说极为重要。接下来,将从一个简单例子来逐步讲解诸多autotools工具的功能和使用。

2.1 代码示例

        简单代码示例,包含src/   tests/    tools/    三个代码目录,每个目录下子目录结构和代码文件结构如下:

./├── src│   ├── common│   │   ├── common.cpp│   │   └── common.h│   ├── prog1│   │   └── main.cpp│   └── prog2│       └── main.cpp├── tests│   └── main.cpp└── tools    └── main.cpp
        其中: src/common/:common.h和common.cpp里包含所有公用的函数,会生成一个静态库

src/prog1/:main.cpp 调用common中函数,对应一个可执行文件

src/prog2/:main.cpp 调用common中函数,对应一个可执行文件

tests/:main.cpp 调用common中函数,对应一个可执行文件

tools/:main.cpp 调用common中函数,对应一个可执行文件

2.2 Autotools使用步骤

步骤1:使用autoscan命令,将扫描工作目录,生成configure.scan文件;

[admin@ChunkServer-4 autotools]$ autoscan[admin@ChunkServer-4 autotools]$ ll总用量 16-rw-rw-r-- 1 admin admin    0 11月 24 17:32 <span style="BACKGROUND-COLOR: #ffff66">autoscan.log</span>-rw-rw-r-- 1 admin admin  486 11月 24 17:32 <span style="BACKGROUND-COLOR: #ffff66">configure.scan</span>drwxrwxr-x 5 admin admin 4096 11月 24 15:55 srcdrwxrwxr-x 2 admin admin 4096 11月 24 17:10 testsdrwxrwxr-x 2 admin admin 4096 11月 24 17:11 tools

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

[admin@ChunkServer-4 autotools]$ mv configure.scan configure.ac[admin@ChunkServer-4 autotools]$ cat configure.ac #                                               -*- Autoconf -*-# Process this file with autoconf to produce a configure script.AC_PREREQ([2.66])AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])AC_CONFIG_SRCDIR([tools/main.cpp])AC_CONFIG_HEADERS([config.h])# Checks for programs.AC_PROG_CXXAC_PROG_CC# Checks for libraries.# Checks for header files.# Checks for typedefs, structures, and compiler characteristics.# Checks for library functions.AC_OUTPUT[admin@ChunkServer-4 autotools]$

内容分析:

  1. 以"#"开始的行均为注释;
  2. AC_PREREQ                      声明本文要求autoconf版本,本文中例子的版本为2.66,无需修改;
  3. AC_INIT                                用来定义软件名称、版本信息、BUG提交地址等,需要自己填入(名称可以随意起,只要符合标识符规则即可),这里bug提交地址可以忽略,或者一般写作者E-mail;
  4. AC_CONFIG_SRCDIR      用来侦测所指定的源码文件是否存在,来确定源码目录的有效性,本文例子中为tools/main.cpp,这个参数一般不修改;
  5. AC_CONFIG_HEADER     用于生成config.h文件,以便autoheader命令使用。也可以不指定;
  6. AC_PROG_CC                   用来指定编译器,CC表示使用C语言,编译器为gcc;
  7. AC_PROG_CXX                 同上,但是CXX表示使用C++语言,编译器为g++,其他语言参考autoscan手册;
  8. AC_OUTPUT                      指定要输出的Makefile文件名,注意每个有源代码(或者有Makefile.am)的地方都要输出Makefile文件,不同的文件之间用空格分开,譬如AC_OUTPUT(Makefile src/Makefile)。同样,也可以使用AC_CONFIG_FILES宏来指定Makefile文件,功能一样,多个Makefile文件(比如子目录中也有Makefile文件)时用空格分开。

             其他的一些这里没有用到的宏定义主要有AC_PROG_INSTALL、PKG_CHECK_MODULES和AC_SUBST、AC_PROG_RANLIB(用到静态库时使用)、AC_PROG_LIBTOOL(用到动态库时使用)等,具体可查看参数帮助手册。中间的注释部分可以天剑用于测试程序、测试函数库、测试头文件等宏定义。

步骤3:对configure.ac文件做适当修改,如下所示

[admin@ChunkServer-4 autotools]$ cat configure.ac #                                               -*- Autoconf -*-# Process this file with autoconf to produce a configure script.AC_PREREQ([2.66])#AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])AC_INIT([test], [1.0], [xxxx@xxx.com])<span style="BACKGROUND-COLOR: #ffff33">AM_INIT_AUTOMAKE(test, 1.0)</span>AC_CONFIG_SRCDIR([tools/main.cpp])AC_CONFIG_HEADERS([config.h])<span style="BACKGROUND-COLOR: #ffff66">AC_PROG_RANLIB#AC_PROG_LIBTOOL</span># Checks for programs.AC_PROG_CXXAC_PROG_CC# Checks for libraries.# Checks for header files.# Checks for typedefs, structures, and compiler characteristics.# Checks for library functions.<span style="BACKGROUND-COLOR: #ffff66">AC_CONFIG_FILES([ \Makefile \src/Makefile \src/common/Makefile \src/prog1/Makefile \src/prog2/Makefile \tools/Makefile \tests/Makefile])</span>AC_OUTPUT[admin@ChunkServer-4 autotools]$ 

内容添加和修改

  1. AM_INIT_AUTOMAKE       手动添加,它是automake所必备的宏,FULL-PACKAGE-NAME是软件名称,VERSION是软件版本号;
  2. AC_PROG_RANLIB          仅使用静态库时,需要添加;
  3. AC_PROG_LIBTOOL        需要使用动态库时,需要加上(后面会有专题介绍这两个宏的使用说明)
  4. AC_CONFIG_FILES          指定生成相应的Makefile文件。

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

[admin@ChunkServer-4 autotools]$ aclocal[admin@ChunkServer-4 autotools]$ ll总用量 56-rw-rw-r-- 1 admin admin 34611 11月 24 19:19 <span style="BACKGROUND-COLOR: #ffff66">aclocal.m4</span>drwxr-xr-x 2 admin admin  4096 11月 24 19:19 <span style="BACKGROUND-COLOR: #ffff66">autom4te.cache</span>-rw-rw-r-- 1 admin admin     0 11月 24 17:32 autoscan.log-rw-rw-r-- 1 admin admin   733 11月 24 19:07 configure.acdrwxrwxr-x 5 admin admin  4096 11月 24 15:55 srcdrwxrwxr-x 2 admin admin  4096 11月 24 17:10 testsdrwxrwxr-x 2 admin admin  4096 11月 24 17:11 tools[admin@ChunkServer-4 autotools]$

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

[admin@ChunkServer-4 autotools]$ autoconf[admin@ChunkServer-4 autotools]$ ll总用量 208-rw-rw-r-- 1 admin admin  34611 11月 24 19:19 aclocal.m4drwxr-xr-x 2 admin admin   4096 11月 24 19:24 autom4te.cache-rw-rw-r-- 1 admin admin      0 11月 24 17:32 autoscan.log-rwxrwxr-x 1 admin admin 151918 11月 24 19:24 <span style="BACKGROUND-COLOR: #ffff66">configure</span>-rw-rw-r-- 1 admin admin    733 11月 24 19:07 configure.acdrwxrwxr-x 5 admin admin   4096 11月 24 15:55 srcdrwxrwxr-x 2 admin admin   4096 11月 24 17:10 testsdrwxrwxr-x 2 admin admin   4096 11月 24 17:11 tools[admin@ChunkServer-4 autotools]$

步骤6:使用autoheader命令根据configure.ac生成config.h.in文件。该命令通常会从acconfig.h文件中复制用户附件的符号定义,注意configure.ac中必须要有AC_PROG_HEADER才能运行autoheader。该例子中没有附件的符号定义,所以不需要创建acconfig.h文件;

[admin@ChunkServer-4 autotools]$ autoheader[admin@ChunkServer-4 autotools]$ ll总用量 212-rw-rw-r-- 1 admin admin  34611 11月 24 19:19 aclocal.m4drwxr-xr-x 2 admin admin   4096 11月 24 19:24 autom4te.cache-rw-rw-r-- 1 admin admin      0 11月 24 17:32 autoscan.log-rw-rw-r-- 1 admin admin    625 11月 24 19:33 <span style="BACKGROUND-COLOR: #ffff66">config.h.in</span>-rwxrwxr-x 1 admin admin 151918 11月 24 19:24 configure-rw-rw-r-- 1 admin admin    733 11月 24 19:07 configure.acdrwxrwxr-x 5 admin admin   4096 11月 24 15:55 srcdrwxrwxr-x 2 admin admin   4096 11月 24 17:10 testsdrwxrwxr-x 2 admin admin   4096 11月 24 17:11 tools[admin@ChunkServer-4 autotools]$

步骤7:手动创建Makefile.am文件。automake工具会根据configure.ac中的参数把Makefile.am文件转换成Makefile.in文件;

./├── aclocal.m4├── autom4te.cache│   ├── output.0│   ├── output.1│   ├── requests│   ├── traces.0│   └── traces.1├── config.h.in├── configure├── configure.ac├── <span style="BACKGROUND-COLOR: #ffff66">Makefile.am</span>├── src│   ├── common│   │   ├── common.cpp│   │   ├── common.h│   │   └── <span style="BACKGROUND-COLOR: #ffff66">Makefile.am</span>│   ├── Makefile.am│   ├── prog1│   │   ├── main.cpp│   │   └── <span style="BACKGROUND-COLOR: #ffff66">Makefile.am</span>│   └── prog2│       ├── main.cpp│       └── <span style="BACKGROUND-COLOR: #ffff66">Makefile.am</span>├── tests│   ├── main.cpp│   └── <span style="BACKGROUND-COLOR: #ffff66">Makefile.am</span>└── tools    ├── main.cpp    └── <span style="BACKGROUND-COLOR: #ffff66">Makefile.am</span>

分别在./    src/      src/common/        src/prog1/        src/prog2/         tests/        tools/    几个目录下添加Makefile.am文件,简单给两个Makefile.am示例如下:

[admin@ChunkServer-4 autotools]$ cat src/common/Makefile.am noinst_LIBRARIES = libcommon.acommon_sources = common.hcommon.cpplibcommon_a_SOURCES = ${common_sources}clean-local: -rm -f *.gcov *.gcno *.gcdaYou have new mail in /var/spool/mail/admin[admin@ChunkServer-4 autotools]$ 
[admin@ChunkServer-4 autotools]$ cat src/prog1/Makefile.am AM_CPPFLAGS := $(AM_CPPFLAGS)-I${top_srcdir}/srcLDADD = ${top_srcdir}/src/common/libcommon.abin_PROGRAMS = prog1prog1_SOURCES = main.cppclean-local:-rm -f *.gcov *.gcno *.gcda[admin@ChunkServer-4 autotools]$ 

Makefile.am也有很多宏,如AM_CPPFLAGS、libcommon_a_SOURCES、noinst_LIBRARIES、bin_PROGRAMS等等,分别代表不同意义。

步骤8:手动创建几个空文件,AUTHORS、ChangeLog、NEWS和README;

[admin@ChunkServer-4 autotools]$ touch NEWS[admin@ChunkServer-4 autotools]$ touch README[admin@ChunkServer-4 autotools]$ touch AUTHORS[admin@ChunkServer-4 autotools]$ touch ChangeLog[admin@ChunkServer-4 autotools]$ ll总用量 868-rw-rw-r-- 1 admin admin 316266 11月 25 17:33 aclocal.m4-rw-rw-r-- 1 admin admin      0 11月 25 18:15 AUTHORSdrwxr-xr-x 2 admin admin   4096 11月 25 17:33 autom4te.cache-rw-rw-r-- 1 admin admin      0 11月 25 18:15 ChangeLog-rw-rw-r-- 1 admin admin   1617 11月 25 17:33 config.h.in-rwxrwxr-x 1 admin admin 539507 11月 25 17:33 configure-rw-rw-r-- 1 admin admin    762 11月 25 16:14 configure.ac-rw-rw-r-- 1 admin admin     53 11月 25 17:28 Makefile.am-rw-rw-r-- 1 admin admin      0 11月 25 18:15 NEWS-rw-rw-r-- 1 admin admin      0 11月 25 18:15 READMEdrwxrwxr-x 5 admin admin   4096 11月 25 08:53 srcdrwxrwxr-x 3 admin admin   4096 11月 25 08:53 testsdrwxrwxr-x 3 admin admin   4096 11月 25 08:53 tools[admin@ChunkServer-4 autotools]$ 

步骤9:使用automake命令生成Makefile.in。使用选项--add-missing可以让automake自动添加一些必须的脚本文件(install-sh、missing、depcomp、INSTALL、COPYING);

[admin@ChunkServer-4 autotools]$ automake --add-missingconfigure.ac:12: installing `./config.guess'configure.ac:12: installing `./config.sub'configure.ac:7: installing `./install-sh'configure.ac:12: required file `./ltmain.sh' not foundconfigure.ac:7: installing `./missing'src/common/Makefile.am: installing `./depcomp'src/prog1/Makefile.am:1: `:='-style assignments are not portablesrc/prog2/Makefile.am:1: `:='-style assignments are not portabletests/Makefile.am:1: `:='-style assignments are not portabletools/Makefile.am:1: `:='-style assignments are not portableMakefile.am: installing `./INSTALL'Makefile.am: installing `./COPYING' using GNU General Public License v3 fileMakefile.am:     Consider adding the COPYING file to the version control systemMakefile.am:     for your code, to avoid questions about which license your project uses.[admin@ChunkServer-4 autotools]$ ll总用量 868-rw-rw-r-- 1 admin admin 316266 11月 25 17:33 aclocal.m4-rw-rw-r-- 1 admin admin      0 11月 25 18:15 AUTHORSdrwxr-xr-x 2 admin admin   4096 11月 25 17:33 autom4te.cache-rw-rw-r-- 1 admin admin      0 11月 25 18:15 ChangeLoglrwxrwxrwx 1 admin admin     37 11月 25 18:19 config.guess -> /usr/share/automake-1.11/config.guess-rw-rw-r-- 1 admin admin   1617 11月 25 17:33 config.h.inlrwxrwxrwx 1 admin admin     35 11月 25 18:19 <span style="BACKGROUND-COLOR: #ffff66">config.sub -> /usr/share/automake-1.11/config.sub</span>-rwxrwxr-x 1 admin admin 539507 11月 25 17:33 configure-rw-rw-r-- 1 admin admin    762 11月 25 16:14 configure.aclrwxrwxrwx 1 admin admin     32 11月 25 18:19 <span style="BACKGROUND-COLOR: #ffff66">COPYING -> /usr/share/automake-1.11/COPYING</span>lrwxrwxrwx 1 admin admin     32 11月 25 18:19 depcomp -> /usr/share/automake-1.11/depcomplrwxrwxrwx 1 admin admin     32 11月 25 18:19 INSTALL -> /usr/share/automake-1.11/INSTALLlrwxrwxrwx 1 admin admin     35 11月 25 18:19 install-sh -> /usr/share/automake-1.11/install-sh-rw-rw-r-- 1 admin admin     53 11月 25 17:28 Makefile.amlrwxrwxrwx 1 admin admin     32 11月 25 18:19 missing -> /usr/share/automake-1.11/missing-rw-rw-r-- 1 admin admin      0 11月 25 18:15 NEWS-rw-rw-r-- 1 admin admin      0 11月 25 18:15 READMEdrwxrwxr-x 5 admin admin   4096 11月 25 08:53 srcdrwxrwxr-x 3 admin admin   4096 11月 25 08:53 testsdrwxrwxr-x 3 admin admin   4096 11月 25 08:53 tools[admin@ChunkServer-4 autotools]$ 

此时,在对应有Makefile.am的目录下均生成一个对应的Makefile.in文件

./├── aclocal.m4├── AUTHORS├── autom4te.cache│   ├── output.0│   ├── output.1│   ├── requests│   ├── traces.0│   └── traces.1├── ChangeLog├── config.guess -> /usr/share/automake-1.11/config.guess├── config.h.in├── config.sub -> /usr/share/automake-1.11/config.sub├── configure├── configure.ac├── COPYING -> /usr/share/automake-1.11/COPYING├── depcomp -> /usr/share/automake-1.11/depcomp├── INSTALL -> /usr/share/automake-1.11/INSTALL├── install-sh -> /usr/share/automake-1.11/install-sh├── Makefile.am├── Makefile.in├── missing -> /usr/share/automake-1.11/missing├── NEWS├── README├── src│   ├── common│   │   ├── common.cpp│   │   ├── common.h│   │   ├── Makefile.am│   │   └── Makefile.in│   ├── Makefile.am│   ├── Makefile.in│   ├── prog1│   │   ├── main.cpp│   │   ├── Makefile.am│   │   └── Makefile.in│   └── prog2│       ├── main.cpp│       ├── Makefile.am│       └── Makefile.in├── tests│   ├── main.cpp│   ├── Makefile.am│   └── Makefile.in└── tools    ├── main.cpp    ├── Makefile.am    └── Makefile.in

步骤9:使用configure脚本生成Makefile。configure脚本会收集系统的信息,创建config.status、Makefile、config.h、stamp-h1等文件。

[admin@ChunkServer-4 autotools]$ ./configure checking for a BSD-compatible install... /usr/bin/install -cchecking whether build environment is sane... yeschecking for a thread-safe mkdir -p... /bin/mkdir -pchecking for gawk... gawkchecking whether make sets $(MAKE)... yeschecking for ranlib... ranlibchecking for g++... g++checking whether the C++ compiler works... yeschecking for C++ compiler default output file name... a.outchecking for suffix of executables... checking whether we are cross compiling... nochecking for suffix of object files... ochecking whether we are using the GNU C++ compiler... yeschecking whether g++ accepts -g... yeschecking for style of include used by make... GNUchecking dependency style of g++... gcc3checking for gcc... gccchecking whether we are using the GNU C compiler... yeschecking whether gcc accepts -g... yeschecking for gcc option to accept ISO C89... none neededchecking dependency style of gcc... gcc3configure: creating ./config.statusconfig.status: creating Makefileconfig.status: creating src/Makefileconfig.status: creating src/common/Makefileconfig.status: creating src/prog1/Makefileconfig.status: creating src/prog2/Makefileconfig.status: creating tools/Makefileconfig.status: creating tests/Makefileconfig.status: creating config.hconfig.status: executing depfiles commands[admin@ChunkServer-4 autotools]$ 

执行到此,Makefile已经自动生成

2.3 Makefile的用法

<i>    make命令,用来编译代码,默认执行make all命令,会递归地在各个目录中调用Makefile,所有的目录下的代码均被编译;

[admin@ChunkServer-4 autotools]$ makemake  all-recursivemake[1]: Entering directory `/home/admin/lyf/xiaopangzi/autotools'Making all in srcmake[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src'Making all in commonmake[3]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src/common'make[3]: Nothing to be done for `all'.make[3]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src/common'Making all in prog1make[3]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src/prog1'make[3]: Nothing to be done for `all'.make[3]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src/prog1'Making all in prog2make[3]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src/prog2'make[3]: Nothing to be done for `all'.make[3]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src/prog2'make[3]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src'make[3]: Nothing to be done for `all-am'.make[3]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src'make[2]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src'Making all in testsmake[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/tests'make[2]: Nothing to be done for `all'.make[2]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/tests'Making all in toolsmake[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/tools'make[2]: Nothing to be done for `all'.make[2]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/tools'make[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools'make[2]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools'make[1]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools'

此时,在src/prog1、src/prog2、tools/、tests/目录下分别生成对应的.o目标文件和可执行文件,而src/common目录下回生成一个libcommon.a静态库。

有时候,可能并不需要编译全部源代码。make命令也支持有选择的编译,执行make -C src/命令,只会编译src/目录下的源码。同时,对于较大工程,数据文件比较多,目录页比较多,我们需要采用多线程编译:make -j all命令,会根据编译环境(机器的核数)进行多线程编译。也指定线程数来编译,make -j 4 all ——指定线程为4。

<ii>     make install,用来将程序安装到系统目录中,对应make uninstall卸载程序,注:执行make install可能需要sudo

[admin@ChunkServer-4 autotools]$ ll /usr/local/bin/tool /usr/local/bin/test /usr/local/bin/prog*-rwxr-xr-x 1 root root  9950 11月 25 18:53 /usr/local/bin/prog1-rwxr-xr-x 1 root root 11527 11月 25 18:53 /usr/local/bin/prog2-rwxr-xr-x 1 root root  9942 11月 25 18:53 /usr/local/bin/test-rwxr-xr-x 1 root root  9942 11月 25 18:53 /usr/local/bin/tool[admin@ChunkServer-4 autotools]$ 

可见,执行sudo make install后,4个可执行文件均被安装在/usr/local/bin目录下,然后执行sudo make uninstall,卸载成功。
<iii>    make dist,将程序打包为.tar.gz压缩包,以便发布。

[admin@ChunkServer-4 autotools]$ make dist{ test ! -d "test-1.0" || { find "test-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "test-1.0"; }; }test -d "test-1.0" || mkdir "test-1.0" (cd src && make  top_distdir=../test-1.0 distdir=../test-1.0/src \     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)make[1]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src' (cd common && make  top_distdir=../../test-1.0 distdir=../../test-1.0/src/common \     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)make[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src/common'make[2]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src/common' (cd prog1 && make  top_distdir=../../test-1.0 distdir=../../test-1.0/src/prog1 \     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)make[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src/prog1'make[2]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src/prog1' (cd prog2 && make  top_distdir=../../test-1.0 distdir=../../test-1.0/src/prog2 \     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)make[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src/prog2'make[2]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src/prog2'make[1]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/src' (cd tests && make  top_distdir=../test-1.0 distdir=../test-1.0/tests \     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)make[1]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/tests'make[1]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/tests' (cd tools && make  top_distdir=../test-1.0 distdir=../test-1.0/tools \     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)make[1]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/tools'make[1]: Leaving directory `/home/admin/lyf/xiaopangzi/autotools/tools'test -n "" \|| find "test-1.0" -type d ! -perm -755 \-exec chmod u+rwx,go+rx {} \; -o \  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \  ! -type d ! -perm -444 -exec /bin/sh /home/admin/lyf/xiaopangzi/autotools/install-sh -c -m a+r {} {} \; \|| chmod -R a+r "test-1.0"tardir=test-1.0 && /bin/sh /home/admin/lyf/xiaopangzi/autotools/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >test-1.0.tar.gz{ test ! -d "test-1.0" || { find "test-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "test-1.0"; }; }[admin@ChunkServer-4 autotools]$ ll

此时,可以在当前目录下看到一个压缩文件:test-1.0.tar.gz,格式为【包名-版本号.tar.gz】。其中,包名和版本号取决于configure.ac中用户的定义,后面会介绍如何使用这个压缩包。
<iv>     make clean,清除之前编译目标文件、可执行文件及配置文件;而make distclean则清除所有生成的文件,包括config.status、Makefile、config.h等,相当于回到./configure之前的状态。

2.4如何使用以发布的压缩文档

1. 下载 test-1.0.tar.gz 压缩文档;

2.  执行 tar -zxvf test-1.0.tar.gz 命令解压;

3. 进入解压后目录,执行 ./configure 命令,主要的作用对即将安装的软件进行配置,检查当前的环境是否满足软件的依赖关系;

4. 执行make 命令,编译源代码生成软件包;

5. 执行make install命令,安装编译后的软件。

 

一切大功告成。由上面的描述不难看出,Autotools确实是软件维护与发布的便捷工具,鉴于此,如今GNU的软件一般都是由automake来制作的。

三、总结

        本文简单了描述了如何使用GNU Autotools来管理源代码、发布源代码、以及如何编译和安装源代码。作为一个新手,对整个工具还处在摸索阶段,文中例子也过于简单,很难覆盖那么全面,GNU Autotools的使用方法也未完全描述清楚,主要有一下几点:

        (1)创建configure.ac文件时,有很多宏并未在文中使用到,但是实际项目中,会有很多地方用到这些宏;

        (2)创建Makefile.am文件时,描述很简单,只包括简单的可执行文件和静态库使用,在较大项目中,代码文件很复杂,可能会有更多依赖、动态库、第三方库等等;

        (3)Makefile涉及到规则本文并未加以描述(其实,还真不清楚)

        最后,希望可以在接下来的博文中,更多更细致的讲解GNU Autotools的使用。

 

文中例子:https://code.csdn.net/minCrazy/gnu-autotools-sample-code/tree/master

参考:

           http://blog.csdn.net/scucj/article/details/6079052

           http://www.douban.com/note/151393163/

 

0 0
原创粉丝点击