ceph 运行的第一个文件:autogen.shhtml
#!/bin/sh -xlinux
"""git
参考redis
http://www.laruence.com/2008/11/11/606.htmlshell
http://blog.chinaunix.net/uid-10915175-id-3256850.html缓存
"""electron
#后续若存在返回非0,则脚本直接退出ide
set -e模块化
#若ceph.in文件在哪一个路径下没有,退出函数
test -f src/ceph.in || {
echo "You must run this script in the top-level ceph directory"
exit 1
}
#定义了一个函数,这里不是调用处,符号&&表示:comd1&&comd2,若comd1执行成功,
#返回0后,执行comd2---另外有符合||,表示comd1执行失败后执行comd2
check_for_pkg_config() {
which pkg-config >/dev/null && return
echo
echo "Error: could not find pkg-config"
echo
echo "Please make sure you have pkg-config installed."
echo
exit 1
}
#libtool 提供通用的库编译支持。
#libtoolize 提供了一种标准方式来将libtool支持加入到一个软件包。
#libltdl隐藏 dlopening 库的复杂细节。
if [ `which libtoolize` ]; then
LIBTOOLIZE=libtoolize
elif [ `which glibtoolize` ]; then
LIBTOOLIZE=glibtoolize
else
echo "Error: could not find libtoolize"
echo " Please install libtoolize or glibtoolize."
exit 1
fi
#判断是否有.git这个路径,这个是那个开源gitub的路径,如有这个
#而后执行git submodule sync和git submodule update --init来更新相关的子项信息
#具体涉及到git中哪些子项,应该是.git中定义的
if test -d ".git" ; then
if ! git submodule sync || ! git submodule update --init; then
echo "Error: could not initialize submodule projects"
echo " Network connectivity might be required."
exit 1
fi
fi
rm -f config.cache
#aclocal是编译的安装工具, 经过configure.ac或者configure.in等,生成m4
#实际上依赖于工具:autoconf、automake
#-I是指路径,m4是ceph的主路径下的一个目录,里面都是.m4文件
#命令功能解释: Generate 'aclocal.m4' by scanning 'configure.ac' or 'configure.in'
#--install copy third-party files to the first -I directory
#要求执行的路径下有:configure.ac文件
#以后执行automake的时候,会依赖configure文件和这个m4文件
aclocal -I m4 --install
#
#检查是否有 pkg_config命令,这个命令能够查询全部库/共享库的版本号,标志位等参数信息
check_for_pkg_config
D
#库编译,若是文件已存在,就覆盖,而且经过复制的方式而不是连接,会将前面aclocal生成的m4宏文件拷到?里面
$LIBTOOLIZE --force --copy
aclocal -I m4 --install
autoconf
autoheader
automake -a --add-missing -Wall
#若是对应的路径存在,在那个路径下,作libtoolize—autoconf--- autoheader-- automake
( cd src/gmock && autoreconf -fvi; )
( cd src/rocksdb && autoreconf -fvi; )
exit
makefile过程图解:
aclocal
user input files optional input process output files
================ ============== ======= ============
acinclude.m4 - - - - -.
V
.-------,
configure.ac ------------------------>|aclocal|
{user macro files} ->| |------> aclocal.m4和缓存文件夹autom4te.cache
`-------'
其中,aclocal.m4主要保存本地宏定义信息
autoheader和autoconf:
根据configure.ac中的某些宏,好比cpp宏定义,运行m4,声称config.h.in
(autoconfig.h.in是configure的运行模板文件,里面有宏参数)
user input files optional input process output files
================ ============== ======= ============
configure.ac ----------------------->|autoconf|----> configure,/autom4te.cache/request
此外,ceph10.2.2 在路径autom4te.cache中生成了文件request,其中autom4te.cache是aclocal时自动生成的。
aclocal.m4 - - - - - - - .
|
V
.----------,
configure.ac ----------------------->|autoheader|----> 更新request(若没有能够生成)
`----------'
4.automake: automake将Makefile.am中定义的结构创建Makefile.in,而后configure脚本将生成的Makefile.in文件转换为Makefile。若是在configure.ac中定义了一些特殊的宏,好比AC_PROG_LIBTOOL,它会调用libtoolize,不然它会本身产生config.guess和config.sub
user input files optional input processes output files
================ ============== ========= ============
.--------,
| | - - -> COPYING
| | - - -> INSTALL
| |------> install-sh
| |------> missing
|automake|------> mkinstalldirs
configure.ac ----------------------->| |
Makefile.am ----------------------->| |------> Makefile.in
| |------> stamp-h.in
.---+ | - - -> config.guess
| | | - - -> config.sub
| `------+-'
| | - - - -> config.guess
|libtoolize| - - - -> config.sub
| |--------> ltmain.sh
| |--------> ltconfig
`----------'
5.autoconf:将configure.ac中的宏展开,生成configure脚本。这个过程可能要用到aclocal.m4中定义的宏。
user input files optional input processes output files
================ ============== ========= ============
aclocal.m4 ,autoconfig.h.in - - - - - - -.
V
.--------,
configure.ac ----------------------->|autoconf|------> configure
6. ./configure的过程
.-------------> [config.cache]
configure* --------------------------+-------------> config.log
|
[config.h.in] -. v .--> [autoconfig.h]
+-------> config.status* -+
Makefile.in ---' `--> Makefile
7. make过程
[autoconfig.h] -.
+--> make* ---> 程序
Makefile ---'
.---------,
config.site - - ->| |
config.cache - - ->| | - - -> config.cache
| +-,
`-+-------' |
| |----> config.status
config.h.in ------->|config- |----> config.h
Makefile.in ------->| .status|----> Makefile
| |----> stamp-h
| +--,
.-+ | |
| `------+--' |
ltmain.sh ------->|ltconfig|-------> libtool
| | |
`-+------' |
|config.guess|
| config.sub |
`------------'
.--------,
Makefile ------>| |
config.h ------>| |
{project sources} ---------------->| |--------> {project targets}
.-+ +--,
| `--------' |
| libtool |
| missing |
| install-sh |
|mkinstalldirs|
`-------------'
参考文献
http://www.07net01.com/program/579475.html
Posted on 2008-06-27 09:42 T.S Liu 阅读(8032) 评论(1) 编辑 收藏 引用 所属分类: makefile
使用 GNU autotools 改造一个软件项目
本文不是一篇规范的教程,而是用一个软件项目做为例子,演示使用 GNU autotools 进行
软件管理的思路和过程
目 录
· 示例项目
· 软件布局
· Makefile 分析
· GNU 的软件风格
· 准备 autotools
· 改造文件布局
· autoscan
· configure.ac 的基本结构
· Makefile 文件的产生
· 编写 Makefile.am
软件根目录 Makefile.am
src/Makefile.am
data/Makefile.am
docs/Makefile.am
fonts/Makefile.am
images/Makefile.am
music/Makefile.am
sound/Makefile.am
· 运行 autotools
· SDL 库的侦测
· 软件使用的数据文件
· configure 选项
· autotools 脚本
· 使用 configure 产生的 Makefile
· 最终的 configure.ac 文件
· 结束语
示例项目
这里借用了 Wei Mingzhi <whistler_wmz@users.sf.net> 开发的麻将游戏来进行演示,在
此,先对他表示感谢!
示例软件下载:
软件布局
将下载的软件包解压到一个目录
$ cd ~/work
$ tar xjf mahjong.tar.bz2
能够看到这是一个典型的 Windows 风格的软件项目布局,在 mahjong 目录下放着程序的源码,程序运行时使用的数据文件放在子目录下面
做者还提供了一个 Makefile,一个 DOS 风格的 !play.bat 批处理文件,一个编译好的mj.exe 可执行文件在 Win32 平台上运行 !play.bat 就能够直接运行程序在 Unix/Linux 系统上,进入 mahjong 目录,键入 make 命令,若是一切顺利的话,将生成 mj 可执行文件,而后在命令行上运行 ./mj 程序,也能够启动麻将游戏
对于一个 Windows 程序来说,该软件布局能够说很是清晰明了但在 Unix/Linux 系统
上,执行 make 命令就可能遇到问题:编译找不到头文件,或者链接找不到库文件而在
make 成功之后,运行麻将程序必须先进入该 majiong 目录,才能执行程序若是要像
其余的程序同样,能够在任意目录使用,就要专门为这一个程序修改 PATH 环境变量,或
者再写一个启动脚本,并将它复制到 /usr/bin 这样的目录下
Makefile 分析
1 #
2 # Copyright (c) 2005, Wei Mingzhi. All rights reserved.
3 #
4 # Use, redistributions and modifications of this file is
5 # unrestricted provided the above copyright notice is
6 # preserved.
7 #
8
9 OBJ = \
10 bot.o config.o game.o general.o hand.o ini.o main.o \
11 player.o text.o tile.o util.o
12
13 HEADERS = \
14 bot.h game.h general.h hand.h ini.h main.h player.h \
15 tile.h
16
17 CC = gcc
18 CXX = g++
19
20 TARGET = mj
21
22 BASEFLAGS = -g3 -D_DEBUG=1
23 #BASEFLAGS = -s -O3
24
25 CFLAGS = ${BASEFLAGS} `sdl-config --cflags`
26 LDFLAGS = ${BASEFLAGS} `sdl-config --libs` -lSDL_image -lSDL_mixer -lSDL_ttf
27
28 all: ${TARGET}
29
30 ${TARGET}: ${OBJ}
31 ${CXX} ${LDFLAGS} -o ${TARGET} ${OBJ}
32
33 clean:
34 rm -f *.o ${TARGET}
35
36 distclean:
37 rm -f *.o ${TARGET}
38
39 %.o: %.cpp ${HEADERS}
40 ${CXX} ${CFLAGS} -c $< -o $@
41
42 %.o: %.c ${HEADERS}
43 ${CC} ${CFLAGS} -c $< -o $@
Makefile 很清楚:
第 20 行定义 TARGET 变量为 mj,
第 28 行代表 make 默认的 target 也就是生成 `mj';
第 22 行加入编译时的调试信息;
第 25-26 行使用了 sdl-config 工具侦测 SDL 开发库编译连接信息,在 26 行还指明须要链接 SDL_imageSDL_mixser 和SDL_ttf 库
GNU 的软件风格
一个标准的 GNU 软件,编译安装都是使用下面三个步骤:
$ ./configure
$ make
$ make install
configure 脚本运行时能够侦测系统的环境,肯定软件安装目录,而后生成 Makefile 文件(Makefile文件中即包含编译信息又包含环境信息)
make 调用系统中的编译器进行编译和链接
make install 将软件安装到设定的目录
用户执行 configure 时能够经过它的命令行参数指定本身所需的编译选项,好比安装目录经过 --prefix=PREFIX 设置,若是不指定,缺省状况下 PREFIX 是 /usr/local默认安装时,执行文件安装到 /usr/local/bin 目录,
库安装到 /usr/local/lib 目录,数据文件安装到 /usr/local/share 目录
因为 GNU 的软件风格方便易用,通用性好,可移植性高,如今大多数 Unix/Linux 系统上的自由软件都采用这种方式分发软件
准备 autotools
GNU autotools 主要包含三个软件: autoconf,automake 和 libtool
当前流行的有新旧两个版本,本例采用的是新版本,分别对应的是: autoconf 2.59, automake 1.9.6和 libtool 1.5.18
不少 linux 发行版都会默认安装这几个工具本例是在 NetBSD 下进行操做,安装这几个
软件包是经过 pkgsrc,它们在 pkgsrc 目录为 devel/autoconf devel/automake 和devel/libtool
改造文件布局
原来软件的根目录下面放的是程序的源码,按照 GNU 的习惯,将它们放到 src 子目录,
根目录留给 configure 这类文件使用,其余的数据文件保持不变,仍然放在各自的子目录
先建立一个目录 majiang,而后根据须要将 mahjong 目录下的文件复制过来因为是为
Unix/Linux 系统进行改写,原目录里的 win32 相关文件就不用复制到新目录
$ cd ~/work/majiang
$ ls
data/ docs/ fonts/ images/ music/ sound/ src/
autoscan
autoconf
软件包里面的 autoscan 工具能够扫描工做目录,生成一个 configure.ac 的模板文件 configure.scan
$ cd ~/work/majiang
$ autoscan
autoscan 命令在当前目录生成的 configure.scan 文件内容为:
1 # -*- Autoconf -*-
2 # Process this file with autoconf to produce a configure script.
3
4 AC_PREREQ(2.59)
5 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
6 AC_CONFIG_SRCDIR([src/bot.h])
7 AC_CONFIG_HEADER([config.h])
8
9 # Checks for programs.
10 AC_PROG_CXX
11 AC_PROG_CC
12
13 # Checks for libraries.
14
15 # Checks for header files.
16 AC_HEADER_STDC
17 AC_CHECK_HEADERS([limits.h malloc.h stdlib.h string.h unistd.h])
18
19 # Checks for typedefs, structures, and compiler characteristics.
20 AC_HEADER_STDBOOL
21 AC_C_CONST
22 AC_C_INLINE
23
24 # Checks for library functions.
25 AC_FUNC_MALLOC
26 AC_FUNC_REALLOC
27 AC_CHECK_FUNCS([memset strcasecmp strchr strdup])
28 AC_OUTPUT
# 号开始的行是注释,其余都是 m4 宏命令将它更名为 configure.ac,而后在此基础上
进行修改
configure.ac 的基本结构
configure.ac 文件是 autoconf 的输入文件,通过 autoconf 处理,展开里面的 m4 宏,输出--- configure 脚本
第 4 行声明本文件要求的 autoconf 版本,由于本例使用了新版本 2.59,因此在此注明
第 5 行 AC_INIT 宏用来定义软件的名称和版本等信息,本例写成:
AC_INIT(majiang, 1.0)
这里省略了 BUG-REPORT-ADDRESS 参数,它是可选项,通常写成做者的邮件地址
第 6 行 AC_CONFIG_SRCDIR 宏经过侦测所指定的源码文件是否存在,来肯定源码目录的有
效性能够选择源码目录中的任何一个文件做为表明,好比将 autoscan 选择的 bot.h
文件改为 main.cpp:
AC_CONFIG_SRCDIR([src/main.cpp])
宏参数中使用 `[ ]',是为了代表其中的字符串是一个总体
第 7 行的 AC_CONFIG_HEADER 宏用于生成 config.h 文件,里面存放 configure 脚本侦
测到的信息若是程序须要使用其中的定义,就在源码中加入
#include <config.h>
其余的一些宏是标准的侦测过程,能够保留不动
configure.ac 文件要求 AC_INIT 宏必须放在开头位置,AC_OUTPUT 放在文件末,中间用来检测编译环境的各类宏没有特别的前后次序要求,由宏之间相互关系决定
Makefile 文件的产生
前面 configure.ac 里面的宏,主要做用是侦测系统,并无编译相关的设置。
由于这些信息是写在 Makefile.am 里面,而后用 automake 工具转换成 Makefile.in,
configure脚本执行时再读取 Makefile.in,并与侦测信息configure.ac一块儿写到 Makefile 文件
在 autotools 的命名习惯中,
后缀 ac 的文件是 autoconf 的输入文件,
后缀 am 的文件是 automake 的输入文件,
后缀 in 的文件是 configure 的输入文件 autoconf 旧版
本中 configure.in 等同于 configure.ac,虽然新版本也能够识别,但它不符合命名规则,因此新版本的文件应该使用 ac 后缀
简单的 Makefile.in 能够手动编写,若是使用 automake 产生,须要在 configure.ac里面加入 AM_INIT_AUTOMAKE 宏进行声明
要输出 Makefile,还须要在 configure.ac 中使用 AC_CONFIG_FILES 宏指明该宏并非只处理 Makefile,而是将 FILE.in 文件转换为 FILE 文件(里面写各个路径下的Makefile文件名,通常都叫Makefile,若不是这个标准名字,应该在调用make的时候要传入文件名参数标志,此外,AC_OUTPUT这个configure.ac的最后一个宏命令的参数也可设定为Makefile,这样也能够有相同的结果)
由于 make 能够遍历子目录,若是子目录中存在 Makefile,也将同时处理在本例中 src 目录下是源码,其余是数据文件,可使用单独一个 Makefile 放在根目录下面,固然也能够生成多个 Makefile。 这样每一个子目录的 Makefile 只需处理本目录的文件,分工明确,是模块化的方法,推荐使用。
在 configure.ac 里面增长下面的宏,表示软件根目录和子目录中都须要生成
Makefile 文件:
AC_CONFIG_FILES([Makefile
src/Makefile
data/Makefile
docs/Makefile
fonts/Makefile
images/Makefile
music/Makefile
sound/Makefile])
编写 Makefile.am
《《软件根目录 Makefile.am》》
因为该目录下面保存的是与 autotools 相关的文件,没有须要编译安装的文件,因此只注明须要进一步处理的子目录信息:
SUBDIRS = src data docs fonts images music sound
<<src/Makefile.am>>
此目录里是源代码,最终生成 mj 可执行文件,在其 Makefile.am 中写入
bin_PROGRAMS = mj
ATmj_SOURCES = bot.h \
bot.cpp \
config.cpp \
game.h \
game.cpp \
general.h \
general.cpp \
hand.h \
hand.cpp \
ini.h \
ini.cpp \
main.h \
main.cpp \
player.h \
player.cpp \
text.cpp \
tile.h \
tile.cpp \
util.cpp
am 文件里变量经过命名判断其含义,保留的字符串间用下划线分隔
bin_PROGRAMS 表示列出二进制的程序,值为多个空格分开的程序列表,这里仅有一个 mj
mj_SOURCES 列出的是组成 mj 程序的文件,文件比较多的时候,每一个文件写成一行容易看清楚
data/Makefile.am
本目录的文件是 mj 运行时读取的数据,它的 Makefile.am 能够这样写
mjdatadir = $(pkgdatadir)/data
mjdata_DATA = mj.ini titles.txt
EXTRA_DIST = $(mjdata_DATA)
由于 datadir 是保留的关键字,因此用 mjdatadir 代替,pkgdatadir 指向 $prefix/
share/FULL-PACKAGE-NAME 目录,由于在 AC_INIT 中已经声明 FULL-PACKAGE-NAME 为
majiang,pkgdatadir 就等于 $prefix/share/majiang 目录
其中 mjdatadir 让 data 目录下的文件安装到 $prefix/share/majiang/data 目录里面
mjdata_DATA 列出此目录下须要安装的文件,而后用 EXTRA_DIST 变量注明
余下几个子目录都与 data 目录相似
docs/Makefile.am
docsdir = $(pkgdatadir)/docs
docs_DATA = gkai00mp.txt gpl.html readme.txt
EXTRA_DIST = $(docs_DATA)
fonts/Makefile.am
fontsdir = $(pkgdatadir)/fonts
fonts_DATA = brush.ttf gkai00mp.ttf
EXTRA_DIST = $(fonts_DATA)
images/Makefile.am
imagesdir = $(pkgdatadir)/images
images_DATA = bgame.jpg \
mjgirl1a.jpg \
mjgirl2a.jpg \
mjgirl3a.jpg \
mjgirl4a.jpg \
tiles.jpg \
electron.jpg \
mjgirl1b.jpg \
mjgirl2b.jpg \
mjgirl3b.jpg \
mjgirl4b.jpg \
gameover.jpg \
mjgirl1c.jpg \
mjgirl2c.jpg \
mjgirl3c.jpg \
mjgirl4c.jpg
EXTRA_DIST = $(images_DATA)
music/Makefile.am
musicdir = $(pkgdatadir)/music
music_DATA = bet.ogg \
bonus.ogg \
music.ogg \
musicb.ogg \
musice.ogg \
win.ogg \
bgame.ogg \
gameover.ogg \
music1.ogg \
musicc.ogg \
musicp.ogg
EXTRA_DIST = $(music_DATA)
sound/Makefile.am
sounddir = $(pkgdatadir)/sound
sound_DATA = boom.wav \
ding.wav \
discard.wav \
discard2.wav \
flash.wav \
snd1.wav \
snd2.wav \
snd3.wav \
snd4.wav
EXTRA_DIST = $(sound_DATA)
运行 autotools
准备好 configure.ac 和 Makefile.am,就能够用 autotools 的命令处理这些文件开始可能会出现错误,不过不要紧,能够按照错误信息的提示逐步进行修正
首先要使用的是 aclocal 命令,它根据 configure.ac 的定义,将须要使用的 m4 宏定义复制到 aclocal.m4 里面。
缺省时,搜索 m4 宏是从 autoconf 的安装目录和系统的
aclocal 目录若是须要使用其余路径下的宏,能够经过命令行的 -I 选项指定
接着使用 autoheader 命令,它负责生成 config.h.in 文件,这里面的 C 语言宏定义也是经过解析 configure.ac 产生
下来运行 automake 命令处理 Makefile.am,生成 Makefile.in
GNU 对本身发布的软件有严格的规范,好比必须附带许可证声明文件 COPYING 等等,不然 automake 执行时会报错
automake 提供了三种软件等级: foreign gnu 和 gnits,让用户选择采用,默认
等级为 gnu。 本例使用 foreign 等级,它只检测必须的文件有一些必需的脚本文件。能够从 automake 软件包里复制过来,在执行时使用
--add-missing 选项可让 automake 自动添加,默认方式是采用符号连接,
如加上 --copy 选项则可使用复制方式
本例中,automake 的命令以下:
$ automake --foreign --add-missing --copy
最后,使用 autoconf 命令生成 configure 脚本文件
SDL 库的侦测
这个麻将游戏是基于 SDL 库开发的,通常系统默认不会安装,所以 configure 脚本的一个任务就是检查用户的系统中是否有该软件包
autoconf 提供了不少宏能够实现侦测功能,但首先应该查看 SDL 软件包是否已经提供相应的宏。经过 pkgsrc 的工具能够看到:
$ pkg_info -L SDL|grep m4
/usr/pkg/share/aclocal/sdl.m4
即 SDL 软件包提供了一个 sdl.m4 宏,放在系统的 aclocal 目录下
在这个宏文件的注释中说明了使用的方法:
dnl AM_PATH_SDL([MINIMUM-VERSION,[ACTION-IF-FOUND[,ACTION-IF-NOT-FOUND]]])
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
也就是说在 configure.ac 里面调用 AM_PATH_SDL 宏,就能够侦测 SDL找到 SDL 库以
后,该宏还输出 SDL_CFLAGS 和 SDL_LIBS 编译链接选项,它们实际上就是调用
`sdl-config --cflags` 和 `sdl-config --libs`
因而在 configure.ac 里面加入 AM_PATH_SDL 宏
# Checks for libraries.
SDL_VERSION=1.2.0
AM_PATH_SDL($SDL_VERSION,
:,
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
)
当前 SDL 的版本为 1.2.9,因而 MINIMUM-VERSION 就设为 1.2.0若是在系统中侦测到
须要的库,没什么额外的操做,假如没有找到,则给出错误信息
AM_PATH_SDL 输出 SDL_CFLAGS 和 SDL_LIBS 编译参数,须要添加到 src/Makefile.am 里
面:
mj_CPPFLAGS = @SDL_CFLAGS@
mj_LDFLAGS = @SDL_LIBS@
用 `@' 包围的变量会在 configure 执行时被替换
从 mahjong 的 Makefile 中看到,这个软件还要使用 SDL_imageSDL_mixser 和
SDL_ttf 库,但它们不属于 SDL 软件包,须要另外安装因为这些库在 sdl.m4 中也没
有进行侦测,因此本身要写一些脚本
autotools 提供了一个 AC_CHECK_LIB 宏能够用来检测库,如今就使用它来检测这几个
SDL 库该宏的语法为:
AC_CHECK_LIB (LIBRARY, FUNCTION, [ACTION-IF-FOUND],
[ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES])
第一个参数是库名,第二个参数是库中的一个函数,第三个参数是检测到之后进行的动做
,第四个参数是未检测到之后的动做,第五个参数是其余的库
对于 SDL_imageSDL_mixer 和 SDL_ttf 对应的使用方法以下:
# Check for SDL_image library
AC_CHECK_LIB(SDL_image, IMG_LoadPNG_RW, , AC_MSG_ERROR([
*** Unable to find SDL_image libary with PNG support
(http://www.libsdl.org/projects/SDL_image/)
]), `sdl-config --libs`)
# Check for SDL_mixer library
AC_CHECK_LIB(SDL_mixer, Mix_LoadOGG_RW, , AC_MSG_ERROR([
*** Unable to find SDL_mixer libary with OGG support
(http://www.libsdl.org/projects/SDL_mixer/)
]), `sdl-config --libs`)
# Check for SDL_ttf library
AC_CHECK_LIB(SDL_ttf, TTF_OpenFont, , AC_MSG_ERROR([
*** Unable to find SDL_ttf libary
(http://www.libsdl.org/projects/SDL_ttf/)
]), `sdl-config --libs`)
《软件使用的数据文件》
原来 mj 读取数据是从执行时目录的子目录中读取,但如今将数据放到 $prefix/share/majiang 目录下,须要经过一种途径让程序能够知道数据文件被安放的位置要达到这个目的有不少方法,这里采用最直接的一种:将数据文件安装目录变量经过
CPPFLAGS 编译参数传递给程序
因而修改 src/Makefile.am 的 CPPFLAGS:
mj_CPPFLAGS = @SDL_CFLAGS@ -DDATA_DIR=\"${datadir}/majiang\"
相应地修改 src 目录下的源码,在读取数据文件的地方,将读取的路径改为 DATA_DIR
里对应的子目录例如,原先 config.cpp 中是:
void LoadCfg()
{
cfg.Load("data/mj.ini");
}
现改为:
void LoadCfg()
{
char ini_file[260];
sprintf(ini_file, "%s/data/mj.ini", DATA_DIR);
cfg.Load(ini_file);
}
configure 选项
原来 mahjong 的 Makefile 第 22 行定义了 debug 调试选项,虽然也能够照样放到 src/Makefile.am 的 CPPFLAGS 里面实现,但 autotools 提供了一种更灵活的机制
configure 脚本能够经过选项来设置编译参数,现增长一个 --enable-debug 选项,须要DEBUG 时,在命令行上加上它来打开,默认则关闭
这项功能是使用 AC_ARG_ENABLE 宏实现:
AC_ARG_ENABLE (FEATURE, HELP-STRING, [ACTION-IF-GIVEN],
[ACTION-IF-NOT-GIVEN])
其中 FEATURE 是功能的名称,HELP_STRING 为说明信息,在使用 ./configure --help 时能够看到最后两个分别对应打开和关闭时的操做
如今将 DEBUG 功能加入 configure.ac:
AC_ARG_ENABLE(debug,
[ --enable-debug turn on debug],
CXXFLAGS="$CXXFLAGS -g3 -D_DEBUG=1")
autotools 脚本
每次修改了 configure.ac 或 Makefile.am 等 autotools 输入文件后都须要再次运行
aclocal
automake
autoconf 这些命令,为了方便起见,能够将他们放到一个 shell
脚本里面,例如:
#! /bin/sh
set -x
aclocal
autoheader
automake --foreign --add-missing --copy
autoconf
将上面内容保存到 autogen.sh 文件,并修改文件属性为 755每次须要从新生成
configure 脚本时,执行 ./autogen.sh 便可
使用 configure 产生的 Makefile
如今执行 ./autogen.sh 获得的 configure 脚本已经能够正常工做了,进入 ~/work/majiang 目录,执行 ./configure,能够看到它检查系统的过程,包括 SDL 和
SDL_image 等库的侦测结果。使用 ./configure --help 能够看到 autotools 提供的帮助信息
configure 执行的完毕,输出软件根目录和几个子目录下面的 Makefile 文件
这些Makefile 有几个经常使用的 target: · make all 不加任何 target,默认就是 all,做用是编译软件 · make install 安装软件包,若是安装到系统目录,须要 root 权限 · make clean 清除编译产生的目标文件 · make distclean 能够同时清除编译的结果和 configure 输出的文件 · make tags 生成 etags 使用的 TAGS 文件 · make dist 生成软件发布包,为 tar.gz 格式的压缩包,文件名由软件包名和版本组成 最终的 configure.ac 文件 # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT([majiang], [1.0]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADER([config.h]) AC_CANONICAL_HOST AC_CANONICAL_TARGET AM_INIT_AUTOMAKE # Checks for programs. AC_PROG_CXX AC_PROG_CC AC_LANG(C++) # Checks for libraries. SDL_VERSION=1.2.0 AM_PATH_SDL($SDL_VERSION, :, AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) ) # Check for SDL_image library AC_CHECK_LIB(SDL_image, IMG_LoadPNG_RW, , AC_MSG_ERROR([ *** Unable to find SDL_image libary with PNG support (http://www.libsdl.org/projects/SDL_image/) ]), `sdl-config --libs`) # Check for SDL_mixer library AC_CHECK_LIB(SDL_mixer, Mix_LoadOGG_RW, , AC_MSG_ERROR([ *** Unable to find SDL_mixer libary with OGG support (http://www.libsdl.org/projects/SDL_mixer/) ]), `sdl-config --libs`) # Check for SDL_ttf library AC_CHECK_LIB(SDL_ttf, TTF_OpenFont, , AC_MSG_ERROR([ *** Unable to find SDL_ttf libary (http://www.libsdl.org/projects/SDL_ttf/) ]), `sdl-config --libs`) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([limits.h malloc.h stdlib.h string.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL AC_C_CONST AC_C_INLINE # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC AC_CHECK_FUNCS([memset strcasecmp strchr strdup]) AC_ARG_ENABLE(debug, [ --enable-debug turn on debug], CXXFLAGS="$CXXFLAGS -g3 -D_DEBUG=1") AC_CONFIG_FILES([Makefile src/Makefile data/Makefile docs/Makefile fonts/Makefile images/Makefile music/Makefile sound/Makefile]) AC_OUTPUT 结束语 GNU 的不少工具常常给人一种感受: 功能很强大,但也很难学autotools 能够说是这类 工具的一个典型,它须要用户对 shellmake软件编译m4 宏语言,以及 Unix/Linux 操做系统各方面知识都有必定的了解使用时又要 autoconf automakelibtool 多个 工具相互配合^1,若是要给软件增长国际化功能,还要再了解和掌握 gettextpo 等工具 和规则 与学习其余知识同样,所谓难,实际上是不了解,不熟悉本文经过一个范例演示使用 autotools 的过程,是让不了解的人熟悉这个工具但真正的理解,还须要将它运用到自 己的软件项目当中,不断地实践,不断地思考和总结