近期项目开发中,因文件较多,后来就改用了autotools来构建整个工程,免去手写Makefile的麻烦,在此记录一下autotools工具的使用。
autotools是一系列工具,它包含了autoscan, aclocal, autoheader, automake, autoconf这些工具。使用流程如下:
上述图片是从 截取的,图片已经把流程说的很清楚了,自己就懒得去画了。
使用autotools工具来构建整个工程,最终的目的是可以让我们在编译代码的时候,可以很方便的执行如下的步骤即可:
./configure make && sudo make install
在实际的项目构建过程中,需要我们编写的就是Makefile.am文件,然后就是对configure.scan文件进行修改。其他的步骤只需要执行相应的命令即可。
1. 修改configure.scan文件:
1) 修改AC_INIT宏
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
把上述的宏中的内容按照自己的项目需要修改即可,如:
AC_INIT(hello, 0.1, wenhaoye@126.com)
2) 增加AM_INIT_AUTOMAKE宏, 此宏是给automake工具使用的
AM_INIT_AUTOMAKE(hello, 0.1)
2. 把configure.scan文件重命名为configure.in
3. 编写Makefile.am文件。我们要在这个文件中说明我们需要编译的目标对象,以及目标对象的依赖和编译链接参数。可以认为这个文件上面需要编写的东西,大部分也是我们要在Makefile中定义的。
先以一个最简单的hello工程来说明,hello工程的目录结构如下:
hello -- src -- hello.c
首先在src目录中添加Makefile.am文件,内容如下:
bin_PROGRAMS=hellohello_SOURCES=hello.c
然后在项目的顶层目录下建立Makefile.am,即在hello目录下,内容如下:
AUTOMAKE_OPTIONS=foreignSUBDIRS=src
1) bin_PROGRAMS: 定义我们需要生成的可执行目标,可以有多个,用空格分开。
2) xxx_SOURCES: 定义要生成xxx目标需要的源文件,有多个源文件时,用空格分开。
3) SUBDIRS: 定义项目子模块的目录,如果有多个子目录,用空格分开。表示在处理本目录前,要递归处理哪些子目录。
4) AUTOMAKE_OPTIONS: 这个而是automake的选项,在执行automake时,它会去检测目录下是否存在标准gnu软件包中应具备的各种文件,如AUTHORS, README, NEWS, ChangeLog等文件。在此我将其设置为foreign,automake会改用一般软件包的标准来检查。默认就是按照标准gnu软件包检查。
在Makefile中,我们可以通过修改CFLAGS, LDFLAGS变量来配置编译与链接选项,那么在Makefile,am中,也是可以配置的,比如我们上述的hello目标在编译的时候需要定义DEBUG宏,在链接的时候需要链接pthread库,可以这样子修改src/Makefile.am文件:
bin_PROGRAMS=hellohello_SOURCES=hello.chello_CFLAGS= -DDEBUGhello_LDFLAGS= -lpthread
如果我们需要把代码编译成库文件,在Makefile.am文件中定义如下:
lib_LTLIBRARIES=libutils.lalibutils_la_SOURCES= $(libutils_sources)libutils_la_CFLAGS=-Wall -DDEBUGlibutils_la_LDFLAGS=-lpthread -lrtlibutils_HEADERS=$(libutils_inc)libutilsdir=$(includedir)/libutils
libutils使我们要编译的库,其中la表示同时生成动态库与静态库,a则表示只生成静态库。
后面就是分别制定要生成libutils.la目标,依赖的源文件,编译与链接选项,以及需要安装的头文件
libutils_HEADERS: 表示需要安装的头文件
xxdir: 表示头文件被安装的路径
此外,还需要修改configure.in文件,增加AC_PROG_LIBTOOL,用来检查libtool脚本,因为要使用libtool工具来制作、安装库。
Makefile.am文件还有如下可用的全局变量:
1) INCLUDES: 编译时需要用到的头文件,
2) LDFLAGS: 链接时需要用到的库文件选项标志
3) LDADD: 链接时需要用到的库
下面把autotools使用的一些步骤进行说明:
如果我们需要配置头文件的模块config.h.in文件,则需要在aclocal命令完成后,使用autoheader来生成;
如果我们需要libtool来制作库文件,则需要在autoconf之前执行libtoolize --force --copy,生成libtool所需要的文件。这个命令主要功能是生成ltmain.sh,而ltmain,sh是用来产生libtool脚本的。
执行automake生成Makefile.in文件时,需要automake -a, 这样子可以建立需要的脚本。
在执行configure脚本时,可以通过--disable-static配置不生成静态库,或者--disable-shared配置不生成动态库。
最后我们可以make checkdist 或者make dist来生成一个发布软件包。