autotools用法简介
本文将简单介绍autotools的使用方法,用它生成一个MySQL客户端应用程序的Makefile并最终得到一个源代码形式(.tar.gz)发布的软件 。 示例文件下载
1.autotools简介
在linux平台下进行开发就一定会接触到Makefile。当代码文件数量较少时,手动编写Makefile并不困难。可是对一个较大的项目而言手动编写Makefile就要困难得多。autotools工具集正是为解决此问题而被设计的。用户只需对目标文件,依赖关系,路径进行简单配置就可以轻松地生成Makefile。而且该工具可根据所在环境进行系统配置信息的收集,可方便处理平台移植性的问题。基于这些优点,在Linux上的软件开发一般都使用autotools来制作Makefile。
2.准备
1)用到的系统:Ubuntu 12.04 autotools工具版本:2.68
2)文中所用的示例程序需要安装mysql
安装mysql,在终端执行以下代码:
sudo apt-get install mysql-server mysql-client
安装mysql开发包,在终端执行以下代码:
sudo apt-get install libmysqlclient15-dev
示例程序的功能是访问数据库并完成一些无关紧要的动作。它访问的是refactoring数据库,该数据库脚本文件在附件里。当然没有此数据库示例程序依然可以运作。
3)安装autotools,在终端执行以下代码:
sudo apt-get install autoconf
autotools工具集由aclocal,autoconf,autoscan,autoheader,automake组成。
安装完成后可以执行以下命令查看安装路径
which aclocal autoconf autoscan autoheader automake
3.操作步骤
步骤1 创建基本框架
如下所示,创建目录dbhelper,在目录dbhelper下创建目录src用来存放源代码文件。源代码文件分别是DBHelpMySQL.h DBHelpMySQL.cpp dbhelper.cpp。其中dbhelper.cpp为程序入口函数,头文件DBHelpMySQL.h被另外两个文件所引用。
<dbhelper>
|--<src>
|-DBHelpMySQL.h
|-DBHelpMySQL.cpp
|-dbhelper.cpp
步骤2 执行autoscan
把目录dbhelper作为当前工作目录,在终端执行命令:autoscan,该操作将在目录下生成autoscan.log,configure.scan两个新文件。如下:
dbhelper$ autoscan
dbhelper$ ls
autoscan.log configure.scan src
步骤3 设置configure.in文件
configure.scan文件的内容如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([src/dbhelper.cpp])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([memset strerror])
AC_OUTPUT
下面对这个脚本文件进行解释:
- 以"#"号开始的行为注释;
- AC_PREREQ 宏声明本文件要求的autoconf版本,如本例使用的版本2.68;
- AC_INIT 宏用来定义软件的名称和版本等信息,BUG-REPORT-ADDRESS一般为作者的e-mail;
- AC_CONFIG_SRCDIR 宏用来侦测所指定的源码文件是否存在,来确定源码目录的有效性;
- AC_CONFIG_HEADER 宏用于生成config.h文件,以便autoheader使用;
- AC_PROG_CC 检查系统可用的C编译器,若源代码是用C写的就需要这个宏。
- AC_PROG_CXX 检查系统可用的C++编译器,若源代码是用C++写的就需要这个宏。
- AC_CHECK_HEADERS 对于每个在以空格分隔的参数列表header-file出现的头文件,如果存在,就定义 HAVE_header-file(全部大写)。如果给出了action-if-found,它就是在找到一个头文件的时候执行的附加shell代码。如果给出了action-if-not-found,它就在找不到某个头文件的时候被执行。
- AC_OUTPUT 设置configure所要产生的文件,若是Makefile,configure 便会把它检查出来的结果带入 Makefile.in 文件后产生合适的 Makefile
1)将configure.scan重命名为configure.in,执行如下命令:
dbhelper$ mv configure.scan configure.in
dbhelper$ ls
autoscan.log configure.in src
2)修改configure.in,内容如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68])
# 软件名称及版本号
AC_INIT(dbhelper, 1.0)
# 用来侦测所指定的源码文件是否存在,来确定源码目录的有效性
AC_CONFIG_SRCDIR([src/dbhelper.cpp])
# 用于生成config.h文件,以便autoheader使用
AC_CONFIG_HEADERS([config.h])
# 新添加的宏,用于初始化automake。参数为软件名称及版本号。它是automake所必备的宏。
AM_INIT_AUTOMAKE(dbhelper,1.0)
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([memset strerror])
# 输出文件,一般来说顶级目录和各子目录都应有Makefile输出
AC_OUTPUT(Makefile src/Makefile)
autotools中的autoconf 是用来产生 configure文件的工具。configure 是一个 shell脚本,它可以自动收集并设定符合各种不同平台的系统特性,并且根据系统参数及环境产生合适的Makefile文件,让原始程序可以很方便地在不同的平台上进行编译。而autoconf会读取 configure.in 文件然后产生configure 这个 shell脚本。
步骤4 执行aclocal
在终端执行命令:aclocal,此操作将生成aclocal.m4,autom4te.cache两个文件。如下:
dbhelper$ aclocal
dbhelper$ ls
aclocal.m4 autom4te.cache autoscan.log configure.in src
步骤5 执行autoheader
如下所示,在终端执行命令:autoheader,此操作将生成config.h.in。该工具通常会从acconfig.h文件中复制用户附加的符号定义,因此此处没有附加符号定义,所以不需要创建acconfig.h文件。
dbhelper$ autoheader
dbhelper$ ls
aclocal.m4 autom4te.cache autoscan.log config.h.in configure.in src
步骤6 编写Makefile.am文件
如下所示,在目录dbhelper和目录src下分别创建Makefile.am文件
<dbhelper>
|-Makefile.am
|--<src>
|-Makefile.am
|-DBHelpMySQL.h
|-DBHelpMySQL.cpp
|-dbhelper.cpp
...
...
目录dbhelper下的Makefile.am内容如下:
AUTOMAKE_OPTIONS=foreign
SUBDIRS=src
内容说明:
- 第一行是告诉automake不要检测目录中是否存在AUTHORS、README等文件;
- 第二行是告诉automake处理src这个子目录。
目录src下的Makefile.am内容如下:
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=dbhelper
dbhelper_SOURCES=dbhelper.cpp DBHelpMySQL.cpp DBHelpMySQL.h
INCLUDES=-I/usr/include/mysql -DBIG_JOINS=1 -fno-strict-aliasing -g
dbhelper_LDADD=/usr/lib/i386-linux-gnu/libmysqlclient.so
dbhelper_LDFLAGS=-L/usr/lib/i386-linux-gnu -lmysqlclient -lpthread -lz -lm -lrt -ldl
内容说明:
- 第一行 作用同前;
- 第二行 要产生的执行文件名;
- 第三行 是生成dbhelper这个程序所需的所有源程序和头文件名称,用空格分隔;
- 第四行 指定所需头文件所在目录。因为程序使用了mysql的C API,因此可以在终端执行以下命令获取该选项的值:mysql_config --cflags
- 第五行 指定链接所需库文件,具体值与所用系统有关;
- 第六行 设置链接选项。因为程序使用了mysql的C API,因此在终端执行以下命令获取该选项的值:mysql_config --libs
autotools中的automake会根据configure.in 中的宏把Makefile.am 转成 Makefile.in 文件。
下面对Makefile.am进行简单说明:
- AUTOMAKE_OPTIONS 为设置automake的选项。由于GNU对自己发布的软件有严格的规范,比如必须附带许可证声明文件COPYING等,否则automake执行时会报错。automake提供了三种软件等级:foreign、gnu和gnits,让用户选择采用,默认等级为gnu。在本例使用foreign等级,它只检测必须的文件;
- bin_PROGRAMS 定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空白符隔开;
- 你要生成软件名_SOURCES 定义这个执行程序所需要的原始文件。如果这个程序是由多个原始文件所产生,必須把它所用到的所有原始文件都列出来,以空白符隔开。例如程序 'hello' 还需要 hello.c、main.c、hello.h 三个文件的话,则定义hello_SOURCES= hello.c main.c hello.h ;
- INCLUDES 设置链接时所需的头文件;
- 你要生成软件名_LDADD 设置链接时所需的库文件;
- 你要生成软件名_LFFLAGS 设置链接选项;
步骤7 执行automake和autoconf
在终端运行automake,此操作将生成depcomp,install-sh,mkinstalldirs,COPYING,INSTALL,missing文件。接着执行autoconf,它将生成最终的configure。命令如下:
dbhelper$ automake -a
configure.in:9: installing `./install-sh'
configure.in:9: installing `./missing'
src/Makefile.am: installing `./depcomp'
dbhelper$ automake -a src/Makefile
dbhelper$ autoconf
dbhelper$ ls
aclocal.m4 config.h.in depcomp src
autom4te.cache configure install-sh Makefile.in
autoscan.log configure.in Makefile.am missing
说明:使用"automake -a"或"automake --add-missing",会自动将install.sh、mkinstalldirs等文件补齐,所以不能省略。
步骤8 编译
如下所示,在终端执行命令:./configure, Makefile.in将变成最终的Makefile文件。
dbhelper$ ./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... no
checking for mawk... Mawk
...
...
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands
步骤9 执行make
如下所示,在终端执行make,生成目标文件。
dbhelper$ make
make all-recursive
make[1]: 正在进入目录 `/home/lxm/src/dbhelper'
Making all in src
make[2]: 正在进入目录 `/home/lxm/src/dbhelper/src'
...
...
make[2]:正在离开目录 `/home/lxm/src/dbhelper/src'
make[2]: 正在进入目录 `/home/lxm/src/dbhelper'
make[2]:正在离开目录 `/home/lxm/src/dbhelper'
make[1]:正在离开目录 `/home/lxm/src/dbhelper'
dbhelper$ cd src
dbhelper/src$ ls
dbhelper dbhelper.o DBHelpMySQL.h Makefile Makefile.in
dbhelper.cpp DBHelpMySQL.cpp DBHelpMySQL.o Makefile.am
至此主要工作已经完成,目录src下的dbhelper就是可执行文件,在终端输入./dbhelper即可执行示例程序。
4.其它
1) 在终端执行如下命令:
dbhelper$ sudo make install
[sudo] password for lxm:
Making install in src
make[1]: 正在进入目录 `/home/lxm/src/dbhelper/src'
make[2]: 正在进入目录 `/home/lxm/src/dbhelper/src'
...
...
make[2]:正在离开目录 `/home/lxm/src/dbhelper'
make[1]:正在离开目录 `/home/lxm/src/dbhelper'
make install: 安装可执行文件以后可以在命令行下直接输入文件名运行程序;
make uninstall:卸载可执行文件
2) 在目录dbhelper下有很多文件,有的是我们自己写的,也有些是编译时生成的临时档案,发布软件时需要打包哪些文件呢?autotools为我们提供了几个很方便的功能。
在终端执行如下命令:
dbhelper$ make dist #将所有的程序和相关的文档打包为一个压缩文件以供发布
dbhelper$ make clean #清除之前编译的可执行文件及配置文件
dbhelper$ make distclean #要清除所有生成的文件