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

        作为一名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 src
drwxrwxr-x 2 admin admin 4096 11月 24 17:10 tests
drwxrwxr-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_CXX
AC_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_CXX
AC_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.ac
drwxrwxr-x 5 admin admin  4096 11月 24 15:55 src
drwxrwxr-x 2 admin admin  4096 11月 24 17:10 tests
drwxrwxr-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.m4
drwxr-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.ac
drwxrwxr-x 5 admin admin   4096 11月 24 15:55 src
drwxrwxr-x 2 admin admin   4096 11月 24 17:10 tests
drwxrwxr-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.m4
drwxr-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.ac
drwxrwxr-x 5 admin admin   4096 11月 24 15:55 src
drwxrwxr-x 2 admin admin   4096 11月 24 17:10 tests
drwxrwxr-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.a
common_sources = common.h		common.cpp

libcommon_a_SOURCES = ${common_sources}

clean-local: 
	-rm -f *.gcov *.gcno *.gcda
You 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}/src
LDADD = ${top_srcdir}/src/common/libcommon.a
bin_PROGRAMS = prog1
prog1_SOURCES = main.cpp
clean-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 AUTHORS
drwxr-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 README
drwxrwxr-x 5 admin admin   4096 11月 25 08:53 src
drwxrwxr-x 3 admin admin   4096 11月 25 08:53 tests
drwxrwxr-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-missing
configure.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 found
configure.ac:7: installing `./missing'
src/common/Makefile.am: installing `./depcomp'
src/prog1/Makefile.am:1: `:='-style assignments are not portable
src/prog2/Makefile.am:1: `:='-style assignments are not portable
tests/Makefile.am:1: `:='-style assignments are not portable
tools/Makefile.am:1: `:='-style assignments are not portable
Makefile.am: installing `./INSTALL'
Makefile.am: installing `./COPYING' using GNU General Public License v3 file
Makefile.am:     Consider adding the COPYING file to the version control system
Makefile.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 AUTHORS
drwxr-xr-x 2 admin admin   4096 11月 25 17:33 autom4te.cache
-rw-rw-r-- 1 admin admin      0 11月 25 18:15 ChangeLog
lrwxrwxrwx 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.in
lrwxrwxrwx 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.ac
lrwxrwxrwx 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/depcomp
lrwxrwxrwx 1 admin admin     32 11月 25 18:19 INSTALL -> /usr/share/automake-1.11/INSTALL
lrwxrwxrwx 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.am
lrwxrwxrwx 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 README
drwxrwxr-x 5 admin admin   4096 11月 25 08:53 src
drwxrwxr-x 3 admin admin   4096 11月 25 08:53 tests
drwxrwxr-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 -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for ranlib... ranlib
checking for g++... g++
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for style of include used by make... GNU
checking dependency style of g++... gcc3
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating src/common/Makefile
config.status: creating src/prog1/Makefile
config.status: creating src/prog2/Makefile
config.status: creating tools/Makefile
config.status: creating tests/Makefile
config.status: creating config.h
config.status: executing depfiles commands
[admin@ChunkServer-4 autotools]$ 

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

2.3 Makefile的用法

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

[admin@ChunkServer-4 autotools]$ make
make  all-recursive
make[1]: Entering directory `/home/admin/lyf/xiaopangzi/autotools'
Making all in src
make[2]: Entering directory `/home/admin/lyf/xiaopangzi/autotools/src'
Making all in common
make[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 prog1
make[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 prog2
make[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 tests
make[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 tools
make[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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值