使用GNU Autotools制作Makefile

最近用了一些开源软件,它们都有统一的安装方法,非常方便:
./configure
make
make install

于是我也鸟枪换炮,给自己的源码用上了automake和autoconf。下面这张流程图显示了制作Makefile的全过程:




1.autoconf


autoconf工具的作用是检查工程依赖的库文件和头文件,同时也是automake的基础。

首先用autoscan工具扫描源码,它会产生一个configure.scan模板,在此基础上我们进行修改得到configure.ca(推荐)或者configure.in(图中是这个),这个文件是configure的关键,里面记录了工程依赖的头文件和库文件。下面是一个例子:
# -*- Autoconf -*- 
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68])
AC_INIT([destor_server], [1.0], [fumin@messy.com])
AM_INIT_AUTOMAKE([destor_server], [1.0]) "如要使用automake,这一句是必须的
# Checks for programs.
AC_PROG_CC
CFLAGS="-g -O2"
# Checks for libraries.
AC_CHECK_LIB([pthread],[pthread_create]) "检查依赖库文件,在此添加依赖的库
AC_CHECK_LIB([glib], [g_hash_table_new],[found_glib=yes],[found_glib=no])
if test "$found_glib" = "no"; then
AC_MSG_ERROR([*** Working glib library not found ***])
fi
AC_CHECK_LIB([crypto],[SHA_Update],[found_crypto=yes],[found_crypto=no])
if test "$found_crypto" = "no"; then
AC_MSG_ERROR([*** Working crypto library not found ***])
fi
AC_PROG_RANLIB

# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h])
AC_CHECK_HEADERS([glib.h]) "检查依赖的头文件
if test "$found_glib_h" = "no"; then
AC_MSG_ERROR([*** Working glib.h header not found ***])
fi
AC_CHECK_HEADERS([openssl/sha.h], [found_sha_h=yes],[found_sha_h=no])
if test "$found_sha_h" = "no"; then
AC_MSG_ERROR([*** Working sha.h header not found ***])
fi

# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T

# Checks for library functions.
AC_FUNC_MALLOC
AC_OUTPUT(Makefile   
  src/Makefile
  src/tools/Makefile
  src/index/Makefile
  src/job/Makefile
  src/storage/Makefile) "需要产生Makefile的位置

每个configure.ac都以AC_INIT开始,以AC_OUTPUT结束,中间则添加需要检查的信息,注意不要轻易改变检查的顺序。其中最重要的几行都用注释标注了。现在我们拥有了一个configure.in,接着用aclocal工具产生aclocal.m4,最后运行autoconf就得到了configure脚本。

2.automake


automake工具的输入包括前文的configure.in和需要我们自己编写的Makefile.am,Makefile.am的编写比Makefile要容易多了。下面是个例子。
bin_PROGRAMS=destor_server
destor_server_SOURCES=
destor_server_LDADD=src/libserver.a src/index/libindex.a src/storage/libstorage.a src/tools/libtools.a src/job/libjob.a
SUBDIRS=src src/index src/job src/storage src/tools
LIBS=-lpthread -lcrypto -lglib

bin_PROGRAMS表示我们要得到一个可安装(make install)的可执行文件,它会把可执行文件安装到指定目录下;如果不需要安装,就使用noinst_PROGRAMS,destor_server是可执行文件名。destor_server_SOURCES表示其依赖的源码文件,因为此目录下没有源码,我们就空着。destor_server_LDADD表示其依赖的库文件,后面都是工程内在各个目录链接得到的库文件,每个目录下都需要一个Makefile.am。SUBDIRS表示执行此Makefile前必须先完成这几个子目录的Makefile。LIBS是工程依赖的库。

子目录内的Makefile.am大同小异,这是src目录的例子:
noinst_LIBRARIES=libserver.a
libserver_a_SOURCES=dedup.c cfl_dedup.c server.c backup_server.c restore_server.c statistic.c jcr.c

其中noinst_LIBRARIES表示我们要得到一个不安装的库文件,libserer.a是它的名字;而libserver_a_SOURCES是其依赖的源码文件。其余子目录也都是这种结构,只需调整一下源码文件和库文件名称。

建好所有Makefile.am后,执行automake --add-missing得到Makefile.in模板,configure将会根据这个模板产生最终的Makefile。在执行automake之前,要在工程目录下先创建NEWS、README、ChangeLog、AUTHORS文件。

大功告成!

参考资料:例解 autoconf 和 automake 生成 Makefile 文件

posted on 2013-09-10 16:22  OpenNaive  阅读(464)  评论(0编辑  收藏  举报

导航