SME系统分析之Makefile分析
一 Makefile概述
SME系统由许多模块组成,而各个模块之间存在着各种各样的依赖关系,所以为了方便管理,SME采用Makefile。Makefile关系到整个软件工程的编译规则。一个工程中的源文件不计数,按其类型、功能、模块分别放在若干个目录中。Makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译等等。 Makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令(make是一个命令工具,是一个解释Makefile中指令的命令工具),整个工程完全自动编译,极大的提高了软件开发的效率。
二 生成Makefile文件的例子介绍
我们以用c语言编写的hello.c为例子,来生成Makefile文件。编译器为gcc。
2.1生成Makefile文件,首先要确保以下软件已经被安装:
●
Automake
●
Autoconf
●
Aclocal
●
Perl
●
Libtool--提供通用的库编译支持。
2.2 建立test,hello目录,用vi编译hello.c。

2.3 用autoscan生成configure.scan(和autoscan.log)文件。把configure.scan重命名为configure.in,然后用vi编辑。
autoconf 是用来产生 'configure' 文件的工具。'configure' 是一个shell script,它可以自动设定原始程序以符合各种不同平台上 Unix 系统的特性,并且根据系统参数及环境产生合适的 Makefile 文件或是C 的头文件 (header
file),让原始程序可以很方便地在这些不同的平台上被编译出来。autoconf 会读取 configure.in 文件然后产生 'configure' 这个shell script。
configure.in 文件的内容是一连串 GNU
m4 的巨集,这些巨集经过autoconf
处理后会变成检查系统特征的shell
script。configure.in 内巨集的顺序并没有特别的规定,但是每一个 configure.in 文件必须在所有巨集前加入 AC_INIT 巨集,然后在所有巨集的最後面加上 AC_OUTPUT 巨集。我们可先用 autoscan 扫描原始文件以产生一个 configure.scan 文件,再对 configure.scan 做些修改成 configure.in 文件。所用到的巨集如下:
dnl
这个巨集后面的字不会被处理,可视为注解。
AC_INIT(FILE)
这个巨集用来检查原始码所在的路径,autoscan 会自动产生,我们不必修改它。
AM_INIT_AUTOMAKE(PACKAGE,VERSION)
这是使用 Automake 所必备的巨集,PACKAGE 是我们所要产生软体套件的名称,VERSION 是版本编号。
AC_PROG_CC
检查系统可用的 C 编译器,如果原始程式是用 C 写的就需要这个巨集。
AC_OUTPUT(FILE)
设定 configure 所要产生的文件,如果是 Makefile 的话,configure 便会把它检查出来的结果带入 Makefile.in 文件然后产生合适的 Makefile。

2.4 执行aclocal和autoconf,分别产生aclocal.m4和configure两个文件。

2.5 编辑Makefile.am。
接下来我们要编辑 Makefile.am 文件,Automake 会根据 configure.in 中的巨集把Makefile.am 转成 Makefile.in 文件。Makefile.am 文件定义我们所要的目标:
AUTOMAKE_OPTIONS
设定 automake 的选项。Automake 主要是帮助开发 GNU 软体的人员维护软体套件,所以在执行 automake 时,会检查目录下是否存在标准 GNU 软体套件中应具备的文件,例如 'NEWS'、'AUTHOR'、'ChangeLog' 等文件文件。设成 foreign 时,automake 会改用一般软体套件的标准来检查。
bin_PROGRAMS
定义我们所要产生的执行文件文件名。如果要产生多个执行文件,每个文件名用空白字元隔开。
hello_SOURCES
定义 'hello' 这个执行文件所需要的原始文件。如果 'hello' 这个程式是由多个原始文件所产生,必须把它所用到的原始文件都列出来,以空白字元隔开。假设 'hello' 这个程式需要 'hello.c'、'main.c'、'hello.h' 三个文件案的话,则定义 hello_SOURCES= hello.c main.c hello.h 如果我们定义多个执行文件,则对每个执行文件都要定义相对的filename_SOURCES。

2.6 执行automake --add-missing。
加上 --add-missing 选项是告诉 automake 顺便帮我们加入包装一个软体套件所必备的文件。Automake 产生出来的 Makefile.in文件是完全符合 GNU Makefile 的惯例的。

2.7 执行./configure,将生成Makefile文件。

2.8 执行make dist, 将程序和相关的文件包装成一个压缩文件以供分发。生成了一个hello-1.0.tar.gz文件。

2.9 可以用make来编译hello.c并生成可执行文件hello.
我们执行./hello,结果“hello,GNU!”就出来了。

具体流程如下所示:
你的源文件 --> [autoscan*] --> [configure.scan] --> configure.in configure.in --. .------> autoconf* -----> configure +---+[aclocal.m4] --+ `---.[acsite.m4] ---' | +--> [autoheader*] -> [config.h.in][acconfig.h] ----. | +-----'[config.h.top] --+[config.h.bot] --'
Makefile.am --à
[Autoconf*] -------> Makefile.in
.-------------> config.cacheconfigure* ------------+-------------> config.log |[config.h.in] -. v .-> [config.h] -. +--> config.status* -+ +--> make*Makefile.in ---' `-> Makefile ---'
上图表示在整个过程中要使用的文件及产生出来的文件,有星号
(*) 代表可执行文件。在此示例中可由
Autoconf 及 Automake 工具所产生的额外文件有 configure.scan、aclocal.m4、configure、Makefile.in,需要加入设置的有configure.in 及 Makefile.am。
三
SME的Makefile文件分析
sme-3.2.73软件包由15个文件夹(Base,exe,MML,SpaceSim,CGP,java,MPE,Dbase,gram,lib,parsers,Driver,MCP,PointGrid)所组成。主目录和每个子目录下的src目录下(除了java目录下没有src目录)都有一个Makefile文件。主目录的Makefile文件里面包含了对各个目录的Makefile文件的调用,先把各子目录下的Makefile进行编译,然后把所需的可执行应用程序,生成的库文件复制到SME系统安装目录并修改相应的权限。
15个文件夹相当于15个不同的功能模块。主目录的Makefile文件用来组织系统的各个模块,记录了各模块相互间的联系和依托关系,把各模块下的Makefile文件连接起来,在SME系统编译时使用。
Base目录: 关于SME基本的应用程序
exe目录:生成SME可执行的应用程序
MML目录:关于模块建模语言(Modular Modeling Language)的应用程序
SpaceSim目录:与Ottawa-Carleton
Educational Space Simulation渥太华教育空间仿真软件有关的应用程序
CGP目录:关于代码生成器的应用程序
java目录:关于Java portal的应用程序
MPE目录:没有任何文件
Dbase目录:与Postgress数据库的接口有关的应用程序
gram目录:关于gram相关的应用程序
lib目录:关于库文件的应用程序
parsers目录:关于模块分析的应用程序
Driver目录:关于驱动器的应用程序
MCP目录:关于模块构造器的应用程序
PointGrid目录:关于PointGrid库的应用程序
参考文献
1 http://www.gnu.org/software/autoconf/manual/autoconf.info.gz
2 http://sources.redhat.com/automake/automake.html